Advertisement
TheTartalex

MFCC

Jul 25th, 2016
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 33.30 KB | None | 0 0
  1. -- Configurazione centrale
  2. local tArgs = {...}
  3. local CONFIG_FILE = "config"
  4.  
  5. local CONFIG_TEMPLATE = [[-- adjust these configuration options as necessary.
  6. -- delay for checking all capacitors
  7. TICK_DELAY = ${tickDelay}
  8.  
  9. -- threshold in percentages
  10. GREEN_ZONE = ${greenZone}
  11. YELLOW_ZONE = ${yellowZone}
  12.  
  13. NORMAL_POWER_THRESHOLD = ${nomalPowerThreshold}
  14. LOW_POWER_THRESHOLD = ${lowPowerThreshold}
  15.  
  16. -- configures what side to emit when low power
  17. -- a valid side is required.
  18. SIDE_TO_EMIT_REDSTONE_ON_LOW_POWER = "${sideForRedstone}"
  19.  
  20. -- Active monitors on startup
  21. MONITORS_ACTIVE = ${monitorsActive}
  22. ]]
  23.  
  24. local MONITORS_ACTIVE = {}
  25.  
  26. do
  27.     if #tArgs > 0 and tArgs[1] == "update" then
  28.         print("aggiornamento  RF ControlCenter ")
  29.         local updateFile = "/rfcc_update"
  30.         local pastebinKey = "TfeHE7Wy"
  31.         shell.run("pastebin", "get", pastebinKey, updateFile)
  32.  
  33.         if fs.exists(updateFile) then
  34.             local programPath = shell.getRunningProgram()
  35.             fs.delete(programPath)
  36.             fs.move(updateFile, programPath)
  37.             print("Success!")
  38.             return
  39.         else
  40.             print("Impossibile ricevere aggiornamenti da pastebin.")
  41.             print("Errore di connessione, riprova in seguito.")
  42.             error()
  43.         end
  44.     end
  45. end
  46.  
  47. local function interpolate(s, params)
  48.     return s:gsub('($%b{})', function(w) return params[w:sub(3, -2)] or w end)
  49. end
  50.  
  51. local function saveSettings()
  52.     local h = fs.open("/"..CONFIG_FILE, "w")
  53.  
  54.     local settings = {
  55.         tickDelay = TICK_DELAY or 100,
  56.         greenZone = GREEN_ZONE or 70,
  57.         yellowZone = YELLOW_ZONE or 30,
  58.         nomalPowerThreshold = NORMAL_POWER_THRESHOLD or 90,
  59.         lowPowerThreshold = LOW_POWER_THRESHOLD or 10,
  60.         sideForRedstone = SIDE_TO_EMIT_REDSTONE_ON_LOW_POWER or "left",
  61.         monitorsActive = textutils.serialize(MONITORS_ACTIVE)
  62.     }
  63.  
  64.     h.write(interpolate(CONFIG_TEMPLATE, settings))
  65.     h.close()
  66. end
  67.  
  68.  
  69. if fs.exists(CONFIG_FILE) == false then
  70.     print("Non riesco a trovare il file del config.")
  71.     print("Generazione nuovo config.")
  72.  
  73.     saveSettings()
  74.  
  75.     print("")
  76.     print("Il file di configurazione e' in /"..CONFIG_FILE)
  77.     print("Se vuoi puoi modificare questo file per cambiare.")
  78.     print("le impostazioni di default, al termine, riavvia.")
  79.     return
  80. else
  81.     os.unloadAPI(CONFIG_FILE)
  82.  
  83.     if os.loadAPI("/"..CONFIG_FILE) == false then
  84.         error("Impossibile caricare il file del config!")
  85.     end
  86.  
  87.     CONFIG = nil
  88.     for k, v in pairs(_G) do
  89.         if k == CONFIG_FILE then
  90.             CONFIG = v
  91.             break
  92.         end
  93.     end
  94.  
  95.     if CONFIG == nil then
  96.         print("non riesco a trovare il file del config.")
  97.         print("probabilmente hai sbagliato qualcosa.")
  98.         error()
  99.     end
  100. end
  101.  
  102. term.setCursorPos(1, 1)
  103. term.clear()
  104. print("Avvio RF Control Center in corso")
  105. sleep(2)
  106.  
  107. -- Constants
  108. local GET_ENERGY_STORED_FUNCTION="getEnergyStored"
  109. local GET_MAX_ENERGY_STORED_FUNCTION="getMaxEnergyStored"
  110.  
  111. local TICK_DELAY = CONFIG.TICK_DELAY
  112. local PAUSE_TIME_IN_SECONDS = TICK_DELAY / 20
  113.  
  114. -- threshold in percentages
  115. local GREEN_ZONE = CONFIG.GREEN_ZONE
  116. local YELLOW_ZONE = CONFIG.YELLOW_ZONE
  117.  
  118. local NORMAL_POWER_THRESHOLD = CONFIG.NORMAL_POWER_THRESHOLD
  119. local LOW_POWER_THRESHOLD = CONFIG.LOW_POWER_THRESHOLD
  120.  
  121. -- configures what side to emit when low power
  122. local SIDE_TO_EMIT_REDSTONE_ON_LOW_POWER = CONFIG.SIDE_TO_EMIT_REDSTONE_ON_LOW_POWER
  123.  
  124. MONITORS_ACTIVE = CONFIG.MONITORS_ACTIVE
  125.  
  126. -- state variables
  127. local clickableLines = {}
  128. local clickableOutputMonitors = {}
  129. local monitors = {}
  130. local capacitors = {}
  131. local dashboardButtons = {}
  132. local totalEnergyAvailable, totalCapacity, totalFlowRate = 0, 0, 0
  133.  
  134. -- Capacitor basic functions
  135. do
  136.     capacitors.add = function(params)
  137.         table.insert(capacitors, params)
  138.     end
  139.  
  140.     capacitors.get = function(name)
  141.         for i, v in ipairs(capacitors) do
  142.             if name == v.name then
  143.                 return v
  144.             end
  145.         end
  146.  
  147.         return nil
  148.     end
  149.  
  150.     capacitors.remove = function(name)
  151.         local found = nil
  152.         for i, v in ipairs(capacitors) do
  153.             if name == v.name then
  154.                 found = i
  155.                 break
  156.             end
  157.         end
  158.  
  159.         if found then
  160.             table.remove(capacitors, found)
  161.         end
  162.     end
  163.  
  164.     capacitors.clear = function()
  165.         for i, v in ipairs(capacitors) do
  166.             capacitors[i] = nil
  167.         end
  168.     end
  169. end
  170.  
  171.  
  172. -- Special Windows
  173. local nativeDisplayTabs = {}
  174. local nativeMonitorTabWindow
  175. local consoleWindow
  176. local monitorSelectionWindow
  177.  
  178. do
  179.     local nativeTerm = term.native()
  180.     local width, height = term.getSize()
  181.     local x, y = 1, 2
  182.     local newWidth, newHeight = width, height - 1
  183.  
  184.     nativeTerm.setCursorPos(x, y)
  185.  
  186.     nativeMonitorTabWindow = window.create(nativeTerm, 1, 1, width, 1, false)
  187.  
  188.     consoleWindow = window.create(nativeTerm, x, y, newWidth, newHeight, false)
  189.     consoleWindow.active = true
  190.  
  191.     monitorSelectionWindow = window.create(nativeTerm, x, y, newWidth, newHeight, false)
  192.     monitorSelectionWindow.active = true
  193. end
  194.  
  195. -- TODO: break up this humongous script into smaller chunks that can be loaded
  196. --       via os.loadAPI().
  197.  
  198.  
  199. -- basic functions
  200. local function tableSize(targetTable)
  201.     local i = 0
  202.     for k, v in pairs(targetTable) do
  203.         i = i + 1
  204.     end
  205.  
  206.     return i
  207. end
  208.  
  209. local function padRight(text, width, padCharacter)
  210.     if width == nil then
  211.         width = term.getSize()
  212.     end
  213.  
  214.     padCount = width - string.len(text)
  215.  
  216.     if padCharacter == nil then
  217.         padCharacter = " "
  218.     end
  219.  
  220.     if padCount > 0 then
  221.         return text..string.rep(padCharacter, padCount)
  222.     else
  223.         return text
  224.     end
  225. end
  226.  
  227. local function padLeft(text, width, padCharacter)
  228.     if width == nil then
  229.         width = term.getSize()
  230.     end
  231.  
  232.     padCount = width - string.len(text)
  233.  
  234.     if padCharacter == nil then
  235.         padCharacter = " "
  236.     end
  237.  
  238.     if padCount > 0 then
  239.         return string.rep(padCharacter, padCount)..text
  240.     else
  241.         return text
  242.     end
  243. end
  244.  
  245. local function printZoneText(percent, callback)
  246.     if percent >= GREEN_ZONE then
  247.         term.setTextColor(colors.green)
  248.     elseif percent >= YELLOW_ZONE and percent < GREEN_ZONE then
  249.         term.setTextColor(colors.yellow)
  250.     else
  251.         term.setTextColor(colors.red)
  252.     end
  253.  
  254.     callback()
  255.  
  256.     term.setTextColor(colors.white)
  257. end
  258.  
  259. local function resetRedstoneState()
  260.     for k,v in pairs(rs.getSides()) do
  261.         rs.setOutput(v, false)
  262.     end
  263. end
  264. -- basic functions
  265.  
  266.  
  267. -- line drawing API
  268. local function drawVerticalLine(targetWindow, x, y, height)
  269.     targetWindow.setCursorPos(x, y)
  270.  
  271.     targetWindow.setBackgroundColor(colors.blue)
  272.     for i = 1, height do
  273.         targetWindow.write(" ")
  274.         targetWindow.setCursorPos(x, i)
  275.     end
  276.     targetWindow.setBackgroundColor(colors.black)
  277. end
  278.  
  279. local function drawHorizontalLine(targetWindow, x, y, width)
  280.     targetWindow.setCursorPos(x, y)
  281.     targetWindow.setBackgroundColor(colors.blue)
  282.     targetWindow.write(string.rep(" ", width))
  283.     targetWindow.setBackgroundColor(colors.black)
  284. end
  285. -- line drawing API
  286.  
  287.  
  288. -- window management
  289. local console = {
  290.     log = function(message)
  291.         local currentTerm = term.current()
  292.         term.redirect(consoleWindow)
  293.  
  294.         print(message)
  295.  
  296.         term.redirect(currentTerm)
  297.     end
  298. }
  299.  
  300. local function showWindows(...)
  301.     for i, v in ipairs(arg) do
  302.         if v.active == true then
  303.             v.setVisible(true)
  304.         else
  305.             v.setVisible(false)
  306.         end
  307.     end
  308. end
  309.  
  310. local function hideWindows(...)
  311.     for i, v in ipairs(arg) do
  312.         v.setVisible(false)
  313.     end
  314. end
  315.  
  316. local function getCursorPositionRelativeToParent(currentWindow)
  317.     -- determine offset of current window from parent
  318.     local x, y = currentWindow.getPosition()
  319.     local xOffset, yOffset = x - 1, y - 1
  320.    
  321.     local cursorX, cursorY = currentWindow.getCursorPos()
  322.     return cursorX + xOffset, cursorY + yOffset
  323. end
  324.  
  325. local function createInformationWindow(parentWindow)
  326.     local width, height = parentWindow.getSize()
  327.  
  328.     local widthOffset = 2
  329.     local heightOffset = 2
  330.  
  331.     local windowWidth = width - (widthOffset * 2)
  332.     local windowHeight = height - (heightOffset * 2)
  333.  
  334.     local informationWindow = window.create(parentWindow, 1 + widthOffset, 1 + heightOffset, windowWidth, windowHeight, false)
  335.     informationWindow.active = false
  336.  
  337.     drawHorizontalLine(informationWindow, 1, 1, windowWidth)
  338.     drawHorizontalLine(informationWindow, 1, windowHeight, windowWidth)
  339.  
  340.     drawVerticalLine(informationWindow, 1, 1, windowHeight)
  341.     drawVerticalLine(informationWindow, windowWidth, 1, windowHeight)
  342.  
  343.     return informationWindow
  344. end
  345.  
  346. local function createSummaryWindow(parentWindow, x, y)
  347.     local width, height = parentWindow.getSize()
  348.  
  349.     -- we make use of the parent window's cursor position to make it more convenient.
  350.     local x, y = parentWindow.getCursorPos()
  351.     local newHeight = height - (y - 1)
  352.  
  353.     local summaryWindow = window.create(parentWindow, x, y, width, newHeight, false)
  354.     summaryWindow.active = false
  355.  
  356.     return summaryWindow
  357. end
  358.  
  359. local function printToWindow(targetWindow, widthOffset, text)
  360.     local x, y = targetWindow.getCursorPos()
  361.     local width, height = targetWindow.getSize()
  362.     local maxTextSize = width - (widthOffset * 2)
  363.  
  364.     targetWindow.write(text:sub(1, maxTextSize))
  365.     targetWindow.setCursorPos(x, y+1)
  366. end
  367.  
  368. local function createDashboardWindows(parentWindow)
  369.     -- order is important here!
  370.     local summaryWindow = createSummaryWindow(parentWindow)
  371.     summaryWindow.active = true
  372.     local informationWindow = createInformationWindow(parentWindow)
  373.     informationWindow.active = false
  374.  
  375.     local windows = {
  376.         [1] = summaryWindow,
  377.         [2] = informationWindow,
  378.  
  379.         getSummaryWindow = function()
  380.             return summaryWindow
  381.         end,
  382.  
  383.         getInformationWindow = function()
  384.             return informationWindow
  385.         end
  386.     }
  387.  
  388.     return windows
  389. end
  390.  
  391. local function initializeNativeDisplayTabs()
  392.     local nativeTerm = term.native()
  393.     nativeTerm.setCursorPos(1, 2)
  394.  
  395.     local dashboardWindows = createDashboardWindows(nativeTerm)
  396.  
  397.     table.insert(nativeDisplayTabs, {
  398.         tab = {
  399.             label = "Dashboard",
  400.             event = "dashboard_clicked",
  401.             active = true,
  402.             startX = 0,
  403.             startY = 0
  404.         },
  405.  
  406.         windows = dashboardWindows
  407.     })
  408.     table.insert(nativeDisplayTabs, {
  409.         tab = {
  410.             label = "Monitors",
  411.             event = "monitors_clicked",
  412.             startX = 0,
  413.             startY = 0
  414.         },
  415.  
  416.         windows = { monitorSelectionWindow }
  417.     })
  418.     table.insert(nativeDisplayTabs, {
  419.         tab = {
  420.             label = "Console",
  421.             event = "console_clicked",
  422.             startX = 0,
  423.             startY = 0
  424.         },
  425.  
  426.         windows = { consoleWindow }
  427.     })
  428.  
  429.     nativeDisplayTabs.getSelectedTab = function(x, y)
  430.         if x == nil or y == nil then
  431.             return nil
  432.         end
  433.  
  434.         for i, v in ipairs(nativeDisplayTabs) do
  435.             local tab = v.tab
  436.             local withinX = x >= tab.startX and x <= tab.endX
  437.             local withinY = y >= tab.startY and y <= tab.endY
  438.  
  439.             if withinX and withinY then
  440.                 return i
  441.             end
  442.         end
  443.  
  444.         return nil
  445.     end
  446.  
  447.     nativeDisplayTabs.setSelectedTab = function(selected)
  448.         for i, v in ipairs(nativeDisplayTabs) do
  449.             if i == selected then
  450.                 v.tab.active = true
  451.             else
  452.                 v.tab.active = false
  453.             end
  454.         end
  455.     end
  456.  
  457.     nativeDisplayTabs.getActiveTab = function()
  458.         for i, v in ipairs(nativeDisplayTabs) do
  459.             if v.tab.active == true then
  460.                 return i
  461.             end
  462.         end
  463.     end
  464.  
  465.     nativeDisplayTabs.getDashboardWindows = function()
  466.         return dashboardWindows
  467.     end
  468. end
  469.  
  470. -- window management
  471.  
  472.  
  473. -- capacitor management
  474. local function addCapacitors(...)
  475.     local peripheralList = arg
  476.  
  477.     if #peripheralList == 0 then
  478.         peripheralList = peripheral.getNames()
  479.         capacitors.clear()
  480.     end
  481.  
  482.     for i, p in ipairs(peripheralList) do
  483.         local currentPeripheral = peripheral.wrap(p)
  484.  
  485.         if currentPeripheral[GET_ENERGY_STORED_FUNCTION] ~= nil and currentPeripheral[GET_MAX_ENERGY_STORED_FUNCTION] ~= nil and currentPeripheral[GET_ENERGY_STORED_FUNCTION]("north") ~= nil then
  486.             console.log("Adding new capacitor: "..p)
  487.             capacitors.add({
  488.                 name = p,
  489.                 peripheral = currentPeripheral,
  490.                 lastReading = 0,
  491.                 flowRate = 0,
  492.                 percent = 0
  493.             })
  494.         end
  495.     end
  496. end
  497.  
  498. local function removeCapacitors(...)
  499.     for i, k in ipairs(arg) do
  500.         capacitors.remove(k)
  501.     end
  502. end
  503.  
  504. local function getReading()
  505.     local totalEnergyAvailable, totalCapacity, totalFlowRate = 0, 0, 0
  506.  
  507.     for i, v in ipairs(capacitors) do
  508.         local currentReading = v.peripheral[GET_ENERGY_STORED_FUNCTION]("north") or 0
  509.         local capacity = v.peripheral[GET_MAX_ENERGY_STORED_FUNCTION]("north") or 0
  510.  
  511.         if currentReading ~= nil then
  512.             v.flowRate = (currentReading - v.lastReading) / TICK_DELAY
  513.             v.lastReading = currentReading
  514.  
  515.             if capacity == 0 then
  516.                 v.percent = 0
  517.             else
  518.                 v.percent = math.floor((currentReading / capacity) * 100)
  519.             end
  520.  
  521.             totalEnergyAvailable = totalEnergyAvailable + v.lastReading
  522.             totalFlowRate = totalFlowRate + v.flowRate
  523.         end
  524.  
  525.         totalCapacity = totalCapacity + capacity
  526.     end
  527.  
  528.     local sortByLastReading = function(a, b)
  529.         return a.percent > b.percent
  530.     end
  531.  
  532.     table.sort(capacitors, sortByLastReading)
  533.  
  534.     return totalEnergyAvailable, totalCapacity, totalFlowRate
  535. end
  536.  
  537. local function emitRedstoneSignalOnLowPower(percent)
  538.     if percent < LOW_POWER_THRESHOLD and rs.getOutput(SIDE_TO_EMIT_REDSTONE_ON_LOW_POWER) == false then
  539.         console.log("Low power threshold reached.")
  540.         rs.setOutput(SIDE_TO_EMIT_REDSTONE_ON_LOW_POWER, true)
  541.     elseif percent >= NORMAL_POWER_THRESHOLD and rs.getOutput(SIDE_TO_EMIT_REDSTONE_ON_LOW_POWER) == true then
  542.         console.log("Back to normal power levels.")
  543.         rs.setOutput(SIDE_TO_EMIT_REDSTONE_ON_LOW_POWER, false)
  544.     end
  545. end
  546. -- capacitor management
  547.  
  548.  
  549. -- monitor management
  550. local function addMonitors(...)
  551.     local monitorList = arg
  552.  
  553.     if #monitorList == 0 then
  554.         monitorList = peripheral.getNames()
  555.         monitors = {}
  556.     end
  557.  
  558.     for i, m in ipairs(monitorList) do
  559.         local currentPeripheral = peripheral.wrap(m)
  560.  
  561.         if "monitor" == peripheral.getType(m) and currentPeripheral.isColour() == true then
  562.             console.log("Adding new monitor: "..m)
  563.             currentPeripheral.setCursorPos(1, 1)
  564.             monitors[m] = {
  565.                 peripheral = currentPeripheral,
  566.                 windows = createDashboardWindows(currentPeripheral),
  567.                 active = false
  568.             }
  569.         end
  570.     end
  571. end
  572.  
  573. local function removeMonitors(...)
  574.     local activeMonitorsCount = tableSize(MONITORS_ACTIVE)
  575.  
  576.     for i, k in ipairs(arg) do
  577.         monitors[k] = nil
  578.         dashboardButtons[k] = nil
  579.         MONITORS_ACTIVE[k] = nil
  580.     end
  581.  
  582.     if activeMonitorsCount ~= tableSize(MONITORS_ACTIVE) then
  583.         saveSettings()
  584.     end
  585. end
  586. -- monitor management
  587.  
  588.  
  589. -- hotplug system
  590. local function doWhileMonitorSuspended(callback)
  591.     os.queueEvent("pause_monitor")
  592.     callback()
  593.     os.queueEvent("resume_monitor")
  594. end
  595.  
  596. local function hotplugPeripherals()
  597.     while true do
  598.         local event, name = os.pullEvent()
  599.         local callback = nil
  600.  
  601.         if event == "peripheral" then
  602.             console.log("Trovata nuova periferica: "..name)
  603.  
  604.             callback = function()
  605.                 addMonitors(name)
  606.                 addCapacitors(name)
  607.             end
  608.         elseif event == "peripheral_detach" then
  609.             console.log("Periferica rimossa: "..name)
  610.  
  611.             callback = function()
  612.                 removeMonitors(name)
  613.                 removeCapacitors(name)
  614.             end
  615.         elseif event == "monitor_resize" then
  616.             console.log("Monitor ridimensionato: "..name)
  617.  
  618.             callback = function()
  619.                 monitors[name].peripheral.setCursorPos(1, 1)
  620.                 monitors[name].windows = createDashboardWindows(monitors[name].peripheral)
  621.                 dashboardButtons[name] = nil
  622.  
  623.                 if monitors[name].active == true then
  624.                     showWindows(unpack(monitors[name].windows))
  625.                 end
  626.             end
  627.         end
  628.  
  629.         if callback ~= nil then
  630.             doWhileMonitorSuspended(callback)
  631.         end
  632.     end
  633. end
  634. -- hotplug system
  635.  
  636.  
  637. -- information window for the capacitors
  638. local function addClickableLine(monitorName, key, currentY)
  639.     clickableLines[monitorName][key] = {
  640.         line = currentY
  641.     }
  642. end
  643.  
  644. local function toggleInformationWindow(summaryWindow, informationWindow, capacitorName)
  645.     if capacitorName == nil then
  646.         summaryWindow.active = true
  647.         informationWindow.active = false
  648.     else
  649.         summaryWindow.active = not summaryWindow.active
  650.         informationWindow.active = not informationWindow.active
  651.     end
  652.  
  653.     local capacitor = capacitors.get(capacitorName)
  654.  
  655.     if informationWindow.active == true then
  656.         widthOffset = 3
  657.         heightOffset = 3
  658.  
  659.         informationWindow.setCursorPos(widthOffset, heightOffset)
  660.         local width, height = informationWindow.getSize()
  661.         local labelWidth = width - (widthOffset * 2)
  662.         local capacity = capacitor.peripheral[GET_MAX_ENERGY_STORED_FUNCTION]("north")
  663.  
  664.         printToWindow(informationWindow, widthOffset, "Nome Batteria:")
  665.         printToWindow(informationWindow, widthOffset, padRight("    "..capacitorName, labelWidth))
  666.         printToWindow(informationWindow, widthOffset, "Tipo Batteria:")
  667.         printToWindow(informationWindow, widthOffset, padRight("    "..peripheral.getType(capacitorName), labelWidth))
  668.         printToWindow(informationWindow, widthOffset, "Capacita':")
  669.         printToWindow(informationWindow, widthOffset, padRight("    "..capacity.." RF", labelWidth))
  670.         printToWindow(informationWindow, widthOffset, "Energia disponibile:")
  671.         printToWindow(informationWindow, widthOffset, padRight("    "..capacitor.lastReading.." RF", labelWidth))
  672.  
  673.         local closeLabel = " Clicka per chiudere "
  674.    
  675.         local x = math.floor(((width - string.len(closeLabel)) / 2 ) + 0.5)
  676.    
  677.         informationWindow.setCursorPos(x, height-2)
  678.  
  679.         informationWindow.setBackgroundColor(colors.red)
  680.         informationWindow.write(closeLabel)
  681.         informationWindow.setBackgroundColor(colors.black)
  682.     end
  683.  
  684.     showWindows(summaryWindow, informationWindow)
  685. end
  686.  
  687. local function checkForSelectableLine(monitorName, x, y)
  688.     if clickableLines[monitorName] == nil then
  689.         return nil
  690.     end
  691.  
  692.     for k,v in pairs(clickableLines[monitorName]) do
  693.         if y == v.line then
  694.             return k
  695.         end
  696.     end
  697.  
  698.     return nil
  699. end
  700.  
  701. local function getSelectedDashboardButton(monitorName, x, y)
  702.     if x == nil or y == nil then
  703.         return nil
  704.     end
  705.  
  706.     local v = dashboardButtons[monitorName]
  707.  
  708.     local nextButtonSelected = (x >= v.next.startX and x <= v.next.endX) and (y >= v.next.startY and y <= v.next.endY)
  709.     local prevButtonSelected = (x >= v.prev.startX and x <= v.prev.endX) and (y >= v.prev.startY and y <= v.prev.endY)
  710.  
  711.     if nextButtonSelected then
  712.         return "Next"
  713.     elseif prevButtonSelected then
  714.         return "Prev"
  715.     end
  716.  
  717.     return nil
  718. end
  719.  
  720. -- information window for the capacitors
  721.  
  722.  
  723. -- main display
  724. local function renderPaginationButtons(monitorName, max)
  725.     local width, height = term.getSize()
  726.     local nextButton = " ---> "
  727.     local previousButton = " <--- "
  728.     local spacer = "    "
  729.  
  730.     local dashboardButtonsToRender = previousButton..spacer..nextButton
  731.     local buttonOffset = (width - (string.len(dashboardButtonsToRender))) / 2
  732.  
  733.     term.setCursorPos(buttonOffset, height)
  734.     local x, y = getCursorPositionRelativeToParent(term.current())
  735.  
  736.     if dashboardButtons[monitorName] ==  nil then
  737.         dashboardButtons[monitorName] = {
  738.             prev = {
  739.                 startX = x,
  740.                 startY = y,
  741.                 endX = x,
  742.                 endY = y
  743.             },
  744.  
  745.             next = {
  746.                 startX = x,
  747.                 startY = y,
  748.                 endX = x,
  749.                 endY = y
  750.             },
  751.  
  752.             offset = 1,
  753.             max = max
  754.         }
  755.     end
  756.  
  757.     if dashboardButtons[monitorName].offset == 1 then
  758.         dashboardButtons[monitorName].max = max
  759.     end
  760.  
  761.     term.setBackgroundColor(colors.red)
  762.     term.write(previousButton)
  763.     dashboardButtons[monitorName].prev.endX, dashboardButtons[monitorName].prev.endY = getCursorPositionRelativeToParent(term.current())
  764.  
  765.     term.setBackgroundColor(colors.black)
  766.     term.write(spacer)
  767.  
  768.     dashboardButtons[monitorName].next.startX, dashboardButtons[monitorName].next.startY = getCursorPositionRelativeToParent(term.current())
  769.     term.setBackgroundColor(colors.red)
  770.     term.write(nextButton)
  771.     dashboardButtons[monitorName].next.endX, dashboardButtons[monitorName].next.endY = getCursorPositionRelativeToParent(term.current())
  772.  
  773.     term.setBackgroundColor(colors.black)
  774. end
  775.  
  776. local function writeSummary(monitorName, totalEnergyAvailable, totalCapacity, totalFlowRate)
  777.     local width, height = term.getSize()
  778.     local gridLabel = os.getComputerLabel() or "No name set"
  779.     local gridLabelOffset = (width - (string.len(gridLabel))) / 2
  780.  
  781.     term.setCursorPos(gridLabelOffset, 1)
  782.     term.write(gridLabel)
  783.     term.setCursorPos(1, 3)
  784.  
  785.     print(padRight("Batterie Totali: "..tostring(#capacitors)))
  786.     print(padRight("Massima Energia Storata: "..totalCapacity.." RF"))
  787.  
  788.     local totalPercentRemaining = math.floor((totalEnergyAvailable / totalCapacity) * 100)
  789.     emitRedstoneSignalOnLowPower(totalPercentRemaining)
  790.  
  791.     printZoneText(totalPercentRemaining, function() print(padRight("Energia Disponibile: "..totalEnergyAvailable.." RF")) end)
  792.  
  793.     if totalFlowRate < 0 then
  794.         term.setTextColor(colors.red)
  795.     elseif totalFlowRate > 0 then
  796.         term.setTextColor(colors.green)
  797.     else
  798.         term.setTextColor(colors.white)
  799.     end
  800.  
  801.     print(padRight("I/O: "..totalFlowRate.." RF/t"))
  802.     term.setTextColor(colors.white)
  803.  
  804.     local currentX, currentY = term.getCursorPos()
  805.     term.setCursorPos(1, currentY+1)
  806.  
  807.     clickableLines[monitorName] = {}
  808.     local pagination = dashboardButtons[monitorName] or {}
  809.     local offset = pagination.offset or 1
  810.  
  811.     local count = 0
  812.     for i = offset, #capacitors do
  813.         local v = capacitors[i]
  814.         local name = string.format(" %03d", i)..": "
  815.         local percent = v.percent
  816.  
  817.         printZoneText(percent, function() term.write(name) end)
  818.  
  819.         local labelLength = string.len(name)
  820.         local powerBarLength = width - labelLength - 1
  821.         local powerBarReading = math.floor((width - labelLength - 1) * (percent/100))
  822.  
  823.         local zoneColor = colors.red
  824.         local textColor = colors.white
  825.         if percent >= GREEN_ZONE then
  826.             zoneColor = colors.green
  827.         elseif percent >= YELLOW_ZONE and percent < GREEN_ZONE then
  828.             zoneColor = colors.yellow
  829.             textColor = colors.blue
  830.         end
  831.  
  832.         local stats = padRight(string.format(" %d", percent).."%, "..v.flowRate.." RF/t", powerBarLength)
  833.  
  834.         term.setTextColor(textColor)
  835.         term.setBackgroundColor(zoneColor)
  836.         j = 1
  837.         for c in stats:gmatch(".") do
  838.             if(j>powerBarReading) then
  839.                 term.setBackgroundColor(colors.black)
  840.             end
  841.  
  842.             term.write(c)
  843.  
  844.             j = j + 1
  845.         end
  846.         term.setTextColor(colors.white)
  847.         term.setBackgroundColor(colors.black)
  848.  
  849.         local currentX, currentY = getCursorPositionRelativeToParent(term.current())
  850.         addClickableLine(monitorName, v.name, currentY)
  851.  
  852.         local termX, termY = term.getCursorPos()
  853.         term.setCursorPos(1, termY+2)
  854.         count = count + 1
  855.  
  856.         if termY > (height - 4) then
  857.             max = count
  858.             break
  859.         end
  860.     end
  861.  
  862.     local currentX, currentY = term.getCursorPos()
  863.     for k = currentY, height-1 do
  864.         term.setCursorPos(1, k)
  865.         term.clearLine()
  866.     end
  867.  
  868.     renderPaginationButtons(monitorName, count)
  869. end
  870.  
  871. local function displaySummary(totalEnergyAvailable, totalCapacity, totalFlowRate, targetMonitor)
  872.     local listOfSummaryWindows = {
  873.         native = nativeDisplayTabs.getDashboardWindows().getSummaryWindow()
  874.     }
  875.  
  876.     for k, v in pairs(monitors) do
  877.         listOfSummaryWindows[k] = v.windows.getSummaryWindow()
  878.     end
  879.  
  880.     for k, v in pairs(listOfSummaryWindows) do
  881.         if targetMonitor == nil or (k == targetMonitor) then
  882.             local currentTerm = term.current()
  883.  
  884.             term.redirect(v)
  885.  
  886.             writeSummary(k, totalEnergyAvailable, totalCapacity, totalFlowRate)
  887.  
  888.             term.redirect(currentTerm)
  889.  
  890.             if k == targetMonitor then
  891.                 return
  892.             end
  893.         end
  894.     end
  895. end
  896.  
  897. local function monitorCapacitors()
  898.     totalEnergyAvailable, totalCapacity, totalFlowRate = 0, 0, 0
  899.  
  900.     while true do
  901.         -- show reading
  902.         displaySummary(totalEnergyAvailable, totalCapacity, totalFlowRate)
  903.  
  904.         -- need to call this first to get most current sample
  905.         getReading()
  906.  
  907.         local samplingTimer = os.startTimer(PAUSE_TIME_IN_SECONDS)
  908.         while true do
  909.             local event, p1 = os.pullEvent()
  910.             if event == "timer" and p1 == samplingTimer then
  911.                 totalEnergyAvailable, totalCapacity, totalFlowRate = getReading()
  912.                 break
  913.             elseif event == "pause_monitor" then
  914.                 os.pullEvent("resume_monitor")
  915.                 break
  916.             end
  917.         end
  918.     end
  919. end
  920.  
  921. local function changePages(monitor, x, y, isInformationWindowActive)
  922.     local selectedButton = getSelectedDashboardButton(monitor, x, y)
  923.     local showSummary = false
  924.  
  925.     if selectedButton == "next" and not isInformationWindowActive then
  926.         local newOffset = dashboardButtons[monitor].offset + (dashboardButtons[monitor].max or 0)
  927.         if newOffset <= #capacitors then
  928.             dashboardButtons[monitor].offset = newOffset
  929.  
  930.             showSummary = true
  931.         end
  932.     elseif selectedButton == "prev" and not isInformationWindowActive then
  933.         local newOffset = dashboardButtons[monitor].offset - (dashboardButtons[monitor].max or 0)
  934.         if newOffset > 0 then
  935.             dashboardButtons[monitor].offset = newOffset
  936.         else
  937.             dashboardButtons[monitor].offset = 1
  938.         end
  939.  
  940.         showSummary = true
  941.     end
  942.  
  943.     if showSummary then
  944.         displaySummary(totalEnergyAvailable, totalCapacity, totalFlowRate, p1)
  945.         return true
  946.     end
  947.  
  948.     return false
  949. end
  950.  
  951. local function nativeDashboardHandler()
  952.     while true do
  953.         local event, x, y = os.pullEvent("dashboard_clicked")
  954.         local isInformationWindowActive = nativeDisplayTabs.getDashboardWindows().getInformationWindow().active
  955.  
  956.         if not changePages("native", x, y, isInformationWindowActive) then
  957.             local selectedCapacitor = checkForSelectableLine("native", x, y)
  958.  
  959.             local summaryWindow = nativeDisplayTabs.getDashboardWindows().getSummaryWindow()
  960.             local informationWindow = nativeDisplayTabs.getDashboardWindows().getInformationWindow()
  961.  
  962.             toggleInformationWindow(summaryWindow, informationWindow, selectedCapacitor)
  963.         end
  964.     end
  965. end
  966.  
  967. local function monitorDashboardHandler()
  968.     while true do
  969.         local event, monitor, x, y = os.pullEvent("monitor_touch")
  970.  
  971.         if monitors[monitor].active == true then
  972.             local summaryWindow = monitors[monitor].windows.getSummaryWindow()
  973.             local informationWindow = monitors[monitor].windows.getInformationWindow()
  974.  
  975.             if not changePages(monitor, x, y, informationWindow.active) then
  976.                 local selectedCapacitor = checkForSelectableLine(monitor, x, y)
  977.                 toggleInformationWindow(summaryWindow, informationWindow, selectedCapacitor)
  978.             end
  979.         end
  980.     end
  981. end
  982. -- main display
  983.  
  984.  
  985. -- monitor selection screen (if monitor is attached)
  986. local function addClickableOutputMonitor(k, currentY)
  987.     clickableOutputMonitors[k] = {
  988.         line = currentY
  989.     }
  990. end
  991.  
  992. local function toggleMonitor(monitorName)
  993.     monitors[monitorName].active = not monitors[monitorName].active
  994.  
  995.     if monitors[monitorName].active then
  996.         console.log("Enabling "..monitorName)
  997.         MONITORS_ACTIVE[monitorName] = true
  998.     else
  999.         console.log("Disabling "..monitorName)
  1000.         MONITORS_ACTIVE[monitorName] = nil
  1001.  
  1002.         hideWindows(unpack(monitors[monitorName].windows))
  1003.         monitors[monitorName].peripheral.setBackgroundColor(colors.black)
  1004.         monitors[monitorName].peripheral.clear()
  1005.     end
  1006.  
  1007.     saveSettings()
  1008. end
  1009.  
  1010. local function showMonitorSelection(targetWindow)
  1011.     local currentTerm = term.current()
  1012.  
  1013.     term.redirect(targetWindow)
  1014.     term.setCursorPos(1, 1)
  1015.     term.clear()
  1016.  
  1017.     local width, height = term.getSize()
  1018.  
  1019.     if tableSize(monitors) > 0 then
  1020.         printToWindow(term, 0, "Seleziona monitor di output: ")
  1021.     else
  1022.         printToWindow(term, 0, "Nessun monitor trovato.")
  1023.     end
  1024.  
  1025.     printToWindow(term, 0, "")
  1026.  
  1027.     local currentX, currentY = term.getCursorPos()
  1028.     term.setCursorPos(currentX + 2, currentY)
  1029.  
  1030.     clickableOutputMonitors = {}
  1031.     for k, v in pairs(monitors) do
  1032.         currentX, currentY = getCursorPositionRelativeToParent(targetWindow)
  1033.         term.setBackgroundColor(colors.black)
  1034.  
  1035.         if v.active == true then
  1036.             term.setBackgroundColor(colors.blue)
  1037.             showWindows(unpack(v.windows))
  1038.         end
  1039.  
  1040.         label = padRight("  "..k, width-4)
  1041.         printToWindow(term, 0, label)
  1042.  
  1043.         addClickableOutputMonitor(k, currentY)
  1044.     end
  1045.     term.setBackgroundColor(colors.black)
  1046.  
  1047.     term.redirect(currentTerm)
  1048.  
  1049.     while true do
  1050.         local event, x, y = os.pullEvent()
  1051.  
  1052.         if "monitors_clicked" == event then
  1053.             for k, v in pairs(clickableOutputMonitors) do
  1054.                 if v.line == y then
  1055.                     toggleMonitor(k)
  1056.                     return
  1057.                 end
  1058.             end
  1059.         elseif event == "peripheral" or event == "peripheral_detach" then
  1060.             coroutine.yield()
  1061.             return
  1062.         end
  1063.     end
  1064. end
  1065.  
  1066. local function monitorSelection()
  1067.     for k, v in pairs(MONITORS_ACTIVE) do
  1068.         if monitors[k] then
  1069.             monitors[k].active = true
  1070.         end
  1071.     end
  1072.  
  1073.     while true do
  1074.         showMonitorSelection(monitorSelectionWindow)
  1075.     end
  1076. end
  1077.  
  1078. local function nativeDisplay()
  1079.     while true do
  1080.         local currentTerm = term.current()
  1081.  
  1082.         term.redirect(nativeMonitorTabWindow)
  1083.         nativeMonitorTabWindow.setVisible(true)
  1084.  
  1085.         term.setCursorPos(1, 1)
  1086.         term.setBackgroundColor(colors.gray)
  1087.         term.clearLine()
  1088.         term.setTextColor(colors.yellow)
  1089.  
  1090.         for i, v in ipairs(nativeDisplayTabs) do
  1091.             hideWindows(unpack(v.windows))
  1092.         end
  1093.  
  1094.         for i, v in ipairs(nativeDisplayTabs) do
  1095.             local tab = v.tab
  1096.             tab.startX, tab.startY = getCursorPositionRelativeToParent(term.current())
  1097.  
  1098.             if tab.active then
  1099.                 term.setBackgroundColor(colors.black)
  1100.                 showWindows(unpack(v.windows))
  1101.             else
  1102.                 term.setBackgroundColor(colors.gray)
  1103.             end
  1104.  
  1105.             term.write(" "..tab.label.." ")
  1106.             tab.endX, tab.endY = getCursorPositionRelativeToParent(term.current())
  1107.         end
  1108.         term.setTextColor(colors.white)
  1109.         term.redirect(currentTerm)
  1110.  
  1111.         while true do
  1112.             local event, selectedTab = os.pullEvent("selected_tab")
  1113.  
  1114.             if selectedTab then
  1115.                 nativeDisplayTabs.setSelectedTab(selectedTab)
  1116.                 break
  1117.             end
  1118.         end
  1119.     end
  1120. end
  1121.  
  1122. local function mouseClickEventMonitor()
  1123.     while true do
  1124.         local event, type, x, y = os.pullEvent("mouse_click")
  1125.         local selectedTab = nativeDisplayTabs.getSelectedTab(x, y)
  1126.  
  1127.         if selectedTab and nativeDisplayTabs.getDashboardWindows().getInformationWindow().active == false then
  1128.             os.queueEvent("selected_tab", selectedTab)
  1129.         elseif selectedTab == nil then
  1130.             local activeTab = nativeDisplayTabs[nativeDisplayTabs.getActiveTab()]
  1131.  
  1132.             os.queueEvent(activeTab.tab.event, x, y)
  1133.         end
  1134.     end
  1135. end
  1136.  
  1137. -- Initialization
  1138. initializeNativeDisplayTabs()
  1139. resetRedstoneState()
  1140. addCapacitors()
  1141. addMonitors()
  1142.  
  1143. while true do
  1144.     parallel.waitForAll(mouseClickEventMonitor, nativeDisplay, monitorSelection, hotplugPeripherals, monitorCapacitors, nativeDashboardHandler, monitorDashboardHandler)
  1145. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement