nSun

CC BigReactor

Dec 3rd, 2014
203
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --
  2. -- Control passive cooled Big Reactor (http://big-reactors.com/).
  3. --
  4. -- Author: kla_sch
  5. -- post: http://www.computercraft.info/forums2/index.php?/topic/18515-control-passive-cooled-big-reactors/
  6. --
  7. -- History:
  8. --    v0.1, 2014-05-05:
  9. --          first version
  10. --
  11. -- Remarks:
  12. --    Reactor API: http://big-reactors.com/cc_api.html
  13. --
  14.  
  15. -- -------------------------------
  16. -- Constant values (configuration)
  17. --
  18. -- Critical energy mark: give us the maximum power.
  19. critEnergy=3000000
  20. -- Low energy mark: turn reactor on to get more energy
  21. lowEnergy=7000000
  22. -- Heigh energy mark: we have enough, so turn the reactor off.
  23. highEnergy=9000000
  24. -- Refresh delay (seconds)
  25. delay=5
  26. -- Peripheriques
  27. pList = peripheral.getNames()
  28.  
  29.  
  30. --
  31. -- Calculate the control rod level (in %) by stored energy of internal
  32. -- recator cell.
  33. --
  34. -- * If cellEnergy <= critEnergy, the calculation results in maximum
  35. --  energy generation (control rod level = 0%).
  36. -- * If cellEnergy >= highEnergy, the calculation results in 10% energy
  37. --  generation (control rod level = 90%).
  38. --
  39. -- Parameters:
  40. --    cellEnergy - stored energy of internal cell in RF
  41. --
  42. -- Return:
  43. --    New control rod level in %.
  44. --
  45. function calcRodLevel(cellEnergy)
  46.     -- Delta between critical and heigh energy mark
  47.     local deltaEnergy = highEnergy - critEnergy
  48.  
  49.     -- Calculated maximum delta energy (not the real maximum), so that
  50.     -- the high energy mark results into a control rod level of 90%
  51.     local deltaEnergy100 = deltaEnergy * 100 / 90
  52.  
  53.     -- Energy for calculation: value between 0 and 'deltaEnergy'
  54.     local calcEnergy = cellEnergy - critEnergy
  55.  
  56.     if calcEnergy < 0 then
  57.         calcEnergy = 0
  58.     elseif calcEnergy > deltaEnergy then
  59.         calcEnergy = deltaEnergy
  60.     end
  61.  
  62.     -- Calculate control rod level and round the result (math.floor + 0.5)
  63.     return math.floor(calcEnergy * 100 / deltaEnergy100 + 0.5)
  64. end
  65.  
  66.  
  67. --
  68. -- Write text with colors, if possible (advance monitor)
  69. --
  70. -- Parameters:
  71. --    mon   - handle of monitor
  72. --    color - text color
  73. --    text  - text to write
  74. --
  75. function writeColor(mon, color, text, bgcolor)
  76.  bgcolor = bgcolor == nil and colors.black or bgcolor
  77.     if (mon.isColor()) then
  78.         mon.setTextColor(color)
  79.         mon.setBackgroundColor(bgcolor)
  80.     end
  81.     mon.write(text)
  82.     if (mon.isColor()) then
  83.         mon.setTextColor(colors.white)
  84.         mon.setBackgroundColor(colors.black)
  85.     end
  86. end
  87. function resetColor(mon)
  88.     mon.setTextColor(1)
  89.     mon.setBackgroundColor(colors.black)
  90. end
  91. function clearSquare(mon, x, y, w, h)
  92.     resetColor(mon)
  93.     for _h=1,h do
  94.         mon.setCursorPos(x,y+_h-1)
  95.         mon.write(string.rep(" ",w))
  96.     end
  97. end
  98.  
  99. --
  100. -- Display reactor status to a monitor.
  101. --
  102. -- Parameters:
  103. --    mon         - handle of monitor.
  104. --    state     - state of reactor (on/off)
  105. --    rodLvl      - Level of control rods in %
  106. --    cellEnergy - stored energy of internal cell (in RF)
  107. --
  108. function displayStatusToMonitor(mon, state, rodLvl, cellEnergy)
  109.     clearSquare(mon, 1, 3, 15, 3)
  110.  
  111.     -- First get the monitor size and try to scale, if the feature ist
  112.     -- available.
  113.     if mon.setTextScale ~= nil then
  114.         -- reset text scale
  115.         mon.setTextScale(1)
  116.     end
  117.  
  118.     local width, height = mon.getSize()
  119.     if width < 15 or height < 5 then
  120.         -- too small: try to scale down.
  121.         if mon.setTextScale ~= nil then
  122.             mon.setTextScale(0.5)
  123.         else
  124.             return -- too small und no text scale available
  125.         end
  126.  
  127.         width, height = mon.getSize()
  128.         if width < 15 or height < 5 then
  129.             return -- still too small
  130.         end
  131.     else
  132.         -- Huge monitors? Try to scale up, if possible (max scale=5).
  133.         local scale = math.min(width / 16, height / 5, 5)
  134.         scale = math.floor(scale * 2) / 2 -- multiple of 0.5
  135.  
  136.         if scale > 1 and mon.setTextScale ~= nil then
  137.             mon.setTextScale(scale)
  138.             width, height = mon.getSize()
  139.         end
  140.     end
  141.  
  142.  
  143.     --
  144.     -- Output the data
  145.     --
  146.     mon.setCursorPos(1,1)
  147.     mon.write("Reactor")
  148.  
  149.     mon.setCursorPos(1,3)
  150.     mon.write("Status ")
  151.  
  152.     if state then
  153.         writeColor(mon, colors.green, "ON")
  154.     else
  155.         writeColor(mon, colors.red, "OFF")
  156.     end
  157.  
  158.     mon.setCursorPos(1,4)
  159.     mon.write("Rod Level: " .. rodLvl .. "%")
  160.  
  161.     mon.setCursorPos(1,5)
  162.     if width < 16 then
  163.         mon.write("Cell: ") -- One block monitor (15x5 with scale 0.5)
  164.     else
  165.         mon.write("Energy: ")
  166.     end
  167.  
  168.     local c
  169.     if cellEnergy < critEnergy then
  170.         c = colors.red -- Red: We use too much energy
  171.     elseif cellEnergy > lowEnergy then
  172.         c = colors.green -- Green: More energy then low water mark
  173.     else
  174.         c = colors.orange -- Orange: Less energy the low water mark, but OK
  175.     end
  176.     writeColor(mon, c, string.format("%d", math.floor(cellEnergy/1000 + 0.5)))
  177.     mon.write(" kRF")
  178. end
  179.  
  180.  
  181. --
  182. -- Display reactor status to any connected monitor and also to console.
  183. --
  184. -- Parameters:
  185. --    state     - state of reactor (on/off)
  186. --    rodLvl      - Level of control rods in %
  187. --    cellEnergy - stored energy of internal energy cell in RF
  188. --
  189. function displayStatus(state, rodLvl, cellEnergy)
  190.     displayStatusToMonitor(term, state, rodLvl, cellEnergy) -- console
  191.     term.setCursorPos(1,17)
  192.     writeColor(term, colors.lightGray, "* Hold Crtl-T to terminate program")
  193.     term.setCursorPos(1,8)
  194.  
  195.     local i, name
  196.     for i, name in pairs(pList) do
  197.         if peripheral.getType(name) == "monitor" then
  198.             -- found monitor as peripheral
  199.             displayStatusToMonitor(peripheral.wrap(name), state, rodLvl, cellEnergy)
  200.         end
  201.     end
  202. end
  203.  
  204.  
  205. --
  206. -- Find the first connected big reactor and return the wraped handle.
  207. --
  208. -- If no reactor was found this function terminate the program.
  209. --
  210. -- Return:
  211. --    Handle of first connected reactor found.
  212. --
  213. function getReactorHandle()
  214.     local i, name
  215.     for i, name in pairs(pList) do
  216.         if peripheral.getType(name) == "BigReactors-Reactor" then
  217.             return peripheral.wrap(name)
  218.         end
  219.     end
  220.  
  221.     error("No big reactor connected: Exit program")
  222.     exit()
  223. end
  224.  
  225. function main()
  226.     reactor = getReactorHandle()
  227.  
  228.     --
  229.     -- Endless loop: Recalculate rod level, set rod level, display result
  230.     -- and wait for 5 secounds.
  231.     --
  232.     while true do
  233.         cellEnergy = reactor.getEnergyStored()
  234.         if cellEnergy < lowEnergy then
  235.             -- Low energy: switch reactor ON and calculate control rods by
  236.             -- energy cell level.
  237.             reactor.setActive(true)
  238.             rodLvl=calcRodLevel(cellEnergy)
  239.         elseif cellEnergy > highEnergy then
  240.             -- High energy: switch reactor OFF and set control rod level to 100
  241.             reactor.setActive(false)
  242.             rodLvl=100
  243.         elseif cellEnergy > lowEnergy then
  244.             -- Enough energy: do not change state of reactor. Only recalculate
  245.             -- control rod level.
  246.             --
  247.             -- * If the reactor ist switched off, we will wait until energy
  248.             --  fall below low energy mark.
  249.             --
  250.             -- * If it is turned on, we generate more energy until the
  251.             --  energy level exeeds the high energy mark.
  252.             rodLvl=calcRodLevel(cellEnergy)
  253.         end
  254.  
  255.         reactor.setAllControlRodLevels(rodLvl)
  256.  
  257.         displayStatus(reactor.getActive(), rodLvl, cellEnergy)
  258.  
  259.         os.sleep(delay) -- Wait for 5s
  260.     end
  261. end
  262.  
  263. function tickToMonitor(mon,frame)
  264.     local len = string.len(delay.."/"..delay)
  265.     local cx,cy = mon.getCursorPos()
  266.     mon.setCursorPos(16-len,1)
  267.     mon.write(string.rep(" ",len))
  268.     mon.setCursorPos(16-string.len(frame.."/"..delay),1)
  269.     writeColor(mon, colors.lightGray, frame.."/"..delay)
  270.     mon.setCursorPos(cx,cy)
  271. end
  272.  
  273. function tick()
  274.     local t=0
  275.     while true do
  276.         local f=t%delay+1
  277.         tickToMonitor(term,f)
  278.         local i, name
  279.         for i, name in pairs(pList) do
  280.             if peripheral.getType(name) == "monitor" then
  281.                 -- found monitor as peripheral
  282.                 tickToMonitor(peripheral.wrap(name),f)
  283.             end
  284.         end
  285.         sleep(1)
  286.         t=t+1
  287.     end
  288. end
  289.  
  290. function shortcutToMonitor(mon)
  291.     local cx,cy = mon.getCursorPos()
  292.     mon.setCursorPos(13,2)
  293.     writeColor(mon, colors.black, "T", colors.orange)
  294.     writeColor(mon, colors.black, "R", colors.blue)
  295.     writeColor(mon, colors.black, "S", colors.red)
  296.     resetColor(mon)
  297.     mon.setCursorPos(cx,cy)
  298. end
  299.  
  300. function shortcut()
  301.     while true do
  302.         shortcutToMonitor(term)
  303.         local i, name
  304.         for i, name in pairs(pList) do
  305.             if peripheral.getType(name) == "monitor" then
  306.                 -- found monitor as peripheral
  307.                 shortcutToMonitor(peripheral.wrap(name))
  308.             end
  309.         end
  310.         event, side, xPos, yPos = os.pullEvent()
  311.         if ((event == "mouse_click" and side == 1) or event == "monitor_touch")
  312.             and yPos == 2 then
  313.             if xPos == 13 then --T
  314.                 return
  315.             elseif xPos == 14 then --R
  316.                 os.reboot()
  317.             elseif xPos == 15 then --S
  318.                 os.shutdown()
  319.             end
  320.         end
  321.         sleep(.2)
  322.     end
  323. end
  324.  
  325. term.clear()
  326. for i, name in pairs(pList) do
  327.     if peripheral.getType(name) == "monitor" then
  328.         -- found monitor as peripheral
  329.         mon = peripheral.wrap(name)
  330.         mon.clear()
  331.     end
  332. end
  333. r = parallel.waitForAny(shortcut, tick, main)
  334. if r == 1 then
  335.     writeColor(term, colors.red, "Terminated", colors.black)
  336.     local i, name
  337.     for i, name in pairs(pList) do
  338.         if peripheral.getType(name) == "monitor" then
  339.             -- found monitor as peripheral
  340.             mon = peripheral.wrap(name)
  341.             mon.setCursorPos(1,6)
  342.             writeColor(mon, colors.red, "Terminated", colors.black)
  343.         end
  344.     end
  345.     print("")
  346. end
  347. --
  348. -- EOF
  349. --
Advertisement
Add Comment
Please, Sign In to add comment