Advertisement
virtualdxs

Reactor Remote Monitor Program

Jan 26th, 2021 (edited)
432
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.96 KB | None | 0 0
  1. --
  2. -- Remote monitor component for reactor control program
  3. --
  4. -- Author: VirtualDXS
  5. -- Based heavily on original reactor control program by kla_sch
  6. --
  7. -- History:
  8. --     v0.1, 2020-01-26
  9. --         First version
  10. --
  11. --
  12. -- Constant values (configuration)
  13. --
  14.  
  15. -- Port to receive telemetry on (requires wireless modem)
  16. receivePort=39124
  17.  
  18. -- Energy thresholds - make sure these match the reactor
  19. critEnergy=3000000
  20. lowEnergy=7000000
  21. highEnergy=9000000
  22.  
  23. --
  24. -- Write text with colors, if possible (advance monitor)
  25. --
  26. -- Parameters:
  27. --     mon   - handle of monitor
  28. --     color - text color
  29. --     text  - text to write
  30. --
  31. function writeColor(mon, color, text)
  32.    if (mon.isColor()) then
  33.       mon.setTextColor(color)
  34.    end
  35.    mon.write(text)
  36.    if (mon.isColor()) then
  37.       mon.setTextColor(colors.white)
  38.    end
  39. end
  40.  
  41.  
  42. --
  43. -- Display reactor status to a monitor.
  44. --
  45. -- Parameters:
  46. --     mon        - handle of monitor.
  47. --     state      - state of reactor (table, see main loop for structure)
  48. --
  49. function displayStatusToMonitor(mon, state)
  50.    mon.clear()
  51.  
  52.    -- First get the monitor size and try to scale, if the feature ist
  53.    -- available.
  54.    if mon.setTextScale ~= nil then
  55.       -- reset text scale
  56.       mon.setTextScale(1)
  57.    end
  58.  
  59.    local width, height = mon.getSize()
  60.    if width < 15 or height < 5 then
  61.       -- too small: try to scale down.
  62.       if mon.setTextScale ~= nil then
  63.          mon.setTextScale(0.5)
  64.       else
  65.          return -- too small and no text scale available
  66.       end
  67.  
  68.       width, height = mon.getSize()
  69.       if width < 15 or height < 5 then
  70.          return -- still too small
  71.       end
  72.    else
  73.       -- Huge monitors? Try to scale up, if possible (max scale=5).
  74.       local scale = math.min(width / 16, height / 5, 5)
  75.       scale = math.floor(scale * 2) / 2 -- multiple of 0.5
  76.  
  77.       if scale > 1 and mon.setTextScale ~= nil then
  78.          mon.setTextScale(scale)
  79.          width, height = mon.getSize()
  80.       end
  81.    end
  82.  
  83.  
  84.    --
  85.    -- Output the data
  86.    --
  87.  
  88.    mon.setCursorPos(1,1)
  89.    mon.write("Reactor")
  90.  
  91.    mon.setCursorPos(1,3)
  92.    mon.write("Status: ")
  93.  
  94.    if state.power then
  95.       writeColor(mon, colors.green, "ACTIVE")
  96.    else
  97.       writeColor(mon, colors.red, "INACTIVE")
  98.    end
  99.  
  100.    mon.setCursorPos(1,4)
  101.    mon.write("Rod Level: " .. state.rodLevel .. "%")
  102.  
  103.    mon.setCursorPos(1,5)
  104.    if width < 16 then
  105.       mon.write("Cell: ") -- One block monitor (15x5 with scale 0.5)
  106.    else
  107.       mon.write("Energy Buffer: ")
  108.    end
  109.  
  110.    local c
  111.    if state.cellEnergy < critEnergy then
  112.       c = colors.red -- Red: We use too much energy
  113.    elseif state.cellEnergy > lowEnergy then
  114.       c = colors.green -- Green: More energy then low water mark
  115.    else
  116.       c = colors.orange -- Orange: Less energy the low water mark, but OK
  117.    end
  118.    writeColor(mon, c, string.format("%d", math.floor(state.cellEnergy/1000 + 0.5)))
  119.    mon.write(" kRF")
  120. end
  121.  
  122.  
  123. --
  124. -- Display reactor status to any connected monitor and also to console.
  125. --
  126. -- Parameters:
  127. --     state      - state of reactor (table, see main loop for structure)
  128. --
  129. function displayStatus(state)
  130.    displayStatusToMonitor(term, state) -- console
  131.    term.setCursorPos(1,7)
  132.    term.write("* Hold Ctrl-T to terminate program")
  133.    term.setCursorPos(1,8)
  134.  
  135.    local pList = peripheral.getNames()
  136.    local i, name
  137.    for i, name in pairs(pList) do
  138.       if peripheral.getType(name) == "monitor" then
  139.          -- found monitor as peripheral
  140.          displayStatusToMonitor(peripheral.wrap(name), state)
  141.       end
  142.    end
  143. end
  144.  
  145. --
  146. -- Receive and unserialize telemetry from a reactor.
  147. -- After perfoming some sanity checks, sets the global variable `state` to
  148. -- the received table.
  149. --
  150. function receiveTelemetry()
  151.     _,_,_,_,message = os.pullEvent("modem_message")
  152.     print("Message received: " .. message)
  153.     local rxState = textutils.unserialize(message)
  154.  
  155.     if type(rxState.power) == "boolean"
  156.         and type(rxState.rodLevel) == "number"
  157.         and type(rxState.cellEnergy) == "number" then
  158.         print("pass")
  159.         state = rxState
  160.     end
  161. end
  162.  
  163.  
  164. --
  165. -- Find the first connected wireless modem and return the wrapped handle.
  166. --
  167. -- If no wireless modem is found this function terminates the program.
  168. --
  169. -- Return:
  170. --     Handle of first connected wireless modem found.
  171. --
  172. function getModemHandle()
  173.    local pList = peripheral.getNames()
  174.    local i, name
  175.    for i, name in pairs(pList) do
  176.       if peripheral.getType(name) == "modem" then
  177.          if peripheral.call(name,"isWireless") then
  178.             return peripheral.wrap(name)
  179.          end
  180.       end
  181.    end
  182.  
  183.    error("No wireless modem connected: Exit program")
  184.    exit()
  185. end
  186.  
  187. modem = getModemHandle()
  188. modem.open(receivePort)
  189.  
  190. --
  191. -- Endless loop: Receive telemetry, display reactor state,
  192. -- and wait for 5 seconds.
  193. --
  194. while true do
  195.     state = nil
  196.  
  197.     local success,err = pcall(receiveTelemetry)
  198.     if not success then print(err) end
  199.  
  200.     if state then
  201.         displayStatus(state)
  202.     end
  203. end
  204.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement