Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- I found this program for controlling a reactor, however it was outdated. I fixed it and this version does currently work in the latest version of Tekkit. I did not write the original, my coding skills are pretty basic. Other than my fix, everything below remains the same as the original.
- Big Reactors controller script
- Uses wired modems to connect to computer control port on reactor
- Prefers monitor connection (also via wired modem) for local display and potentially control
- Uses wireless modem channel to send status and accept control commands from central system
- If present, wireless modem must be on top of the computer
- Note: Do not connect more than one reactor to the same controlling computer
- ]]--
- -- Global settings
- -- This reactor ID
- reactorID = 2
- -- Wireless channels
- wcStatus = 100
- wcCtl = 110
- -- Minimum control rod setting - This is to prevent longer 'hunt' times to optimize temperature
- -- Note: This setting will be adjusted automatically as the reactor runs, but is not saved through restarts
- crmin = 0
- -- Start pushing in control rods when temperature climbs above this temp
- tempmax = 995
- tempmin = 940
- -- Start pushing in control rods when stored energy climbs above this percent
- -- Control rods will scale from crmin to 100%, starting from this %
- storpct = 30
- -- There should be no need to edit code below this line
- -- Utility function - return a wrapped variable for a specific peripheral
- function wrapThis(thing)
- local wrapped, i = nil, 0
- while wrapped == nil and i <= 100 do
- wrapped = peripheral.wrap(thing.."_"..i)
- i = i + 1
- end
- if wrapped == nil then
- return nil
- else
- return wrapped
- end
- end
- -- Collect statistics for Local display and remote send
- function getStats()
- local curTemp = r.getFuelTemperature()
- local curFuel = r.getFuelAmount()
- local maxFuel = r.getFuelAmountMax()
- local curRF = r.getEnergyStored()
- local ctlRod = r.getControlRodLevel(0)
- local curFuelPct = curFuel/maxFuel*100
- local curRFPct = curRF/100000
- local curRFGen = r.getEnergyProducedLastTick()
- local active = r.getActive()
- -- Round values
- curRFPct = math.floor((curRFPct*10))/10
- curFuelPct = math.floor((curFuelPct*10))/10
- curRFGen = math.floor(curRFGen)
- return curTemp, curFuelPct, curRFPct, curRFGen, ctlRod, active
- end
- -- Local status display
- function displayStatus()
- if mon == nil then
- return
- end
- local curTemp, curFuelPct, curRFPct, curRFGen, ctlRod, active = getStats()
- mon.clear()
- mon.setCursorPos(1,1)
- mon.write("Temp: "..curTemp)
- mon.setCursorPos(1,2)
- mon.write("Fuel: "..curFuelPct.."%")
- mon.setCursorPos(1,3)
- mon.write("Energy: "..curRFPct.."%")
- mon.setCursorPos(1,4)
- mon.write("RF Gen: "..curRFGen)
- mon.setCursorPos(1,5)
- mon.write("Control Rod: "..ctlRod.."%")
- mon.setCursorPos(1,6)
- mon.write("Min Control Rod: "..crmin.."%")
- mon.setCursorPos(1,7)
- if active then
- mon.write("Active")
- else
- mon.write("Shutdown")
- end
- end
- -- Transmit current system stats on wireless channel
- function txStatus()
- if modem == nil then
- return
- end
- local curTemp, curFuelPct, curRFPct, curRFGen, ctlRod, active = getStats()
- local updateStr = "R:"..reactorID.." T:"..curTemp.." F:"..curFuelPct.." E:"..curRFPct.." G:"..curRFGen.." C:"..ctlRod.." S:"..crmin
- if active then
- updateStr = updateStr.." A:true"
- else
- updateStr = updateStr.." A:false"
- end
- modem.transmit(wcStatus, wcCtl, updateStr)
- end
- function main()
- print("Initializing reactor control...")
- print("Max Temp: "..tempmax)
- print("Control rod minimum: "..crmin.."%")
- print("Target Energy level: "..storpct.."%")
- -- Initialize connections to peripherals
- if initConnections() == false then
- return false
- end
- -- Start the reactor
- startup()
- -- Start our monitoring and control loop
- running = true
- local loopCount = 1
- os.startTimer(1)
- while running do
- local e, p1, p2, p3, p4, p5 = os.pullEvent()
- if e == "key" then
- if p1 == 16 then -- 'q' key
- running = false
- elseif p1 == 13 then -- '=/+' key
- crmin = crmin + 10
- elseif p1 == 12 then -- '-' key
- crmin = crmin - 10
- elseif p1 == 18 then -- 'e'
- r.setActive(false)
- elseif p1 == 19 then -- 'r'
- r.setActive(true)
- end
- elseif e == "modem_message" and p2 == wcCtl then
- local rid, cmd = string.gmatch(p4, "%S+")
- if rid == reactorID then
- if cmd == 'stop' then
- r.setActive(false)
- elseif cmd == 'start' then
- r.setActive(true)
- elseif cmd == 'crminup' then
- crmin = crmin + 10
- elseif cmd == 'crmindown' then
- crmin = crmin - 10
- end
- end
- elseif e == "timer" then
- os.startTimer(1)
- end
- -- Constrain the control rod settings
- if crmin < 0 then
- crmin = 0
- elseif crmin > 100 then
- crmin = 100
- end
- -- Run reactor controls every 10 cycles - this allows for some time for things to stabilize after each adjustment
- if loopCount > 10 then
- manageReactor()
- loopCount = 1
- end
- -- Update the displays after every loop
- displayStatus()
- txStatus()
- loopCount = loopCount + 1
- end
- cleanup()
- return true
- end
- -- Initialize connections to peripherals. Only return false if we can't talk to the reactor
- function initConnections()
- -- Connect to reactor
- r = wrapThis("BigReactors-Reactor")
- if r == nil then
- print("No reactor found")
- return false
- end
- -- Check to see if we have a valid reactor
- if r.getConnected() == false then
- print("Reactor not connected")
- return false
- end
- -- Connect monitor
- mon = wrapThis("monitor")
- if mon == nil then
- print("No monitor found, full status display disabled")
- else
- -- Start things off with current status
- displayStatus()
- end
- -- Connect wireless network - wireless modem needs to be on top
- modem = peripheral.wrap("top")
- if modem == nil then
- print("No wireless modem found. No remote status/control enabled")
- else
- txStatus()
- -- Open control channel
- modem.open(wcCtl)
- end
- return true
- end
- -- Configure initial control rod settings and activate reactor
- function startup()
- -- Verify initial control rod state and activate reactor (if needed)
- local curTemp, curFuelPct, curRFPct, curRFGen, ctlRod, active = getStats()
- if ctlRod < crmin then
- r.setAllControlRodLevels(crmin)
- end
- if active == false then
- r.setActive(true)
- end
- end
- -- Cleanup reactor before exiting
- -- Note: This will shutdown the reactor to avoid having the reactor run without supervision
- function cleanup()
- r.setActive(false)
- end
- -- Adjust reactor status based on temperature, energy level and control rod settings
- function manageReactor()
- local cRT = r.getControlRodLevel(0)
- -- First, if the control rods are lower than our minimum setting, just bump it up
- if cRT < crmin then
- r.setAllControlRodLevels(crmin)
- end
- local curTemp, curFuelPct, curRFPct, curRFGen, ctlRod, active = getStats()
- ctlSet = ctlRod
- ctTargR = 0
- -- If the reactor stored energy is above the target, start pushing the control rods in - scale from crmin to 100
- -- Better to run the reactor at 50% stable than turn it full on/off to maintain energy reserve?
- -- Scale insertion speed based on how far above the target we are? - similar to temp adjustments
- -- Figure out the target control rod setting based on energy storage
- if curRFPct > storpct then
- ctScale = 100 - crmin
- esScale = 100 - storpct
- esLvl = curRFPct - storpct
- esMult = esLvl / esScale
- ctTargR = ctScale * esMult + crmin
- ctTargR = math.floor(ctTargR)
- end
- -- Look for control rod insertion, adjust and return if matched
- -- If the reactor temp is too high, start pushing the control rods in - continue if matched
- if curTemp > tempmax then
- local dT = curTemp - tempmax
- if dT > 100 then
- dR = 15
- elseif dT > 30 then
- dR = 10
- elseif dT > 20 then
- dR = 5
- elseif dT > 10 then
- dR = 2
- elseif dT > 5 then
- dR = 1
- end
- ctlSet = ctlRod + dR
- end
- -- Apply energy load adjustment
- if ctTargR > ctlSet then
- ctlSet = ctTargR
- end
- -- If we are pushing the control rods in, then we need to do that here and then return - Note - a hot and charged reactor will scale control rods very quickly
- if ctlSet > 100 then
- ctlSet = 100
- end
- if ctlSet > ctlRod then
- r.setAllControlRodLevels(ctlSet)
- return
- end
- -- If the reactor temp is too low, retract control rods
- if curTemp < tempmin then
- local dT = tempmin - curTemp
- if dT > 100 then
- dR = 15
- elseif dT > 70 then
- dR = 10
- elseif dT > 40 then
- dR = 5
- elseif dT > 20 then
- dR = 2
- elseif dT > 10 then
- dR = 1
- end
- ctlSet = ctlSet - dR
- end
- -- Apply energy load adjustment
- if ctTargR > ctlSet then
- ctlSet = ctTargR
- end
- -- Retract control rods
- if ctlSet < crmin then
- ctlSet = crmin
- end
- if ctlSet <= ctlRod then
- r.setAllControlRodLevels(ctlSet)
- end
- end
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement