Guest User

reactorV2

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