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
Comments