mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
Merge branch 'devel' into color-update
This commit is contained in:
commit
c714e49ad8
@ -95,9 +95,9 @@ function coordinator.load_config()
|
||||
|
||||
---@class monitors_struct
|
||||
local monitors = {
|
||||
primary = nil, ---@type table|nil
|
||||
primary_name = "",
|
||||
flow = nil, ---@type table|nil
|
||||
main = nil, ---@type table|nil
|
||||
main_name = "",
|
||||
flow = nil, ---@type table|nil
|
||||
flow_name = "",
|
||||
unit_displays = {},
|
||||
unit_name_map = {}
|
||||
@ -121,11 +121,11 @@ function coordinator.load_config()
|
||||
return 2, "Main monitor is not connected."
|
||||
end
|
||||
|
||||
monitors.primary = ppm.get_periph(config.MainDisplay)
|
||||
monitors.primary_name = config.MainDisplay
|
||||
monitors.main = ppm.get_periph(config.MainDisplay)
|
||||
monitors.main_name = config.MainDisplay
|
||||
|
||||
monitors.primary.setTextScale(0.5)
|
||||
w, _ = ppm.monitor_block_size(monitors.primary.getSize())
|
||||
monitors.main.setTextScale(0.5)
|
||||
w, _ = ppm.monitor_block_size(monitors.main.getSize())
|
||||
if w ~= 8 then
|
||||
return 2, util.c("Main monitor width is incorrect (was ", w, ", must be 8).")
|
||||
end
|
||||
|
@ -235,7 +235,10 @@ function iocontrol.init(conf, comms, temp_scale)
|
||||
control_state = false,
|
||||
burn_rate_cmd = 0.0,
|
||||
radiation = types.new_zero_radiation_reading(),
|
||||
sna_prod_rate = 0.0,
|
||||
|
||||
sna_peak_rate = 0.0,
|
||||
sna_max_rate = 0.0,
|
||||
sna_out_rate = 0.0,
|
||||
|
||||
waste_mode = types.WASTE_MODE.MANUAL_PLUTONIUM,
|
||||
waste_product = types.WASTE_PRODUCT.PLUTONIUM,
|
||||
@ -1064,12 +1067,14 @@ function iocontrol.update_unit_statuses(statuses)
|
||||
-- solar neutron activator status info
|
||||
if type(rtu_statuses.sna) == "table" then
|
||||
unit.num_snas = rtu_statuses.sna[1] ---@type integer
|
||||
unit.sna_prod_rate = rtu_statuses.sna[2] ---@type number
|
||||
unit.sna_peak_rate = rtu_statuses.sna[3] ---@type number
|
||||
unit.sna_peak_rate = rtu_statuses.sna[2] ---@type number
|
||||
unit.sna_max_rate = rtu_statuses.sna[3] ---@type number
|
||||
unit.sna_out_rate = rtu_statuses.sna[4] ---@type number
|
||||
|
||||
unit.unit_ps.publish("sna_count", unit.num_snas)
|
||||
unit.unit_ps.publish("sna_prod_rate", unit.sna_prod_rate)
|
||||
unit.unit_ps.publish("sna_peak_rate", unit.sna_peak_rate)
|
||||
unit.unit_ps.publish("sna_max_rate", unit.sna_max_rate)
|
||||
unit.unit_ps.publish("sna_out_rate", unit.sna_out_rate)
|
||||
|
||||
sna_count_sum = sna_count_sum + unit.num_snas
|
||||
else
|
||||
@ -1217,7 +1222,7 @@ function iocontrol.update_unit_statuses(statuses)
|
||||
|
||||
local u_spent_rate = waste_rate
|
||||
local u_pu_rate = util.trinary(is_pu, waste_rate, 0.0)
|
||||
local u_po_rate = util.trinary(not is_pu, math.min(waste_rate, unit.sna_prod_rate), 0.0)
|
||||
local u_po_rate = unit.sna_out_rate
|
||||
|
||||
unit.unit_ps.publish("pu_rate", u_pu_rate)
|
||||
unit.unit_ps.publish("po_rate", u_po_rate)
|
||||
@ -1225,14 +1230,15 @@ function iocontrol.update_unit_statuses(statuses)
|
||||
unit.unit_ps.publish("sna_in", util.trinary(is_pu, 0, burn_rate))
|
||||
|
||||
if unit.waste_product == types.WASTE_PRODUCT.POLONIUM then
|
||||
u_spent_rate = u_po_rate
|
||||
unit.unit_ps.publish("po_pl_rate", u_po_rate)
|
||||
unit.unit_ps.publish("po_am_rate", 0)
|
||||
po_pl_rate = po_pl_rate + u_po_rate
|
||||
elseif unit.waste_product == types.WASTE_PRODUCT.ANTI_MATTER then
|
||||
u_spent_rate = 0
|
||||
unit.unit_ps.publish("po_pl_rate", 0)
|
||||
unit.unit_ps.publish("po_am_rate", u_po_rate)
|
||||
po_am_rate = po_am_rate + u_po_rate
|
||||
u_spent_rate = 0
|
||||
else
|
||||
unit.unit_ps.publish("po_pl_rate", 0)
|
||||
unit.unit_ps.publish("po_am_rate", 0)
|
||||
|
@ -52,6 +52,16 @@ local function _init_display(monitor)
|
||||
end
|
||||
end
|
||||
|
||||
-- print out that the monitor is too small
|
||||
---@param monitor table monitor
|
||||
local function _print_too_small(monitor)
|
||||
monitor.setCursorPos(1, 1)
|
||||
monitor.setBackgroundColor(colors.black)
|
||||
monitor.setTextColor(colors.red)
|
||||
monitor.clear()
|
||||
monitor.write("monitor too small")
|
||||
end
|
||||
|
||||
-- disable the flow view
|
||||
---@param disable boolean
|
||||
function renderer.legacy_disable_flow_view(disable)
|
||||
@ -64,15 +74,15 @@ function renderer.set_displays(monitors)
|
||||
engine.monitors = monitors
|
||||
|
||||
-- report to front panel as connected
|
||||
iocontrol.fp_monitor_state("main", engine.monitors.primary ~= nil)
|
||||
iocontrol.fp_monitor_state("main", engine.monitors.main ~= nil)
|
||||
iocontrol.fp_monitor_state("flow", engine.monitors.flow ~= nil)
|
||||
for i = 1, #engine.monitors.unit_displays do iocontrol.fp_monitor_state(i, true) end
|
||||
end
|
||||
|
||||
-- init all displays in use by the renderer
|
||||
function renderer.init_displays()
|
||||
-- init primary and flow monitors
|
||||
_init_display(engine.monitors.primary)
|
||||
-- init main and flow monitors
|
||||
_init_display(engine.monitors.main)
|
||||
if not engine.disable_flow_view then _init_display(engine.monitors.flow) end
|
||||
|
||||
-- init unit displays
|
||||
@ -94,8 +104,8 @@ end
|
||||
|
||||
-- initialize the dmesg output window
|
||||
function renderer.init_dmesg()
|
||||
local disp_w, disp_h = engine.monitors.primary.getSize()
|
||||
engine.dmesg_window = window.create(engine.monitors.primary, 1, 1, disp_w, disp_h)
|
||||
local disp_w, disp_h = engine.monitors.main.getSize()
|
||||
engine.dmesg_window = window.create(engine.monitors.main, 1, 1, disp_w, disp_h)
|
||||
log.direct_dmesg(engine.dmesg_window)
|
||||
end
|
||||
|
||||
@ -166,8 +176,8 @@ function renderer.try_start_ui()
|
||||
|
||||
status, msg = pcall(function ()
|
||||
-- show main view on main monitor
|
||||
if engine.monitors.primary ~= nil then
|
||||
engine.ui.main_display = DisplayBox{window=engine.monitors.primary,fg_bg=style.root}
|
||||
if engine.monitors.main ~= nil then
|
||||
engine.ui.main_display = DisplayBox{window=engine.monitors.main,fg_bg=style.root}
|
||||
main_view(engine.ui.main_display)
|
||||
end
|
||||
|
||||
@ -244,14 +254,14 @@ function renderer.handle_disconnect(device)
|
||||
|
||||
if not engine.monitors then return false end
|
||||
|
||||
if engine.monitors.primary == device then
|
||||
if engine.monitors.main == device then
|
||||
if engine.ui.main_display ~= nil then
|
||||
-- delete element tree and clear root UI elements
|
||||
engine.ui.main_display.delete()
|
||||
end
|
||||
|
||||
is_used = true
|
||||
engine.monitors.primary = nil
|
||||
engine.monitors.main = nil
|
||||
engine.ui.main_display = nil
|
||||
|
||||
iocontrol.fp_monitor_state("main", false)
|
||||
@ -298,9 +308,9 @@ function renderer.handle_reconnect(name, device)
|
||||
-- note: handle_resize is a more adaptive way of re-initializing a connected monitor
|
||||
-- since it can handle a monitor being reconnected that isn't the right size
|
||||
|
||||
if engine.monitors.primary_name == name then
|
||||
if engine.monitors.main_name == name then
|
||||
is_used = true
|
||||
engine.monitors.primary = device
|
||||
engine.monitors.main = device
|
||||
|
||||
renderer.handle_resize(name)
|
||||
elseif engine.monitors.flow_name == name then
|
||||
@ -334,8 +344,8 @@ function renderer.handle_resize(name)
|
||||
|
||||
if not engine.monitors then return false, false end
|
||||
|
||||
if engine.monitors.primary_name == name and engine.monitors.primary then
|
||||
local device = engine.monitors.primary ---@type table
|
||||
if engine.monitors.main_name == name and engine.monitors.main then
|
||||
local device = engine.monitors.main ---@type table
|
||||
|
||||
-- this is necessary if the bottom left block was broken and on reconnect
|
||||
_init_display(device)
|
||||
@ -343,9 +353,9 @@ function renderer.handle_resize(name)
|
||||
is_used = true
|
||||
|
||||
-- resize dmesg window if needed, but don't make it thinner
|
||||
local disp_w, disp_h = engine.monitors.primary.getSize()
|
||||
local disp_w, disp_h = engine.monitors.main.getSize()
|
||||
local dmsg_w, _ = engine.dmesg_window.getSize()
|
||||
engine.dmesg_window.reposition(1, 1, math.max(disp_w, dmsg_w), disp_h, engine.monitors.primary)
|
||||
engine.dmesg_window.reposition(1, 1, math.max(disp_w, dmsg_w), disp_h, engine.monitors.main)
|
||||
|
||||
if ui.main_display then
|
||||
ui.main_display.delete()
|
||||
@ -368,11 +378,7 @@ function renderer.handle_resize(name)
|
||||
ui.main_display = nil
|
||||
end
|
||||
|
||||
device.setCursorPos(1, 1)
|
||||
device.setBackgroundColor(colors.black)
|
||||
device.setTextColor(colors.red)
|
||||
device.clear()
|
||||
device.write("monitor too small")
|
||||
_print_too_small(device)
|
||||
|
||||
iocontrol.fp_monitor_state("main", false)
|
||||
is_ok = false
|
||||
@ -407,11 +413,7 @@ function renderer.handle_resize(name)
|
||||
ui.flow_display = nil
|
||||
end
|
||||
|
||||
device.setCursorPos(1, 1)
|
||||
device.setBackgroundColor(colors.black)
|
||||
device.setTextColor(colors.red)
|
||||
device.clear()
|
||||
device.write("monitor too small")
|
||||
_print_too_small(device)
|
||||
|
||||
iocontrol.fp_monitor_state("flow", false)
|
||||
is_ok = false
|
||||
@ -448,11 +450,7 @@ function renderer.handle_resize(name)
|
||||
ui.unit_displays[idx] = nil
|
||||
end
|
||||
|
||||
device.setCursorPos(1, 1)
|
||||
device.setBackgroundColor(colors.black)
|
||||
device.setTextColor(colors.red)
|
||||
device.clear()
|
||||
device.write("monitor too small")
|
||||
_print_too_small(device)
|
||||
|
||||
iocontrol.fp_monitor_state(idx, false)
|
||||
is_ok = false
|
||||
@ -474,7 +472,7 @@ function renderer.handle_mouse(event)
|
||||
if engine.fp_ready and event.monitor == "terminal" then
|
||||
engine.ui.front_panel.handle_mouse(event)
|
||||
elseif engine.ui_ready then
|
||||
if event.monitor == engine.monitors.primary_name then
|
||||
if event.monitor == engine.monitors.main_name then
|
||||
if engine.ui.main_display then engine.ui.main_display.handle_mouse(event) end
|
||||
elseif event.monitor == engine.monitors.flow_name then
|
||||
if engine.ui.flow_display then engine.ui.flow_display.handle_mouse(event) end
|
||||
|
@ -22,9 +22,9 @@ local sounder = require("coordinator.sounder")
|
||||
|
||||
local apisessions = require("coordinator.session.apisessions")
|
||||
|
||||
local COORDINATOR_VERSION = "v1.2.7"
|
||||
local COORDINATOR_VERSION = "v1.2.11"
|
||||
|
||||
local CHUNK_LOAD_DELAY_S = 20.0
|
||||
local CHUNK_LOAD_DELAY_S = 30.0
|
||||
|
||||
local println = util.println
|
||||
local println_ts = util.println_ts
|
||||
@ -42,24 +42,33 @@ local log_crypto = coordinator.log_crypto
|
||||
-- mount connected devices (required for monitor setup)
|
||||
ppm.mount_all()
|
||||
|
||||
local wait_on_load = true
|
||||
local loaded, monitors = coordinator.load_config()
|
||||
|
||||
-- if the computer just started, its chunk may have just loaded (...or the user rebooted)
|
||||
-- if monitor config failed, maybe an adjacent chunk containing all or part of a monitor has not loaded yet, so keep trying
|
||||
while loaded == 2 and os.clock() < CHUNK_LOAD_DELAY_S do
|
||||
while wait_on_load and loaded == 2 and os.clock() < CHUNK_LOAD_DELAY_S do
|
||||
term.clear()
|
||||
term.setCursorPos(1, 1)
|
||||
println("There was a monitor configuration problem at boot.\n")
|
||||
println("Startup will keep trying every 2s in case of chunk load delays.\n")
|
||||
println(util.sprintf("The configurator will be started in %ds if all attempts fail.\n", math.max(0, CHUNK_LOAD_DELAY_S - os.clock())))
|
||||
println("(exit early with ctrl-t)")
|
||||
println("(click to skip to the configurator)")
|
||||
|
||||
---@diagnostic disable-next-line: undefined-field
|
||||
os.sleep(2)
|
||||
local timer_id = util.start_timer(2)
|
||||
|
||||
-- remount and re-attempt
|
||||
ppm.mount_all()
|
||||
loaded, monitors = coordinator.load_config()
|
||||
while true do
|
||||
local event, param1 = util.pull_event()
|
||||
if event == "timer" and param1 == timer_id then
|
||||
-- remount and re-attempt
|
||||
ppm.mount_all()
|
||||
loaded, monitors = coordinator.load_config()
|
||||
break
|
||||
elseif event == "mouse_click" or event == "terminate" then
|
||||
wait_on_load = false
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if loaded ~= 0 then
|
||||
@ -67,9 +76,13 @@ if loaded ~= 0 then
|
||||
local success, error = configure.configure(loaded, monitors)
|
||||
if success then
|
||||
loaded, monitors = coordinator.load_config()
|
||||
assert(loaded == 0, util.trinary(loaded == 1, "failed to load valid configuration", "monitor configuration invalid"))
|
||||
if loaded ~= 0 then
|
||||
println(util.trinary(loaded == 2, "monitor configuration invalid", "failed to load a valid configuration") .. ", please reconfigure")
|
||||
return
|
||||
end
|
||||
else
|
||||
assert(success, "coordinator configuration error: " .. error)
|
||||
println("configuration error: " .. error)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -187,10 +187,10 @@ local function make(parent, x, y, wide, unit)
|
||||
|
||||
local waste_rate = DataIndicator{parent=waste,x=1,y=3,lu_colors=lu_c,label="",unit="mB/t",format="%7.2f",value=0,width=12,fg_bg=s_field}
|
||||
local pu_rate = DataIndicator{parent=waste,x=_wide(82,70),y=3,lu_colors=lu_c,label="",unit="mB/t",format="%7.3f",value=0,width=12,fg_bg=s_field}
|
||||
local po_rate = DataIndicator{parent=waste,x=_wide(52,45),y=6,lu_colors=lu_c,label="",unit="mB/t",format="%7.3f",value=0,width=12,fg_bg=s_field}
|
||||
local popl_rate = DataIndicator{parent=waste,x=_wide(82,70),y=6,lu_colors=lu_c,label="",unit="mB/t",format="%7.3f",value=0,width=12,fg_bg=s_field}
|
||||
local poam_rate = DataIndicator{parent=waste,x=_wide(82,70),y=10,lu_colors=lu_c,label="",unit="mB/t",format="%7.3f",value=0,width=12,fg_bg=s_field}
|
||||
local spent_rate = DataIndicator{parent=waste,x=_wide(117,99),y=3,lu_colors=lu_c,label="",unit="mB/t",format="%7.3f",value=0,width=12,fg_bg=s_field}
|
||||
local po_rate = DataIndicator{parent=waste,x=_wide(52,45),y=6,lu_colors=lu_c,label="",unit="mB/t",format="%7.2f",value=0,width=12,fg_bg=s_field}
|
||||
local popl_rate = DataIndicator{parent=waste,x=_wide(82,70),y=6,lu_colors=lu_c,label="",unit="mB/t",format="%7.2f",value=0,width=12,fg_bg=s_field}
|
||||
local poam_rate = DataIndicator{parent=waste,x=_wide(82,70),y=10,lu_colors=lu_c,label="",unit="mB/t",format="%7.2f",value=0,width=12,fg_bg=s_field}
|
||||
local spent_rate = DataIndicator{parent=waste,x=_wide(117,98),y=3,lu_colors=lu_c,label="",unit="mB/t",format="%8.3f",value=0,width=13,fg_bg=s_field}
|
||||
|
||||
waste_rate.register(unit.unit_ps, "act_burn_rate", waste_rate.update)
|
||||
pu_rate.register(unit.unit_ps, "pu_rate", pu_rate.update)
|
||||
@ -220,7 +220,7 @@ local function make(parent, x, y, wide, unit)
|
||||
sna_act.register(unit.unit_ps, "po_rate", function (r) sna_act.update(r > 0) end)
|
||||
sna_cnt.register(unit.unit_ps, "sna_count", sna_cnt.update)
|
||||
sna_pk.register(unit.unit_ps, "sna_peak_rate", sna_pk.update)
|
||||
sna_max.register(unit.unit_ps, "sna_prod_rate", sna_max.update)
|
||||
sna_max.register(unit.unit_ps, "sna_max_rate", sna_max.update)
|
||||
sna_in.register(unit.unit_ps, "sna_in", sna_in.update)
|
||||
|
||||
return root
|
||||
|
@ -351,7 +351,7 @@ local function init(main)
|
||||
status.register(facility.sps_ps_tbl[1], "computed_status", status.update)
|
||||
|
||||
TextBox{parent=sps_box,x=2,y=3,text="Input Rate",height=1,width=10,fg_bg=style.label}
|
||||
local sps_in = DataIndicator{parent=sps_box,x=2,label="",format="%15.3f",value=0,unit="mB/t",lu_colors=lu_col,width=20,fg_bg=s_field}
|
||||
local sps_in = DataIndicator{parent=sps_box,x=2,label="",format="%15.2f",value=0,unit="mB/t",lu_colors=lu_col,width=20,fg_bg=s_field}
|
||||
|
||||
sps_in.register(facility.ps, "po_am_rate", sps_in.update)
|
||||
|
||||
@ -373,8 +373,8 @@ local function init(main)
|
||||
TextBox{parent=main,x=145,y=21,text="PROC. WASTE",alignment=ALIGN.CENTER,width=19,height=1,fg_bg=wh_gray}
|
||||
local pr_waste = Rectangle{parent=main,x=145,y=22,border=border(1,colors.gray,true),width=19,height=5,thin=true,fg_bg=s_hi_bright}
|
||||
local pu = DataIndicator{parent=pr_waste,lu_colors=lu_c_d,label="Pu",unit="mB/t",format="%9.3f",value=0,width=17}
|
||||
local po = DataIndicator{parent=pr_waste,lu_colors=lu_c_d,label="Po",unit="mB/t",format="%9.3f",value=0,width=17}
|
||||
local popl = DataIndicator{parent=pr_waste,lu_colors=lu_c_d,label="PoPl",unit="mB/t",format="%7.3f",value=0,width=17}
|
||||
local po = DataIndicator{parent=pr_waste,lu_colors=lu_c_d,label="Po",unit="mB/t",format="%9.2f",value=0,width=17}
|
||||
local popl = DataIndicator{parent=pr_waste,lu_colors=lu_c_d,label="PoPl",unit="mB/t",format="%7.2f",value=0,width=17}
|
||||
|
||||
pu.register(facility.ps, "pu_rate", pu.update)
|
||||
po.register(facility.ps, "po_rate", po.update)
|
||||
|
@ -18,7 +18,7 @@ local iocontrol = require("pocket.iocontrol")
|
||||
local pocket = require("pocket.pocket")
|
||||
local renderer = require("pocket.renderer")
|
||||
|
||||
local POCKET_VERSION = "v0.7.0-alpha"
|
||||
local POCKET_VERSION = "v0.7.1-alpha"
|
||||
|
||||
local println = util.println
|
||||
local println_ts = util.println_ts
|
||||
@ -31,9 +31,13 @@ if not pocket.load_config() then
|
||||
-- try to reconfigure (user action)
|
||||
local success, error = configure.configure(true)
|
||||
if success then
|
||||
assert(pocket.load_config(), "failed to load valid configuration")
|
||||
if not pocket.load_config() then
|
||||
println("failed to load a valid configuration, please reconfigure")
|
||||
return
|
||||
end
|
||||
else
|
||||
assert(success, "pocket configuration error: " .. error)
|
||||
println("configuration error: " .. error)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -70,9 +70,9 @@ function databus.tx_link_state(state)
|
||||
end
|
||||
|
||||
-- transmit reactor enable state across the bus
|
||||
---@param active boolean reactor active
|
||||
---@param active any reactor active
|
||||
function databus.tx_reactor_state(active)
|
||||
databus.ps.publish("reactor_active", active)
|
||||
databus.ps.publish("reactor_active", active == true)
|
||||
end
|
||||
|
||||
-- transmit RPS data across the bus
|
||||
|
@ -129,6 +129,21 @@ function plc.rps_init(reactor, is_formed)
|
||||
end
|
||||
end
|
||||
|
||||
-- check if the result of a peripheral call was OK, handle the failure if not
|
||||
---@nodiscard
|
||||
---@param result any PPM function call result
|
||||
---@return boolean succeeded if the result is OK, false if it was a PPM failure
|
||||
local function _check_and_handle_ppm_call(result)
|
||||
if result == ppm.ACCESS_FAULT then
|
||||
_set_fault()
|
||||
elseif result == ppm.UNDEFINED_FIELD then
|
||||
_set_fault()
|
||||
self.formed = false
|
||||
else return true end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- set emergency coolant control (if configured)
|
||||
---@param state boolean true to enable emergency coolant, false to disable
|
||||
local function _set_emer_cool(state)
|
||||
@ -167,25 +182,20 @@ function plc.rps_init(reactor, is_formed)
|
||||
-- check if the reactor is formed
|
||||
local function _is_formed()
|
||||
local formed = reactor.isFormed()
|
||||
if formed == ppm.ACCESS_FAULT then
|
||||
-- lost the peripheral or terminated, handled later
|
||||
_set_fault()
|
||||
else
|
||||
if _check_and_handle_ppm_call(formed) then
|
||||
self.formed = formed
|
||||
end
|
||||
|
||||
if not self.state[state_keys.sys_fail] then
|
||||
self.state[state_keys.sys_fail] = not formed
|
||||
end
|
||||
-- always update, since some ppm failures constitute not being formed
|
||||
if not self.state[state_keys.sys_fail] then
|
||||
self.state[state_keys.sys_fail] = not self.formed
|
||||
end
|
||||
end
|
||||
|
||||
-- check if the reactor is force disabled
|
||||
local function _is_force_disabled()
|
||||
local disabled = reactor.isForceDisabled()
|
||||
if disabled == ppm.ACCESS_FAULT then
|
||||
-- lost the peripheral or terminated, handled later
|
||||
_set_fault()
|
||||
else
|
||||
if _check_and_handle_ppm_call(disabled) then
|
||||
self.force_disabled = disabled
|
||||
|
||||
if not self.state[state_keys.force_disabled] then
|
||||
@ -197,22 +207,16 @@ function plc.rps_init(reactor, is_formed)
|
||||
-- check for high damage
|
||||
local function _high_damage()
|
||||
local damage_percent = reactor.getDamagePercent()
|
||||
if damage_percent == ppm.ACCESS_FAULT then
|
||||
-- lost the peripheral or terminated, handled later
|
||||
_set_fault()
|
||||
elseif not self.state[state_keys.high_dmg] then
|
||||
if _check_and_handle_ppm_call(damage_percent) and not self.state[state_keys.high_dmg] then
|
||||
self.state[state_keys.high_dmg] = damage_percent >= RPS_LIMITS.MAX_DAMAGE_PERCENT
|
||||
end
|
||||
end
|
||||
|
||||
-- check if the reactor is at a critically high temperature
|
||||
local function _high_temp()
|
||||
-- mekanism: MAX_DAMAGE_TEMPERATURE = 1_200
|
||||
-- mekanism: MAX_DAMAGE_TEMPERATURE = 1200K
|
||||
local temp = reactor.getTemperature()
|
||||
if temp == ppm.ACCESS_FAULT then
|
||||
-- lost the peripheral or terminated, handled later
|
||||
_set_fault()
|
||||
elseif not self.state[state_keys.high_temp] then
|
||||
if _check_and_handle_ppm_call(temp) and not self.state[state_keys.high_temp] then
|
||||
self.state[state_keys.high_temp] = temp >= RPS_LIMITS.MAX_DAMAGE_TEMPERATURE
|
||||
end
|
||||
end
|
||||
@ -220,10 +224,7 @@ function plc.rps_init(reactor, is_formed)
|
||||
-- check if there is very low coolant
|
||||
local function _low_coolant()
|
||||
local coolant_filled = reactor.getCoolantFilledPercentage()
|
||||
if coolant_filled == ppm.ACCESS_FAULT then
|
||||
-- lost the peripheral or terminated, handled later
|
||||
_set_fault()
|
||||
elseif not self.state[state_keys.low_coolant] then
|
||||
if _check_and_handle_ppm_call(coolant_filled) and not self.state[state_keys.low_coolant] then
|
||||
self.state[state_keys.low_coolant] = coolant_filled < RPS_LIMITS.MIN_COOLANT_FILL
|
||||
end
|
||||
end
|
||||
@ -231,10 +232,7 @@ function plc.rps_init(reactor, is_formed)
|
||||
-- check for excess waste (>80% filled)
|
||||
local function _excess_waste()
|
||||
local w_filled = reactor.getWasteFilledPercentage()
|
||||
if w_filled == ppm.ACCESS_FAULT then
|
||||
-- lost the peripheral or terminated, handled later
|
||||
_set_fault()
|
||||
elseif not self.state[state_keys.ex_waste] then
|
||||
if _check_and_handle_ppm_call(w_filled) and not self.state[state_keys.ex_waste] then
|
||||
self.state[state_keys.ex_waste] = w_filled > RPS_LIMITS.MAX_WASTE_FILL
|
||||
end
|
||||
end
|
||||
@ -242,10 +240,7 @@ function plc.rps_init(reactor, is_formed)
|
||||
-- check for heated coolant backup (>95% filled)
|
||||
local function _excess_heated_coolant()
|
||||
local hc_filled = reactor.getHeatedCoolantFilledPercentage()
|
||||
if hc_filled == ppm.ACCESS_FAULT then
|
||||
-- lost the peripheral or terminated, handled later
|
||||
_set_fault()
|
||||
elseif not self.state[state_keys.ex_hcoolant] then
|
||||
if _check_and_handle_ppm_call(hc_filled) and not self.state[state_keys.ex_hcoolant] then
|
||||
self.state[state_keys.ex_hcoolant] = hc_filled > RPS_LIMITS.MAX_HEATED_COLLANT_FILL
|
||||
end
|
||||
end
|
||||
@ -253,10 +248,7 @@ function plc.rps_init(reactor, is_formed)
|
||||
-- check if there is no fuel
|
||||
local function _insufficient_fuel()
|
||||
local fuel = reactor.getFuelFilledPercentage()
|
||||
if fuel == ppm.ACCESS_FAULT then
|
||||
-- lost the peripheral or terminated, handled later
|
||||
_set_fault()
|
||||
elseif not self.state[state_keys.no_fuel] then
|
||||
if _check_and_handle_ppm_call(fuel) and not self.state[state_keys.no_fuel] then
|
||||
self.state[state_keys.no_fuel] = fuel <= RPS_LIMITS.NO_FUEL_FILL
|
||||
end
|
||||
end
|
||||
@ -477,13 +469,22 @@ function plc.rps_init(reactor, is_formed)
|
||||
self.tripped = false
|
||||
self.trip_cause = RPS_TRIP_CAUSE.OK
|
||||
|
||||
for i = 1, #self.state do
|
||||
self.state[i] = false
|
||||
end
|
||||
for i = 1, #self.state do self.state[i] = false end
|
||||
|
||||
if not quiet then log.info("RPS: reset") end
|
||||
end
|
||||
|
||||
-- partial RPS reset that only clears fault and sys_fail
|
||||
function public.reset_formed()
|
||||
self.tripped = false
|
||||
self.trip_cause = RPS_TRIP_CAUSE.OK
|
||||
|
||||
self.state[state_keys.fault] = false
|
||||
self.state[state_keys.sys_fail] = false
|
||||
|
||||
log.info("RPS: partial reset on formed")
|
||||
end
|
||||
|
||||
-- reset the automatic and timeout trip flags, then clear trip if that was the trip cause
|
||||
function public.auto_reset()
|
||||
self.state[state_keys.automatic] = false
|
||||
|
@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc")
|
||||
local renderer = require("reactor-plc.renderer")
|
||||
local threads = require("reactor-plc.threads")
|
||||
|
||||
local R_PLC_VERSION = "v1.6.11"
|
||||
local R_PLC_VERSION = "v1.6.14"
|
||||
|
||||
local println = util.println
|
||||
local println_ts = util.println_ts
|
||||
@ -31,9 +31,13 @@ if not plc.load_config() then
|
||||
-- try to reconfigure (user action)
|
||||
local success, error = configure.configure(true)
|
||||
if success then
|
||||
assert(plc.load_config(), "failed to load valid configuration")
|
||||
if not plc.load_config() then
|
||||
println("failed to load a valid configuration, please reconfigure")
|
||||
return
|
||||
end
|
||||
else
|
||||
assert(success, "reactor PLC configuration error: " .. error)
|
||||
println("configuration error: " .. error)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
@ -131,15 +135,22 @@ local function main()
|
||||
|
||||
-- we need a reactor, can at least do some things even if it isn't formed though
|
||||
if plc_state.no_reactor then
|
||||
println("init> fission reactor not found");
|
||||
println("init> fission reactor not found")
|
||||
log.warning("init> no reactor on startup")
|
||||
|
||||
plc_state.init_ok = false
|
||||
plc_state.degraded = true
|
||||
elseif not smem_dev.reactor.isFormed() then
|
||||
println("init> fission reactor not formed");
|
||||
println("init> fission reactor is not formed")
|
||||
log.warning("init> reactor logic adapter present, but reactor is not formed")
|
||||
|
||||
plc_state.degraded = true
|
||||
plc_state.reactor_formed = false
|
||||
elseif smem_dev.reactor.getStatus() == ppm.UNDEFINED_FIELD then
|
||||
-- reactor formed after ppm.mount_all was called
|
||||
println("init> fission reactor was not formed")
|
||||
log.warning("init> reactor reported formed, but multiblock functions are not available")
|
||||
|
||||
plc_state.degraded = true
|
||||
plc_state.reactor_formed = false
|
||||
end
|
||||
|
@ -125,9 +125,8 @@ function threads.thread__main(smem, init)
|
||||
plc_comms.reconnect_reactor(plc_dev.reactor)
|
||||
end
|
||||
|
||||
-- reset RPS for newly connected reactor
|
||||
-- without this, is_formed will be out of date and cause it to think its no longer formed again
|
||||
rps.reset()
|
||||
-- partial reset of RPS, specific to becoming formed
|
||||
rps.reset_formed()
|
||||
else
|
||||
-- fully lost the reactor now :(
|
||||
println_ts("reactor lost (failed reconnect)!")
|
||||
@ -231,9 +230,8 @@ function threads.thread__main(smem, init)
|
||||
plc_comms.reconnect_reactor(plc_dev.reactor)
|
||||
end
|
||||
|
||||
-- reset RPS for newly connected reactor
|
||||
-- without this, is_formed will be out of date and cause it to think its no longer formed again
|
||||
rps.reset()
|
||||
-- partial reset of RPS, specific to becoming formed
|
||||
rps.reset_formed()
|
||||
end
|
||||
elseif networked and type == "modem" then
|
||||
-- note, check init_ok first since nic will be nil if it is false
|
||||
|
@ -31,7 +31,7 @@ local sna_rtu = require("rtu.dev.sna_rtu")
|
||||
local sps_rtu = require("rtu.dev.sps_rtu")
|
||||
local turbinev_rtu = require("rtu.dev.turbinev_rtu")
|
||||
|
||||
local RTU_VERSION = "v1.7.13"
|
||||
local RTU_VERSION = "v1.7.14"
|
||||
|
||||
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
||||
local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE
|
||||
@ -47,9 +47,13 @@ if not rtu.load_config() then
|
||||
-- try to reconfigure (user action)
|
||||
local success, error = configure.configure(true)
|
||||
if success then
|
||||
assert(rtu.load_config(), "failed to load valid configuration")
|
||||
if not rtu.load_config() then
|
||||
println("failed to load a valid configuration, please reconfigure")
|
||||
return
|
||||
end
|
||||
else
|
||||
assert(success, "RTU configuration error: " .. error)
|
||||
println("configuration error: " .. error)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -17,7 +17,7 @@ local max_distance = nil
|
||||
local comms = {}
|
||||
|
||||
-- protocol/data version (protocol/data independent changes tracked by util.lua version)
|
||||
comms.version = "2.4.4"
|
||||
comms.version = "2.4.5"
|
||||
|
||||
---@enum PROTOCOL
|
||||
local PROTOCOL = {
|
||||
|
@ -9,7 +9,7 @@ local util = require("scada-common.util")
|
||||
local ppm = {}
|
||||
|
||||
local ACCESS_FAULT = nil ---@type nil
|
||||
local UNDEFINED_FIELD = "undefined field"
|
||||
local UNDEFINED_FIELD = "__PPM_UNDEF_FIELD__"
|
||||
local VIRTUAL_DEVICE_TYPE = "ppm_vdev"
|
||||
|
||||
ppm.ACCESS_FAULT = ACCESS_FAULT
|
||||
@ -155,7 +155,7 @@ local function peri_init(iface)
|
||||
|
||||
self.fault_counts[key] = self.fault_counts[key] + 1
|
||||
|
||||
return (function () return ACCESS_FAULT end)
|
||||
return (function () return UNDEFINED_FIELD end)
|
||||
end
|
||||
}
|
||||
|
||||
@ -306,7 +306,7 @@ function ppm.log_mounts()
|
||||
log.info(util.c("PPM: had found a ", mount.type, " (", iface, ")"))
|
||||
end
|
||||
|
||||
if #ppm_sys.mounts == 0 then
|
||||
if util.table_len(ppm_sys.mounts) == 0 then
|
||||
log.warning("PPM: no devices had been found")
|
||||
end
|
||||
end
|
||||
|
@ -22,7 +22,7 @@ local t_pack = table.pack
|
||||
local util = {}
|
||||
|
||||
-- scada-common version
|
||||
util.version = "1.1.16"
|
||||
util.version = "1.1.18"
|
||||
|
||||
util.TICK_TIME_S = 0.05
|
||||
util.TICK_TIME_MS = 50
|
||||
@ -284,11 +284,13 @@ function util.cancel_timer(timer) os.cancelTimer(timer) end
|
||||
|
||||
--#region PARALLELIZATION
|
||||
|
||||
-- protected sleep call so we still are in charge of catching termination
|
||||
---@param t integer seconds
|
||||
-- protected sleep call so we still are in charge of catching termination<br>
|
||||
-- returns the result of pcall
|
||||
---@param t number seconds
|
||||
---@return boolean success, any result, any ...
|
||||
--- EVENT_CONSUMER: this function consumes events
|
||||
---@diagnostic disable-next-line: undefined-field
|
||||
function util.psleep(t) pcall(os.sleep, t) end
|
||||
function util.psleep(t) return pcall(os.sleep, t) end
|
||||
|
||||
-- no-op to provide a brief pause (1 tick) to yield<br>
|
||||
--- EVENT_CONSUMER: this function consumes events
|
||||
|
@ -152,6 +152,8 @@ function facility.new(num_reactors, cooling_conf)
|
||||
table.insert(self.test_tone_states, false)
|
||||
end
|
||||
|
||||
-- PRIVATE FUNCTIONS --
|
||||
|
||||
-- check if all auto-controlled units completed ramping
|
||||
---@nodiscard
|
||||
local function _all_units_ramped()
|
||||
@ -228,7 +230,7 @@ function facility.new(num_reactors, cooling_conf)
|
||||
---@class facility
|
||||
local public = {}
|
||||
|
||||
-- ADD/LINK DEVICES --
|
||||
--#region Add/Link Devices
|
||||
|
||||
-- link a redstone RTU session
|
||||
---@param rs_unit unit_session
|
||||
@ -268,11 +270,9 @@ function facility.new(num_reactors, cooling_conf)
|
||||
for _, v in pairs(self.rtu_list) do util.filter_table(v, function (s) return s.get_session_id() ~= session end) end
|
||||
end
|
||||
|
||||
-- UPDATE --
|
||||
--#endregion
|
||||
|
||||
-- supervisor sessions reporting the list of active RTU sessions
|
||||
---@param rtu_sessions table session list of all connected RTUs
|
||||
function public.report_rtus(rtu_sessions) self.rtu_conn_count = #rtu_sessions end
|
||||
--#region Update
|
||||
|
||||
-- update (iterate) the facility management
|
||||
function public.update()
|
||||
@ -323,7 +323,7 @@ function facility.new(num_reactors, cooling_conf)
|
||||
-- Run Process Control --
|
||||
-------------------------
|
||||
|
||||
--#region Process Control
|
||||
--#region
|
||||
|
||||
local avg_charge = self.avg_charge.compute()
|
||||
local avg_inflow = self.avg_inflow.compute()
|
||||
@ -597,7 +597,7 @@ function facility.new(num_reactors, cooling_conf)
|
||||
-- Evaluate Automatic SCRAM --
|
||||
------------------------------
|
||||
|
||||
--#region Automatic SCRAM
|
||||
--#region
|
||||
|
||||
local astatus = self.ascram_status
|
||||
|
||||
@ -727,6 +727,8 @@ function facility.new(num_reactors, cooling_conf)
|
||||
-- Handle Redstone I/O --
|
||||
-------------------------
|
||||
|
||||
--#region
|
||||
|
||||
if #self.redstone > 0 then
|
||||
-- handle facility SCRAM
|
||||
if self.io_ctl.digital_read(IO.F_SCRAM) then
|
||||
@ -756,10 +758,14 @@ function facility.new(num_reactors, cooling_conf)
|
||||
self.io_ctl.digital_write(IO.F_ALARM_ANY, has_any_alarm)
|
||||
end
|
||||
|
||||
--#endregion
|
||||
|
||||
----------------
|
||||
-- Unit Tasks --
|
||||
----------------
|
||||
|
||||
--#region
|
||||
|
||||
local insufficent_po_rate = false
|
||||
local need_emcool = false
|
||||
|
||||
@ -798,10 +804,14 @@ function facility.new(num_reactors, cooling_conf)
|
||||
end
|
||||
end
|
||||
|
||||
--#endregion
|
||||
|
||||
------------------------
|
||||
-- Update Alarm Tones --
|
||||
------------------------
|
||||
|
||||
--#region
|
||||
|
||||
local allow_test = self.allow_testing and self.test_tone_set
|
||||
|
||||
local alarms = { false, false, false, false, false, false, false, false, false, false, false, false }
|
||||
@ -888,6 +898,8 @@ function facility.new(num_reactors, cooling_conf)
|
||||
self.test_tone_set = false
|
||||
self.test_tone_reset = true
|
||||
end
|
||||
|
||||
--#endregion
|
||||
end
|
||||
|
||||
-- call the update function of all units in the facility<br>
|
||||
@ -900,7 +912,9 @@ function facility.new(num_reactors, cooling_conf)
|
||||
end
|
||||
end
|
||||
|
||||
-- COMMANDS --
|
||||
--#endregion
|
||||
|
||||
--#region Commands
|
||||
|
||||
-- SCRAM all reactor units
|
||||
function public.scram_all()
|
||||
@ -988,7 +1002,9 @@ function facility.new(num_reactors, cooling_conf)
|
||||
}
|
||||
end
|
||||
|
||||
-- SETTINGS --
|
||||
--#endregion
|
||||
|
||||
--#region Settings
|
||||
|
||||
-- set the automatic control group of a unit
|
||||
---@param unit_id integer unit ID
|
||||
@ -1029,7 +1045,9 @@ function facility.new(num_reactors, cooling_conf)
|
||||
return self.pu_fallback
|
||||
end
|
||||
|
||||
-- DIAGNOSTIC TESTING --
|
||||
--#endregion
|
||||
|
||||
--#region Diagnostic Testing
|
||||
|
||||
-- attempt to set a test tone state
|
||||
---@param id TONE|0 tone ID or 0 to disable all
|
||||
@ -1069,7 +1087,9 @@ function facility.new(num_reactors, cooling_conf)
|
||||
return self.allow_testing, self.test_alarm_states
|
||||
end
|
||||
|
||||
-- READ STATES/PROPERTIES --
|
||||
--#endregion
|
||||
|
||||
--#region Read States/Properties
|
||||
|
||||
-- get current alarm tone on/off states
|
||||
---@nodiscard
|
||||
@ -1183,6 +1203,12 @@ function facility.new(num_reactors, cooling_conf)
|
||||
return status
|
||||
end
|
||||
|
||||
--#endregion
|
||||
|
||||
-- supervisor sessions reporting the list of active RTU sessions
|
||||
---@param rtu_sessions table session list of all connected RTUs
|
||||
function public.report_rtus(rtu_sessions) self.rtu_conn_count = #rtu_sessions end
|
||||
|
||||
-- get the units in this facility
|
||||
---@nodiscard
|
||||
function public.get_units() return self.units end
|
||||
|
@ -21,7 +21,7 @@ local supervisor = require("supervisor.supervisor")
|
||||
|
||||
local svsessions = require("supervisor.session.svsessions")
|
||||
|
||||
local SUPERVISOR_VERSION = "v1.2.8"
|
||||
local SUPERVISOR_VERSION = "v1.2.11"
|
||||
|
||||
local println = util.println
|
||||
local println_ts = util.println_ts
|
||||
@ -34,9 +34,13 @@ if not supervisor.load_config() then
|
||||
-- try to reconfigure (user action)
|
||||
local success, error = configure.configure(true)
|
||||
if success then
|
||||
assert(supervisor.load_config(), "failed to load valid configuration")
|
||||
if not supervisor.load_config() then
|
||||
println("failed to load a valid configuration, please reconfigure")
|
||||
return
|
||||
end
|
||||
else
|
||||
assert(success, "supervisor configuration error: " .. error)
|
||||
println("configuration error: " .. error)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -77,7 +77,6 @@ function unit.new(reactor_id, num_boilers, num_turbines)
|
||||
tanks = {},
|
||||
snas = {},
|
||||
envd = {},
|
||||
sna_prod_rate = 0,
|
||||
-- redstone control
|
||||
io_ctl = nil, ---@type rs_controller
|
||||
valves = {}, ---@type unit_valves
|
||||
@ -256,7 +255,7 @@ function unit.new(reactor_id, num_boilers, num_turbines)
|
||||
|
||||
-- PRIVATE FUNCTIONS --
|
||||
|
||||
--#region time derivative utility functions
|
||||
--#region Time Derivative Utility Functions
|
||||
|
||||
-- compute a change with respect to time of the given value
|
||||
---@param key string value key
|
||||
@ -331,7 +330,7 @@ function unit.new(reactor_id, num_boilers, num_turbines)
|
||||
|
||||
--#endregion
|
||||
|
||||
--#region redstone I/O
|
||||
--#region Redstone I/O
|
||||
|
||||
-- create a generic valve interface
|
||||
---@nodiscard
|
||||
@ -398,8 +397,7 @@ function unit.new(reactor_id, num_boilers, num_turbines)
|
||||
---@class reactor_unit
|
||||
local public = {}
|
||||
|
||||
-- ADD/LINK DEVICES --
|
||||
--#region
|
||||
--#region Add/Link Devices
|
||||
|
||||
-- link the PLC
|
||||
---@param plc_session plc_session_struct
|
||||
@ -489,7 +487,7 @@ function unit.new(reactor_id, num_boilers, num_turbines)
|
||||
|
||||
--#endregion
|
||||
|
||||
-- UPDATE SESSION --
|
||||
--#region Update Session
|
||||
|
||||
-- update (iterate) this unit
|
||||
function public.update()
|
||||
@ -557,8 +555,9 @@ function unit.new(reactor_id, num_boilers, num_turbines)
|
||||
end
|
||||
end
|
||||
|
||||
-- AUTO CONTROL OPERATIONS --
|
||||
--#region
|
||||
--#endregion
|
||||
|
||||
--#region Auto Control Operations
|
||||
|
||||
-- engage automatic control
|
||||
function public.auto_engage()
|
||||
@ -645,8 +644,7 @@ function unit.new(reactor_id, num_boilers, num_turbines)
|
||||
|
||||
--#endregion
|
||||
|
||||
-- OPERATIONS --
|
||||
--#region
|
||||
--#region Operations
|
||||
|
||||
-- queue a command to disable the reactor
|
||||
function public.disable()
|
||||
@ -726,8 +724,7 @@ function unit.new(reactor_id, num_boilers, num_turbines)
|
||||
|
||||
--#endregion
|
||||
|
||||
-- READ STATES/PROPERTIES --
|
||||
--#region
|
||||
--#region Read States/Properties
|
||||
|
||||
-- check if an alarm of at least a certain priority level is tripped
|
||||
---@nodiscard
|
||||
@ -857,13 +854,15 @@ function unit.new(reactor_id, num_boilers, num_turbines)
|
||||
status.tanks[tank.get_device_idx()] = { tank.is_faulted(), db.formed, db.state, db.tanks }
|
||||
end
|
||||
|
||||
-- basic SNA statistical information
|
||||
local total_peak = 0
|
||||
-- SNA statistical information
|
||||
local total_peak, total_avail, total_out = 0, 0, 0
|
||||
for i = 1, #self.snas do
|
||||
local db = self.snas[i].get_db() ---@type sna_session_db
|
||||
total_peak = total_peak + db.state.peak_production
|
||||
total_avail = total_avail + db.state.production_rate
|
||||
total_out = total_out + math.min(db.tanks.input.amount / 10, db.state.production_rate)
|
||||
end
|
||||
status.sna = { #self.snas, public.get_sna_rate(), total_peak }
|
||||
status.sna = { #self.snas, total_peak, total_avail, total_out }
|
||||
|
||||
-- radiation monitors (environment detectors)
|
||||
status.envds = {}
|
||||
@ -876,7 +875,7 @@ function unit.new(reactor_id, num_boilers, num_turbines)
|
||||
return status
|
||||
end
|
||||
|
||||
-- get the current total [max] production rate is
|
||||
-- get the current total max production rate
|
||||
---@nodiscard
|
||||
---@return number total_avail_rate
|
||||
function public.get_sna_rate()
|
||||
|
@ -54,9 +54,7 @@ function logic.update_annunciator(self)
|
||||
-- variables for boiler, or reactor if no boilers used
|
||||
local total_boil_rate = 0.0
|
||||
|
||||
-------------
|
||||
-- REACTOR --
|
||||
-------------
|
||||
--#region Reactor
|
||||
|
||||
annunc.AutoControl = self.auto_engaged
|
||||
|
||||
@ -143,9 +141,9 @@ function logic.update_annunciator(self)
|
||||
self.plc_cache.ok = false
|
||||
end
|
||||
|
||||
---------------
|
||||
-- MISC RTUs --
|
||||
---------------
|
||||
--#endregion
|
||||
|
||||
--#region Misc RTUs
|
||||
|
||||
local max_rad, any_faulted = 0, false
|
||||
|
||||
@ -170,9 +168,9 @@ function logic.update_annunciator(self)
|
||||
end
|
||||
end
|
||||
|
||||
-------------
|
||||
-- BOILERS --
|
||||
-------------
|
||||
--#endregion
|
||||
|
||||
--#region Boilers
|
||||
|
||||
local boilers_ready = num_boilers == #self.boilers
|
||||
|
||||
@ -230,9 +228,9 @@ function logic.update_annunciator(self)
|
||||
boiler_water_dt_sum = _get_dt(DT_KEYS.ReactorCCool)
|
||||
end
|
||||
|
||||
---------------------------
|
||||
-- COOLANT FEED MISMATCH --
|
||||
---------------------------
|
||||
--#endregion
|
||||
|
||||
--#region Coolant Feed Mismatch
|
||||
|
||||
-- check coolant feed mismatch if using boilers, otherwise calculate with reactor
|
||||
local cfmismatch = false
|
||||
@ -263,9 +261,9 @@ function logic.update_annunciator(self)
|
||||
|
||||
annunc.CoolantFeedMismatch = cfmismatch
|
||||
|
||||
--------------
|
||||
-- TURBINES --
|
||||
--------------
|
||||
--#endregion
|
||||
|
||||
--#region Turbines
|
||||
|
||||
local turbines_ready = num_turbines == #self.turbines
|
||||
|
||||
@ -340,6 +338,8 @@ function logic.update_annunciator(self)
|
||||
annunc.TurbineTrip[idx] = has_steam and db.state.flow_rate == 0
|
||||
end
|
||||
|
||||
--#endregion
|
||||
|
||||
-- update auto control ready state for this unit
|
||||
self.db.control.ready = plc_ready and boilers_ready and turbines_ready
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user