Skip to content

Commit 77a8a0f

Browse files
initial commit
0 parents  commit 77a8a0f

10 files changed

+2212
-0
lines changed

LICENSE

Lines changed: 502 additions & 0 deletions
Large diffs are not rendered by default.

bin/nuke_manager.lua

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
2+
local filesystem = require("filesystem")
3+
local serialization = require("serialization")
4+
local component = require("component")
5+
local thread = require("thread")
6+
local event = require("event")
7+
local os = require("os")
8+
local term = require("term")
9+
10+
local parser = require("nuke_manager.parser")
11+
local utils = require("nuke_manager.utils")
12+
local items = require("nuke_manager.items")
13+
local reactor_manager = require("nuke_manager.reactor_manager")
14+
local logging = require("nuke_manager.logging")
15+
16+
local nuke_manager = {
17+
logger = nil,
18+
settings = {},
19+
reactor_config = {},
20+
threads = {}
21+
}
22+
23+
local function load_config()
24+
if not filesystem.exists("/etc/nuke-manager") then
25+
filesystem.makeDirectory("/etc/nuke-manager")
26+
end
27+
28+
if not component.isAvailable("database") then
29+
print("error: an unrecoverable error has occurred:")
30+
print("error: a database upgrade is required for this program to work.")
31+
print("error: install one into an adapter and ensure the adapter is connected to the computer network.")
32+
error("a database upgrade is required")
33+
end
34+
35+
nuke_manager.settings = utils.load("/etc/nuke-manager/settings.cfg") or {}
36+
37+
if nuke_manager.settings.code == nil or nuke_manager.settings.code == "" then
38+
error("reactor planner code is not set: please run config.lua and set it")
39+
end
40+
41+
local reactors = utils.load("/etc/nuke-manager/reactors.cfg")
42+
43+
if reactors == nil then
44+
error("/etc/nuke-manager/reactors.cfg has not been initialized: please run config.lua")
45+
end
46+
47+
nuke_manager.settings.database = nuke_manager.settings.database or component.database.address
48+
nuke_manager.settings.reactors = reactors
49+
50+
nuke_manager.reactor_config = parser.load_config(nuke_manager.settings.code)
51+
52+
nuke_manager.logger = logging({
53+
app_name = "nuke_manager",
54+
debug = nuke_manager.settings.debug_logs,
55+
max_level = nuke_manager.settings.max_log_level,
56+
})
57+
58+
for _, reactor in pairs(nuke_manager.settings.reactors) do
59+
local config_error = reactor_manager.validate_config(nuke_manager.reactor_config, reactor)
60+
61+
if config_error ~= nil then
62+
error(config_error)
63+
end
64+
end
65+
66+
end
67+
68+
local function start()
69+
load_config()
70+
71+
local next_slot = 1
72+
73+
for _, reactor in pairs(nuke_manager.settings.reactors) do
74+
local t = reactor_manager.start(nuke_manager.settings, nuke_manager.reactor_config, reactor, next_slot, nuke_manager.logger)
75+
76+
t:detach()
77+
78+
nuke_manager.threads[#nuke_manager.threads + 1] = {
79+
t = t,
80+
reactor = reactor
81+
}
82+
83+
next_slot = next_slot + 1
84+
end
85+
end
86+
87+
local function stop()
88+
for _, t in pairs(nuke_manager.threads) do
89+
nuke_manager.logger.info("Stopping reactor " .. t.reactor.reactor_address)
90+
event.push("reactor_stop", t.reactor.reactor_address)
91+
end
92+
93+
for _, t in pairs(nuke_manager.threads) do
94+
nuke_manager.logger.info("Waiting for worker thread to stop for reactor " .. t.reactor.reactor_address)
95+
t.t:join()
96+
end
97+
98+
threads = {}
99+
end
100+
101+
local function run()
102+
term.clear()
103+
104+
print("Starting nuke_manager in 5 seconds, press Ctrl+C to cancel")
105+
106+
if event.pull(5, "interrupted") then
107+
nuke_manager.logger.info("Exiting.")
108+
return
109+
end
110+
111+
local state = { running = true }
112+
113+
local function interrupt()
114+
nuke_manager.logger.info("Interrupted")
115+
state.running = false
116+
end
117+
118+
event.listen("interrupted", interrupt)
119+
120+
if not state.running then
121+
return
122+
end
123+
124+
start()
125+
126+
while state.running do
127+
if nuke_manager.settings.coolant_interface then
128+
local iface
129+
130+
if nuke_manager.settings.coolant_interface == "any" then
131+
if component.isAvailable("me_interface") then
132+
iface = component.me_interface
133+
end
134+
else
135+
iface = component.proxy(nuke_manager.settings.coolant_interface)
136+
end
137+
138+
if iface == nil then
139+
nuke_manager.logger.warn("Could not find me_interface to check coolant levels")
140+
event.push("reactor_pause")
141+
goto continue
142+
end
143+
144+
local hot_coolant = 0
145+
local coolant = 0
146+
147+
for _, fluid in pairs(iface.getFluidsInNetwork()) do
148+
if fluid.name == "ic2hotcoolant" then
149+
hot_coolant = fluid.amount
150+
elseif fluid.name == "ic2coolant" then
151+
coolant = fluid.amount
152+
end
153+
end
154+
155+
local needs_hot_coolant = nuke_manager.settings.hot_coolant_max == nil or hot_coolant < nuke_manager.settings.hot_coolant_max
156+
local has_coolant = coolant > (nuke_manager.settings.cool_coolant_min or 0)
157+
158+
if not has_coolant then
159+
nuke_manager.logger.warn("Not enough coolant: needs " .. utils.format_int(nuke_manager.settings.cool_coolant_min or 0) .. " but has " .. utils.format_int(coolant))
160+
end
161+
162+
if has_coolant and needs_hot_coolant then
163+
event.push("reactor_continue")
164+
else
165+
event.push("reactor_pause")
166+
end
167+
end
168+
169+
::continue::
170+
171+
os.sleep(5)
172+
end
173+
174+
event.ignore("interrupted", interrupt)
175+
176+
stop()
177+
end
178+
179+
function catch(fn, logger)
180+
local success, ret = pcall(fn)
181+
182+
if not success then
183+
logger.error(tostring(ret))
184+
else
185+
return ret
186+
end
187+
end
188+
189+
-- thread.create(function() catch(run, nuke_manager.logger) end):join()
190+
run()

0 commit comments

Comments
 (0)