--- /dev/null
+local config = dofile("/etc/rscr.lua")
+
+local modem
+do
+ local m
+ if config.modem ~= nil then
+ m = peripheral.wrap(config.modem)
+ else
+ m = peripheral.find("modem")
+ end
+ if m then
+ modem = peripheral.getName(m)
+ peripheral.call(modem, "open", config.controller_port)
+ else
+ print("No modem connected")
+ return false
+ end
+end
+
+local speed_controller
+do
+ local sc
+ if config.speed_controller ~= nil then
+ sc = peripheral.wrap(config.speed_controller)
+ else
+ sc = peripheral.find("Create_RotationSpeedController")
+ end
+ if sc then
+ speed_controller = peripheral.getName(sc)
+ else
+ print("No rotation speed controller connected")
+ return false
+ end
+end
+
+local stressometer
+do
+ local sm
+ if config.stressometer ~= nil then
+ sm = peripheral.wrap(config.stressometer)
+ else
+ sm = peripheral.find("Create_Stressometer")
+ end
+ if sm then
+ stressometer = peripheral.getName(sm)
+ else
+ print("No stressometer connected, limited functionality")
+ end
+end
+
+local transmit = function(payload)
+ peripheral.call(modem, "transmit", config.remote_port, config.controller_port, textutils.serialize(payload, { compact = true }))
+end
+
+local st =
+ { name = config.controller_name
+ , speed =
+ { absolute = 0
+ , percentage = 0
+ }
+ , stress =
+ { absolute = 0
+ , capacity = 0
+ , percentage = 0
+ }
+ }
+
+do if not stressometer then st.stress = nil end end
+
+-- if called without argument: (getter)
+-- watch for changes. returns true if changed, false otherwise.
+-- if called with table: (setter)
+-- make changes accordingly. return true
+local update = function(set_speed)
+ local new_st = textutils.unserialize(textutils.serialize(st))
+ local updated = false
+ local x = config.max_speed - config.min_speed
+
+ if set_speed and set_speed >= 0 and set_speed <= 100 then
+ new_st.speed.absolute = math.floor(((set_speed / 100) * x) + config.min_speed + 0.5)
+ peripheral.call(speed_controller, "setTargetSpeed", new_st.speed.absolute)
+ updated = true
+ else
+ new_st.speed.absolute = peripheral.call(speed_controller, "getTargetSpeed")
+ if new_st.speed.absolute ~= st.speed.absolute then updated = true end
+ end
+ new_st.speed.percentage = math.floor(((new_st.speed.absolute - config.min_speed) / x * 10000) + 0.5) / 100
+
+ if stressometer then
+ sleep(0) -- if speed was just set, this is needed
+ new_st.stress.absolute = stressometer and peripheral.call(stressometer, "getStress")
+ new_st.stress.capacity = stressometer and peripheral.call(stressometer, "getStressCapacity")
+ if new_st.stress.capacity == 0 then
+ new_st.stress.percentage = 0
+ else
+ new_st.stress.percentage = math.floor(((new_st.stress.absolute / new_st.stress.capacity) * 10000) + 0.5) / 100
+ end
+ if new_st.stress.absolute ~= st.stress.absolute or
+ new_st.stress.capacity ~= st.stress.capacity then
+ updated = true
+ end
+ end
+
+ if updated then st = new_st end
+ return updated
+end
+
+local receive
+receive = function()
+ local _, p, c_port, r_port, msg, _ = os.pullEvent("modem_message")
+ if p == modem and
+ c_port == config.controller_port and
+ r_port == config.remote_port then
+ local t = textutils.unserialize(msg)
+ if t.connect then
+ transmit(st)
+ elseif t.set_speed then
+ update(t.set_speed)
+ transmit(st)
+ end
+ end
+ return receive()
+end
+
+local update_remotes
+update_remotes = function()
+ if update() then
+ transmit(st)
+ print(os.clock(), "updating...")
+ else
+ print(os.clock(), "nothing to update")
+ end
+ os.sleep(2)
+ return update_remotes()
+end
+
+parallel.waitForAny(receive, update_remotes)
--- /dev/null
+-- gui for a 15*10 advanced monitor (single monitor with text scale 0.5)
+-- sends modem messages to controller on touch event
+-- listens for modem messages from controller
+
+local config = dofile("/etc/rscr.lua")
+
+local modem
+do
+ local m
+ if config.modem ~= nil then
+ m = peripheral.wrap(config.modem)
+ else
+ m = peripheral.find("modem")
+ end
+ if m then
+ modem = peripheral.getName(m)
+ peripheral.call(modem, "open", config.remote_port)
+ else
+ print("No modem connected")
+ return false
+ end
+end
+
+local monitor
+do
+ local m
+ if config.monitor ~= nil then
+ m = peripheral.wrap(config.monitor)
+ else
+ m = peripheral.find("monitor")
+ end
+ if m then
+ monitor = peripheral.getName(m)
+ peripheral.call(monitor, "setTextScale", 0.5)
+ else
+ print("No advanced monitor connected")
+ return false
+ end
+end
+
+
+local st =
+ { name = "connecting..."
+ , speed =
+ { absolute = 0
+ , percentage = 0
+ }
+ , stress = nil
+-- { absolute = 0
+-- , max = 0
+-- , percentage =
+-- }
+ }
+
+local bar = function(len, percentage, solid)
+ if len < 1 then error("Status bar needs a positive (integral) length") end
+ local bars = math.floor(((len-1)*percentage/100) + 0.5) + 1
+ local str = ""
+ for i = 1, len do
+ if i <= bars then
+ str = str .. "|"
+ else
+ str = str .. " "
+ end
+ end
+
+ local c
+ if solid then
+ c = function(i) return solid end
+ elseif percentage == 0 then
+ c = function(i) return "7" end
+ else
+ c = function(i)
+ local p = (i-1)/(len-1)
+ if p < 0.6 then return "d" -- green
+ elseif p < 0.8 then return "1" -- orange
+ else return "e" -- red
+ end
+ end
+ end
+
+ local fg, bg = "", ""
+ for i = 1, len do
+ bg = bg .. "f"
+ fg = fg .. c(i)
+ end
+ return str, fg, bg
+end
+
+-- local print_bar = function(t, unit, width, y)
+-- local m = peripheral.wrap(monitor)
+-- m.setCursorPos(1, y)
+-- m.write(tostring(t.absolute).." "..unit)
+-- local percentage = tostring(t.percentage).."%"
+-- m.setCursorPos(width - string.len(percentage) + 1, y)
+-- m.write(percentage)
+-- m.setCursorPos(1, y + 1)
+-- m.blit(bar(width, t.percentage))
+-- end
+
+local draw = function()
+ local m = peripheral.wrap(monitor)
+ local width, _ = m.getSize()
+ local overstressed = st.stress and st.stress.absolute > st.stress.capacity
+
+ m.clear()
+ m.setCursorPos(1,1)
+ m.setTextColor(colors.white)
+ if overstressed then
+ m.setBackgroundColor(colors.red)
+ else
+ m.setBackgroundColor(colors.gray)
+ end
+ local pad
+ pad = function(i)
+ if i > 0 then return " "..pad(i-1)
+ else return "" end
+ end
+ m.write(st.name..pad(width))
+ m.setBackgroundColor(colors.black)
+ m.setCursorPos(1,2)
+ m.setBackgroundColor(colors.black)
+
+ m.setCursorPos(1,3)
+ m.write(tostring(st.speed.absolute).." RPM")
+ local speed_percentage = tostring(st.speed.percentage).."%"
+ m.setCursorPos(width - string.len(speed_percentage) + 1, 3)
+ m.write(speed_percentage)
+ m.setCursorPos(1, 4)
+ m.blit(bar(width, st.speed.percentage))
+
+ m.setCursorPos(1,6)
+ if st.stress then
+ m.write("~"..tostring(math.floor((st.stress.absolute/1000)+0.5)).." KSU")
+ local stress_percentage = tostring(st.stress.percentage).."%"
+ m.setCursorPos(width - string.len(stress_percentage) + 1, 6)
+ m.write(stress_percentage)
+ m.setCursorPos(1,7)
+ m.blit(bar(width, st.stress.percentage, overstressed and "e"))
+ m.setCursorPos(1,8)
+ m.write("total: ~"..tostring(math.floor((st.stress.capacity/1000)+0.5)).." KSU")
+ m.setCursorPos(1,9)
+ m.write("avail: ~"..tostring(math.floor(((st.stress.capacity - st.stress.absolute)/1000)+0.5)).." KSU")
+ else
+ m.setTextColor(colors.gray)
+ m.write("No stress")
+ m.setCursorPos(1,7)
+ m.write("information")
+ m.setCursorPos(1,8)
+ m.write("available")
+ m.setTextColor(colors.white)
+ end
+end
+
+local transmit = function(payload)
+ peripheral.call(modem, "transmit", config.controller_port, config.remote_port, textutils.serialize(payload, { compact = true }))
+end
+
+local touch_screen
+touch_screen = function()
+ local _, p, x, y = os.pullEvent("monitor_touch")
+ if p ~= monitor then return touch_screen() end
+ local m = peripheral.wrap(monitor)
+ local width, _ = m.getSize()
+ if x >= 1 and x <= width then
+ draw()
+ -- todo: don't hard code the y position
+ m.setCursorPos(x, 4)
+ m.blit("|", "0", "f")
+ transmit({ set_speed = math.floor((x-1)/(width-1)*10000)/100 })
+ end
+ return touch_screen()
+end
+
+local receive
+receive = function()
+ local _, p, r_port, c_port, msg, _ = os.pullEvent("modem_message")
+ if p == modem and
+ r_port == config.remote_port and
+ c_port == config.controller_port then
+ local new_st = textutils.unserialize(msg)
+ st = new_st
+ draw()
+ end
+ return receive()
+end
+
+local on_terminate = function()
+ os.pullEventRaw("terminate")
+ peripheral.call(monitor, "clear")
+end
+
+draw()
+transmit({ connect = true })
+parallel.waitForAny(on_terminate, touch_screen, receive)