Skip to content

Instantly share code, notes, and snippets.

@Decstasy
Last active May 6, 2021 19:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Decstasy/5e1ad1c3df6ed7b5fd9502369c0c443f to your computer and use it in GitHub Desktop.
Save Decstasy/5e1ad1c3df6ed7b5fd9502369c0c443f to your computer and use it in GitHub Desktop.
A small Computercraft reactor control program
-- Little reactor control by Decstasy request@decstasy.de
-- Please configure everything for your needs
-- Where the energy store is located relative to the computer
local BatterySide = "back"
-- Where to send the "enable the reactor" redstone signal
local reactorEnableRedstone = "front"
-- Where to abort program when getting a redstone signal
local reactorEmergencyRedstone = "right"
-- Monitor position
local MonitorPosition = "top"
-- Turn reactor on when battery is x% discharged
local reactorThresholdOn = 20
-- Turn reactor off then battery is x% charged
local reactorThresholdOff = 90
--[[
!!!
Please don't edit something upon this point unless you know what you're doing
!!!
--]]
--[[
Vars
--]]
local state = "init"
-- Interval in seconds to check energy levels etc
local checkInterval = 1
local lastPercentile = 200
--[[
Functions
--]]
function queryEnergy(obj)
energy = obj.getEnergy()
-- 2147483647 ~ 2.14 GFE is the maximum readout
cap = obj.getEnergyCapacity()
end
function queryPercentile(obj)
queryEnergy(obj)
percentile = math.ceil(( energy / cap ) * 100)
return percentile
end
function ts()
return os.date('%H:%M:%S')
end
function pr(text)
print(ts() .. " " .. text)
end
-- Newline
function MonitorNL(mon)
local cX,cY = mon.getCursorPos()
mon.setCursorPos(1,cY+1)
end
-- https://www.computercraft.info/wiki/Colors_(API)#Colors
function blitWrapper(mon, text, fg, bg)
local fg = string.rep(fg, string.len(text))
local bg = string.rep(bg, string.len(text))
mon.blit(text, bg, fg)
MonitorNL(mon)
end
function MonitorReactorStatus(mon)
if state == "full" then
blitWrapper(mon, "Reactor off", "7", "8")
else
blitWrapper(mon, "Reactor on", "7", "d")
end
end
function MonitorChargeStatus(mon, charge)
local chargeText = "Charge: " .. charge .. "%"
if charge <= reactorThresholdOn then
blitWrapper(mon, chargeText, "7", "e" )
elseif charge >= reactorThresholdOff then
blitWrapper(mon, chargeText, "7", "d" )
else
blitWrapper(mon, chargeText, "7", "4" )
end
end
function showStatus(mon, charge)
mon.clear()
mon.setCursorPos(1,1)
MonitorReactorStatus(mon)
MonitorChargeStatus(mon, charge)
end
function showEmergency(mon)
mon.clear()
mon.setCursorPos(1,1)
blitWrapper(mon, "EMERGENCY", "f", "e" )
blitWrapper(mon, "SHUTDOWN", "f", "e" )
blitWrapper(mon, "EMERGENCY", "f", "e" )
blitWrapper(mon, "SHUTDOWN", "f", "e" )
end
--[[
Main Program
--]]
-- Wrap energy storage to object
Battery = peripheral.wrap(BatterySide)
-- Wrap Monitor if present
if peripheral.isPresent(MonitorPosition) then
if peripheral.getType(MonitorPosition) == "monitor" then
Monitor = peripheral.wrap(MonitorPosition)
end
end
-- Startup message
print("Enable/Disable threshold: " .. reactorThresholdOn .. "% / " .. reactorThresholdOff .. "%")
pr("Program started!")
while true do
-- Check for emergency signal
if rs.getInput(reactorEmergencyRedstone) then
-- Disable reactor
rs.setOutput(reactorEnableRedstone, false)
-- Inform user
pr("EMERGENCY INPUT TRIGGERED!")
if Monitor then
showEmergency(Monitor)
end
-- Terminate program
break
end
-- Turn off reactor when energy level is sufficient
if queryPercentile(Battery) >= reactorThresholdOff then
if not (state == "full") then
pr("Reactor turned off")
state = "full"
end
rs.setOutput(reactorEnableRedstone, false)
-- Turn on reactor when energy level is below threshold
elseif queryPercentile(Battery) <= reactorThresholdOn then
if not (state == "empty") then
pr("Reactor turned on")
state = "empty"
end
rs.setOutput(reactorEnableRedstone, true)
-- Condition between threshold
else
-- Make sure redstone signal is off while discharging
if state == "full" then
rs.setOutput(reactorEnableRedstone, false)
end
end
-- Print actual readings if +- 1% change
if not (lastPercentile == percentile) then
lastPercentile = percentile
pr("Energy: " .. percentile .. "% " .. ( math.floor(energy / 1000^2) ) .. "MFE / " .. ( math.floor(cap / 1000^2) ) .. "MFE")
if Monitor then
showStatus(Monitor, percentile)
end
end
-- Interval
sleep(checkInterval)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment