EnergyMonitor/server/monitorReceiver.lua
2023-11-03 20:46:25 +01:00

189 lines
4.9 KiB
Lua

-- user options
local options = {
timeout = 15,
scale = 2,
}
-- clear terminal to start
term.clear()
-- system options/components
local system = {}
-- initialize ender modem
function init_modem()
local modem = peripheral.find('modem')
system.modem = modem
end
init_modem()
-- initialize monitor
function init_monitor()
local monitor = peripheral.find('monitor')
-- redirect output to monitor
term.redirect(monitor)
term.clear()
term.setCursorPos(1, 1)
-- set text scale on monitor
monitor.setTextScale(options.scale)
-- save monitor and width
system.monitor = monitor
system.width = term.getSize()
end
init_monitor()
-- check whether channel is already in use and negate output
function channel_used(channel)
for _, value in pairs(system.channels) do
if value == channel then
return true
end
end
return false
end
-- wait for components to connect to receiver
function wait_for_components()
-- reset system variables
system.timeout = false
system.components = {}
system.channels = {}
system.index = 1
-- open initializer channel
system.modem.open(1)
print('Waiting for components...')
print('Continue by clicking.')
local count = 0
while true do
-- get next pull event
local event, _, senderChannel, replyChannel, message, _ = os.pullEvent()
local component = ''
local success = false
-- reply to channel 1 (initializer) only
if event == 'modem_message' and senderChannel == 1 then
-- component is trying to connect
if channel_used(replyChannel) then
system.modem.transmit(replyChannel, replyChannel, 'used')
else
-- save component
table.insert(system.channels, replyChannel)
table.insert(system.components, message)
component = message
count = count + 1
success = true
end
elseif event == 'monitor_touch' and count > 0 then break end
-- reply with successful connection
if success then
system.modem.transmit(replyChannel, replyChannel, 'ready ' .. system.width)
-- open channel for communication
system.modem.open(replyChannel)
print(component .. ' connected!')
end
end
-- reset terminal
term.clear()
term.setCursorPos(1, 1)
-- close initializer channel
system.modem.close(1)
end
wait_for_components()
function display_messages(buffer)
print(table.concat(buffer, '\n'))
end
function add_message(buffer, text)
table.insert(buffer, text)
end
function get_messages(buffer)
-- get component data
local index = system.index
local channel = system.channels[index]
local component = system.components[index]
-- pad the index with leading zeroes for display
local length = #tostring(index)
local amount = #tostring(#system.components)
local padded = string.rep('0', #tostring(amount - length)) .. index
-- add component as title
table.insert(buffer, '#' .. padded .. ' ' .. component .. ':')
-- request data and measure elapsed time
local timer_id = os.startTimer(options.timeout)
system.modem.transmit(channel, channel, 'print')
-- keep track of exit condition
local touchExit = false
while true do
-- get next pull event
local event, _, senderChannel, _, message, _ = os.pullEvent()
if event == 'modem_message' then
-- save message in buffer
if senderChannel == channel then
table.insert(buffer, message)
system.modem.transmit(channel, channel, 'ok')
break
-- dont accept messages from wrong channel
else system.modem.transmit(senderChannel, senderChannel, 'busy') end
elseif event == 'timer' then
system.timeout = true
return
elseif event == 'monitor_touch' then
touchExit = true
end
end
-- cancel timer on success
os.cancelTimer(timer_id)
-- increment index and clear terminal on exit by touch
if touchExit then
term.clear()
system.index = system.index % #system.components + 1
return false
end
return true
end
-- main program
function main()
-- permanent runtime
while true do
term.clear()
system.test = true
while not system.timeout do
-- print over old values
term.setCursorPos(1, 1)
local buffer = {}
if get_messages(buffer) then display_messages(buffer) end
end
-- reset terminal
term.clear()
term.setCursorPos(1, 1)
print('Component disconnected!')
print('Rescanning . . . ')
-- rescan components
wait_for_components()
end
end
main()