Skip to content

Instantly share code, notes, and snippets.

@huwcbjones
Last active May 9, 2021 07:54
Show Gist options
  • Save huwcbjones/3d58f62c3811b1f087ac6412c5598a5c to your computer and use it in GitHub Desktop.
Save huwcbjones/3d58f62c3811b1f087ac6412c5598a5c to your computer and use it in GitHub Desktop.
Nuclearcraft OpenComputers Fusion Reactor Control Script
-- On/Off Switch Input
in_enable = {address = "", side = 4}
-- Preheat Output
out_preheat = {address = "", side = 3}
-- ELectromagnet Energy Cube
elec_energy_cube = {address = ""}
-- Electromagnets Output
out_elecmagnets = {address = "", side = 0}
-- Fusion Reactor Core Output
out_core = {address = "", side = 0}
-- Fusion Reactor Status Output
out_status = {address = "", side = 0}
-- Fusion Reactor Block
nc_reactor = {address = ""}
-- Screen Address
screen = {address = "", tag=""}
component = require("component")
inet = require("internet")
fs = require("filesystem")
term = require("term")
config_dir = "/etc/nc-fusion/"
config_file = "fusion.cfg"
in_enable = nil
out_preheat = nil
out_elecmagnets = nil
out_core = nil
out_status = nil
elec_energy_cube = nil
nc_reactor = nil
local proxied_components = {"in_enable", "out_preheat", "out_elecmagnets", "out_core", "out_status", "elec_energy_cube","nc_reactor"}
config_path = config_dir .. config_file
function defined(var)
for k, _ in pairs(_G) do
if k == var then
return true
end
end
end
function http_get(uri)
local request = inet.request(uri)
if not request.finishConnect() then
return nil
end
local response_code, _, headers = request.response()
response_code = math.floor(response_code)
if headers["Content-Length"] == nil then
return nil
end
local content_length = tonumber(headers["Content-Length"][1])
body = request.read(content_length)
return {response_code = response_code, headers = headers, body = body}
end
function loadConfig()
-- Check if config file exists, if not, download it
if not fs.exists(config_path) then
if fetchDefaultConfig() then
print("The default config file has been downloaded to: " .. config_path)
print("Please edit it for your configuration")
else
print("Failed to download default config file!")
end
return false
end
-- Load config file
config = {}
local f, err = loadfile(config_path, "t", config)
if not f then
print("There was an error loading the config file.")
print("Please check the config syntax.")
print("\nError details:")
print(err)
return false
end
-- Load config from loaded config file
print("Loading config file '" .. config_file .. "'")
f()
for k, v in pairs(config) do
_G[k] = v
end
-- Proxy components
for _, var_name in pairs(proxied_components) do
local periph = config[var_name]
local comp = component.proxy(periph.address)
assert(comp, "Could not connect to " .. var_name .. " at address '" .. periph.address .. "'\n Check config file!")
periph.component = comp
_G[var_name] = periph
end
print("Configuration successfully loaded!")
end
function saveURI(uri, path)
local request = http_get(uri)
if request == nil or request.response_code ~= 200 then
return false
end
local output_file = io.open(path, "w")
output_file:write(request.body)
output_file:close()
return true
end
function fetchDefaultConfig()
if not fs.exists(config_dir) then
fs.makeDirectory(config_dir)
end
return saveURI("https://gist.githubusercontent.com/huwcbjones/3d58f62c3811b1f087ac6412c5598a5c/raw/fusion.cfg", config_path)
end
function setOutputState(component, state)
if not component or not component.component then
return
end
local value = 0
if state then
value = 16
end
component.component.setOutput(component.side, value)
end
function getOutputState(component)
if not component or not component.component then
return
end
local value = component.component.getOutput(component.side)
return value > 8
end
function getInputState(component, raw_value)
if raw_value == nil then
raw_value = false
end
if not component or not component.component then
return
end
local value = component.component.getInput(component.side)
if raw_value then
return value
end
return value > 0
end
function reset()
setOutputState(out_status, false)
setOutputState(out_preheat, false)
setOutputState(out_core, false)
setOutputState(out_elecmagnets, false)
local reactorTemperature = getReactorTemperature()
if reactorTemperature>= 5 then
setStatus("Cooling " .. string.format("%.0fK", reactorTemperature))
else
setStatus("Off")
end
end
function shouldPowerUp()
return getInputState(in_enable)
end
function electromagnetsPowered()
local isPowered = getOutputState(out_elecmagnets, true)
local problem = nc_reactor.component.getProblem()
return problem ~= "E-magnets not Powered" and isPowered
end
function isReactorRunning()
return nc_reactor.component.isProcessing()
end
function getReactorTemperature()
return nc_reactor.component.getTemperature()
end
function getReactorPower()
return nc_reactor.component.getReactorProcessPower()
end
function isCoreHotEnough()
return getReactorTemperature() >= 8000
end
function setStatus(str)
component.screen_controller.setText("nc_rf_out", str, 0xffffff)
end
function reactorHasFuel()
local fuel_a = nc_reactor.component.getFirstFusionFuel()
local fuel_b = nc_reactor.component.getSecondFusionFuel()
return fuel_a ~= "Empty" and fuel_b ~= "Empty"
end
function getEmagnetPower()
return elec_energy_cube.component.getEnergyStored()
end
function getEmagnetPowerPercent()
local storedPower = getEmagnetPower()
local maxPower = elec_energy_cube.component.getMaxEnergyStored()
return 100 * storedPower/maxPower
end
function powerOnElectromagnets()
setOutputState(out_elecmagnets, true)
local c = 0
while not electromagnetsPowered() do
os.sleep(1)
if not shouldPowerUp() then
return false
end
if getEmagnetPowerPercent() <= 25 then
print("Not enough power to run electromagnets!")
return false
end
local time = string.format("% 2d", c)
term.write("\rWaiting for electromagnets to power up... " .. time)
setStatus("Powering e-magnets " .. time)
c = c + 1
end
term.clearLine()
return true
end
function preheatCore()
setOutputState(out_preheat, true)
local c = 0
while not isCoreHotEnough() do
os.sleep(1)
if not shouldPowerUp() then
return false
end
local core_heat = string.format("% 5.0fK/% 4dK", getReactorTemperature(), 8000)
term.write("\rWaiting for core to heat up... [" .. core_heat .. "]")
setStatus("Preheating " .. core_heat)
c = c + 1
end
term.clearLine()
return true
end
function powerOnReactor()
if not shouldPowerUp() then
return
end
if not reactorHasFuel() then
print("Reactor does not have any fuel!")
print("Please add fuel before continuing")
return false
end
print("Powering up reactor...")
setStatus("Powering up...")
if not electromagnetsPowered() then
print("Turning on electromagnets...")
if not powerOnElectromagnets() then
print("Aborting power up!")
return false
end
end
print("Electromagnets powered up!")
if not isCoreHotEnough() then
print("Preheating core...")
if not preheatCore() then
print("Aborting power up!")
return false
end
end
print("Core preheated!")
print("Turning on reactor...")
setOutputState(out_core, true)
setOutputState(out_preheat, false)
print("Reactor powered up!")
return isReactorRunning()
end
function main_loop()
while true do
os.sleep(0.5)
if not shouldPowerUp() then
reset()
elseif not isReactorRunning() then
if not reactorHasFuel() then
reset()
setStatus("NO FUEL")
elseif getEmagnetPowerPercent() <= 40 then
reset()
setStatus("E-MAGNET POWER")
elseif not powerOnReactor() then
reset()
setStatus("Error powering up")
end
os.sleep(1)
else
if getEmagnetPowerPercent() <= 25 then
reset()
setStatus("E-MAGNET POWER")
end
setStatus("Power " .. string.format("%.0f/t", getReactorPower()))
if not getOutputState(out_status) then
setOutputState(out_status, true)
end
end
end
end
loadConfig()
reset()
main_loop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment