Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --
- -- Control passive cooled Big Reactor (http://big-reactors.com/).
- --
- -- Author: kla_sch
- -- post: http://www.computercraft.info/forums2/index.php?/topic/18515-control-passive-cooled-big-reactors/
- --
- -- History:
- -- v0.1, 2014-05-05:
- -- first version
- --
- -- Remarks:
- -- Reactor API: http://big-reactors.com/cc_api.html
- --
- -- -------------------------------
- -- Constant values (configuration)
- --
- -- Critical energy mark: give us the maximum power.
- critEnergy=3000000
- -- Low energy mark: turn reactor on to get more energy
- lowEnergy=7000000
- -- Heigh energy mark: we have enough, so turn the reactor off.
- highEnergy=9000000
- -- Refresh delay (seconds)
- delay=5
- -- Peripheriques
- pList = peripheral.getNames()
- --
- -- Calculate the control rod level (in %) by stored energy of internal
- -- recator cell.
- --
- -- * If cellEnergy <= critEnergy, the calculation results in maximum
- -- energy generation (control rod level = 0%).
- -- * If cellEnergy >= highEnergy, the calculation results in 10% energy
- -- generation (control rod level = 90%).
- --
- -- Parameters:
- -- cellEnergy - stored energy of internal cell in RF
- --
- -- Return:
- -- New control rod level in %.
- --
- function calcRodLevel(cellEnergy)
- -- Delta between critical and heigh energy mark
- local deltaEnergy = highEnergy - critEnergy
- -- Calculated maximum delta energy (not the real maximum), so that
- -- the high energy mark results into a control rod level of 90%
- local deltaEnergy100 = deltaEnergy * 100 / 90
- -- Energy for calculation: value between 0 and 'deltaEnergy'
- local calcEnergy = cellEnergy - critEnergy
- if calcEnergy < 0 then
- calcEnergy = 0
- elseif calcEnergy > deltaEnergy then
- calcEnergy = deltaEnergy
- end
- -- Calculate control rod level and round the result (math.floor + 0.5)
- return math.floor(calcEnergy * 100 / deltaEnergy100 + 0.5)
- end
- --
- -- Write text with colors, if possible (advance monitor)
- --
- -- Parameters:
- -- mon - handle of monitor
- -- color - text color
- -- text - text to write
- --
- function writeColor(mon, color, text, bgcolor)
- bgcolor = bgcolor == nil and colors.black or bgcolor
- if (mon.isColor()) then
- mon.setTextColor(color)
- mon.setBackgroundColor(bgcolor)
- end
- mon.write(text)
- if (mon.isColor()) then
- mon.setTextColor(colors.white)
- mon.setBackgroundColor(colors.black)
- end
- end
- function resetColor(mon)
- mon.setTextColor(1)
- mon.setBackgroundColor(colors.black)
- end
- function clearSquare(mon, x, y, w, h)
- resetColor(mon)
- for _h=1,h do
- mon.setCursorPos(x,y+_h-1)
- mon.write(string.rep(" ",w))
- end
- end
- --
- -- Display reactor status to a monitor.
- --
- -- Parameters:
- -- mon - handle of monitor.
- -- state - state of reactor (on/off)
- -- rodLvl - Level of control rods in %
- -- cellEnergy - stored energy of internal cell (in RF)
- --
- function displayStatusToMonitor(mon, state, rodLvl, cellEnergy)
- clearSquare(mon, 1, 3, 15, 3)
- -- First get the monitor size and try to scale, if the feature ist
- -- available.
- if mon.setTextScale ~= nil then
- -- reset text scale
- mon.setTextScale(1)
- end
- local width, height = mon.getSize()
- if width < 15 or height < 5 then
- -- too small: try to scale down.
- if mon.setTextScale ~= nil then
- mon.setTextScale(0.5)
- else
- return -- too small und no text scale available
- end
- width, height = mon.getSize()
- if width < 15 or height < 5 then
- return -- still too small
- end
- else
- -- Huge monitors? Try to scale up, if possible (max scale=5).
- local scale = math.min(width / 16, height / 5, 5)
- scale = math.floor(scale * 2) / 2 -- multiple of 0.5
- if scale > 1 and mon.setTextScale ~= nil then
- mon.setTextScale(scale)
- width, height = mon.getSize()
- end
- end
- --
- -- Output the data
- --
- mon.setCursorPos(1,1)
- mon.write("Reactor")
- mon.setCursorPos(1,3)
- mon.write("Status ")
- if state then
- writeColor(mon, colors.green, "ON")
- else
- writeColor(mon, colors.red, "OFF")
- end
- mon.setCursorPos(1,4)
- mon.write("Rod Level: " .. rodLvl .. "%")
- mon.setCursorPos(1,5)
- if width < 16 then
- mon.write("Cell: ") -- One block monitor (15x5 with scale 0.5)
- else
- mon.write("Energy: ")
- end
- local c
- if cellEnergy < critEnergy then
- c = colors.red -- Red: We use too much energy
- elseif cellEnergy > lowEnergy then
- c = colors.green -- Green: More energy then low water mark
- else
- c = colors.orange -- Orange: Less energy the low water mark, but OK
- end
- writeColor(mon, c, string.format("%d", math.floor(cellEnergy/1000 + 0.5)))
- mon.write(" kRF")
- end
- --
- -- Display reactor status to any connected monitor and also to console.
- --
- -- Parameters:
- -- state - state of reactor (on/off)
- -- rodLvl - Level of control rods in %
- -- cellEnergy - stored energy of internal energy cell in RF
- --
- function displayStatus(state, rodLvl, cellEnergy)
- displayStatusToMonitor(term, state, rodLvl, cellEnergy) -- console
- term.setCursorPos(1,17)
- writeColor(term, colors.lightGray, "* Hold Crtl-T to terminate program")
- term.setCursorPos(1,8)
- local i, name
- for i, name in pairs(pList) do
- if peripheral.getType(name) == "monitor" then
- -- found monitor as peripheral
- displayStatusToMonitor(peripheral.wrap(name), state, rodLvl, cellEnergy)
- end
- end
- end
- --
- -- Find the first connected big reactor and return the wraped handle.
- --
- -- If no reactor was found this function terminate the program.
- --
- -- Return:
- -- Handle of first connected reactor found.
- --
- function getReactorHandle()
- local i, name
- for i, name in pairs(pList) do
- if peripheral.getType(name) == "BigReactors-Reactor" then
- return peripheral.wrap(name)
- end
- end
- error("No big reactor connected: Exit program")
- exit()
- end
- function main()
- reactor = getReactorHandle()
- --
- -- Endless loop: Recalculate rod level, set rod level, display result
- -- and wait for 5 secounds.
- --
- while true do
- cellEnergy = reactor.getEnergyStored()
- if cellEnergy < lowEnergy then
- -- Low energy: switch reactor ON and calculate control rods by
- -- energy cell level.
- reactor.setActive(true)
- rodLvl=calcRodLevel(cellEnergy)
- elseif cellEnergy > highEnergy then
- -- High energy: switch reactor OFF and set control rod level to 100
- reactor.setActive(false)
- rodLvl=100
- elseif cellEnergy > lowEnergy then
- -- Enough energy: do not change state of reactor. Only recalculate
- -- control rod level.
- --
- -- * If the reactor ist switched off, we will wait until energy
- -- fall below low energy mark.
- --
- -- * If it is turned on, we generate more energy until the
- -- energy level exeeds the high energy mark.
- rodLvl=calcRodLevel(cellEnergy)
- end
- reactor.setAllControlRodLevels(rodLvl)
- displayStatus(reactor.getActive(), rodLvl, cellEnergy)
- os.sleep(delay) -- Wait for 5s
- end
- end
- function tickToMonitor(mon,frame)
- local len = string.len(delay.."/"..delay)
- local cx,cy = mon.getCursorPos()
- mon.setCursorPos(16-len,1)
- mon.write(string.rep(" ",len))
- mon.setCursorPos(16-string.len(frame.."/"..delay),1)
- writeColor(mon, colors.lightGray, frame.."/"..delay)
- mon.setCursorPos(cx,cy)
- end
- function tick()
- local t=0
- while true do
- local f=t%delay+1
- tickToMonitor(term,f)
- local i, name
- for i, name in pairs(pList) do
- if peripheral.getType(name) == "monitor" then
- -- found monitor as peripheral
- tickToMonitor(peripheral.wrap(name),f)
- end
- end
- sleep(1)
- t=t+1
- end
- end
- function shortcutToMonitor(mon)
- local cx,cy = mon.getCursorPos()
- mon.setCursorPos(13,2)
- writeColor(mon, colors.black, "T", colors.orange)
- writeColor(mon, colors.black, "R", colors.blue)
- writeColor(mon, colors.black, "S", colors.red)
- resetColor(mon)
- mon.setCursorPos(cx,cy)
- end
- function shortcut()
- while true do
- shortcutToMonitor(term)
- local i, name
- for i, name in pairs(pList) do
- if peripheral.getType(name) == "monitor" then
- -- found monitor as peripheral
- shortcutToMonitor(peripheral.wrap(name))
- end
- end
- event, side, xPos, yPos = os.pullEvent()
- if ((event == "mouse_click" and side == 1) or event == "monitor_touch")
- and yPos == 2 then
- if xPos == 13 then --T
- return
- elseif xPos == 14 then --R
- os.reboot()
- elseif xPos == 15 then --S
- os.shutdown()
- end
- end
- sleep(.2)
- end
- end
- term.clear()
- for i, name in pairs(pList) do
- if peripheral.getType(name) == "monitor" then
- -- found monitor as peripheral
- mon = peripheral.wrap(name)
- mon.clear()
- end
- end
- r = parallel.waitForAny(shortcut, tick, main)
- if r == 1 then
- writeColor(term, colors.red, "Terminated", colors.black)
- local i, name
- for i, name in pairs(pList) do
- if peripheral.getType(name) == "monitor" then
- -- found monitor as peripheral
- mon = peripheral.wrap(name)
- mon.setCursorPos(1,6)
- writeColor(mon, colors.red, "Terminated", colors.black)
- end
- end
- print("")
- end
- --
- -- EOF
- --
Advertisement
Add Comment
Please, Sign In to add comment