local cellTable = {} local isTE2 = false local linesDrawn = 0 function detect() for per, side in pairs(rs.getSides()) do if peripheral.isPresent(side) then if peripheral.getType(side) == "monitor" then mon = peripheral.wrap(side) elseif peripheral.getType(side) == "modem" then modem = side end end end return mon, modem end function updateCells(_cell, _energy, _max, _state, _isTE2) cellTable[_cell] = {energy = _energy, cellMax = _max, state = _state, isTE2 = _isTE2} end function getEnergyStats() currentSum = 0 maxSum = 0 for cell, data in pairs(cellTable) do currentSum = currentSum + data.energy maxSum = maxSum + data.cellMax end end function updateStatus(cell, energy, state) if state == "EMPTY" then mon.write("Cell "..cell.." : ") mon.setTextColor(colors.red) mon.write("EMPTY") elseif state == "FULL" then mon.write("Cell "..cell.." : ") mon.setTextColor(colors.lightBlue) mon.write("FULL") elseif state == "CHARGING" then mon.write("Cell "..cell.." : ") mon.setTextColor(colors.lime) mon.write(energy.."%") elseif state == "DISCHARGING" then mon.write("Cell "..cell.." : ") mon.setTextColor(colors.orange) mon.write(energy.."%") elseif state == "NO CHANGE" then mon.write("Cell "..cell.." : "..energy.."%") else mon.setBackgroundColor(colors.red) mon.setTextColor(colors.black) mon.write("Cell "..cell.." : ERROR") end mon.setBackgroundColor(colors.black) end function round(num, places) local multi = 10 ^ (places or 0) return math.floor(num * multi + 0.5) / multi end function getPercentage(current, max) return (current / max) * 100 end function drawBar(val, x, y) local percent local modifier local color --If the monitor is 39 cols wide or wider --then extend the bar using a static modifier if monWidth >= 61 then percent = val * 0.025 modifier = 4 elseif monWidth >= 39 then percent = val * 0.05 modifier = 2 elseif monWidth < 39 then percent = val * 0.1 modifier = 1 end --Determine what color the bar should be if percent >= 10 / modifier then color = colors.lightBlue elseif percent >= 8 / modifier then color = colors.cyan elseif percent >= 6 / modifier then color = colors.lime elseif percent >= 4 / modifier then color = colors.yellow elseif percent >= 2 / modifier then color = colors.orange else color = colors.red end --Print bar "brackets" mon.setTextColor(colors.white) mon.setCursorPos(x, y) mon.write("[") --Raise modifier to the power of 2 if --monitor is large enough --[Monitor size to segment size:] --3m wide: 10% per segment --4m wide: 5% per segment --6m wide: 2.5% per segment for i = 1, percent * (modifier ^ 2) do mon.setTextColor(color) mon.write("#") end if monWidth >= 61 then mon.setCursorPos(x + 41, y) elseif monWidth >= 39 then mon.setCursorPos(x + 21, y) elseif monWidth < 39 then mon.setCursorPos(x + 11, y) end mon.setTextColor(colors.white) mon.write("]") end --Draw all on-screen data function draw(serverID) local header = "-- Energy Storage Status --" --Energy summary mon.setBackgroundColor(colors.black) mon.setTextColor(colors.white) mon.clear() mon.setCursorPos((monWidth / 2) - (#header / 2) + 1, 1) mon.setBackgroundColor(colors.gray) mon.clearLine() mon.write(header) mon.setCursorPos(1, 3) mon.setBackgroundColor(colors.black) mon.write("System Energy : ") if isTE2 then mon.write(currentSum.." MJ") else mon.write(currentSum.." RF") end mon.setCursorPos(1, 4) mon.write("Max Sys. Energy : ") if isTE2 then mon.write(maxSum.." MJ") else mon.write(maxSum.." RF") end mon.setCursorPos(1, 6) --Render individual cell percentages, --states, and colored bars for cell, data in pairs(cellTable) do mon.setCursorPos(1, 5 + cell) print(serverID.." -> Cell "..cell.." : "..data.energy.."/"..data.cellMax.." ["..data.state.."]") linesDrawn = linesDrawn + 1 updateStatus(cell, round(getPercentage(data.energy, data.cellMax), 2), data.state) --mon.setCursorPos(17, 5 + cell) drawBar(round(getPercentage(data.energy, data.cellMax), 2), 17, 5 + cell) end --Bottom bar on monitor mon.setCursorPos(1, monHeight) mon.setBackgroundColor(colors.gray) mon.clearLine() --Reset button mon.setBackgroundColor(colors.red) mon.write(" RESET ") --Client ID local cidText = "Client ID: "..os.getComputerID() mon.setCursorPos(monWidth - #cidText, monHeight) mon.setBackgroundColor(colors.gray) mon.write(cidText) end function init() --Print client ID reminder in terminal term.clear() term.setCursorPos(1, 1) term.write("This client's ID is "..os.getComputerID()..".") term.setCursorPos(1, 3) end term.clear() mon, modem = detect() --Get initial monitor size monWidth, monHeight = mon.getSize() rednet.open(modem) init() --End program if screen is too small --Screen must be 3 blocks wide by --two blocks tall to display any info if monWidth < 29 or monHeight < 12 then error("Monitor must be 3 blocks wide by 2 blocks high to display data.") end local idle = "No Signal" mon.setCursorPos((monWidth / 2) - (#idle / 2) + 1, (monHeight / 2) + 1) mon.setBackgroundColor(colors.red) mon.write(idle) while true do event, p1, p2, p3 = os.pullEvent() if event == "monitor_touch" then if p2 <= 7 and p3 == monHeight then term.setTextColor(colors.red) print("Reboot event requested by user.") os.sleep(2) os.reboot() end end local sender, message, dist = rednet.receive() local data = textutils.unserialize(message) --Get monitor size in case size changes while client is running monWidth, monHeight = mon.getSize() updateCells(data._cellNum, data._current, data._max, data._state, data._isTE2) getEnergyStats() isTE2 = data._isTE2 draw(sender) if linesDrawn > 8 then term.clear() linesDrawn = 0 init() end end