diff --git a/coordinator/iocontrol.lua b/coordinator/iocontrol.lua index 7fc2707..5edd724 100644 --- a/coordinator/iocontrol.lua +++ b/coordinator/iocontrol.lua @@ -92,6 +92,7 @@ function iocontrol.init(conf, comms, temp_scale) ---@type WASTE_PRODUCT auto_current_waste_product = types.WASTE_PRODUCT.PLUTONIUM, auto_pu_fallback_active = false, + auto_sps_disabled = false, radiation = types.new_zero_radiation_reading(), @@ -593,7 +594,7 @@ function iocontrol.update_facility_status(status) local ctl_status = status[1] - if type(ctl_status) == "table" and #ctl_status == 16 then + if type(ctl_status) == "table" and #ctl_status == 17 then fac.all_sys_ok = ctl_status[1] fac.auto_ready = ctl_status[2] @@ -644,9 +645,11 @@ function iocontrol.update_facility_status(status) fac.auto_current_waste_product = ctl_status[15] fac.auto_pu_fallback_active = ctl_status[16] + fac.auto_sps_disabled = ctl_status[17] fac.ps.publish("current_waste_product", fac.auto_current_waste_product) fac.ps.publish("pu_fallback_active", fac.auto_pu_fallback_active) + fac.ps.publish("sps_disabled_low_power", fac.auto_sps_disabled) else log.debug(log_header .. "control status not a table or length mismatch") valid = false diff --git a/coordinator/process.lua b/coordinator/process.lua index 581fcd9..1016e62 100644 --- a/coordinator/process.lua +++ b/coordinator/process.lua @@ -29,7 +29,8 @@ local self = { gen_target = 0.0, limits = {}, waste_product = PRODUCT.PLUTONIUM, - pu_fallback = false + pu_fallback = false, + sps_low_power = false }, waste_modes = {}, priority_groups = {} @@ -65,6 +66,7 @@ function process.init(iocontrol, coord_comms) ctl_proc.limits = config.limits ctl_proc.waste_product = config.waste_product ctl_proc.pu_fallback = config.pu_fallback + ctl_proc.sps_low_power = config.sps_low_power self.io.facility.ps.publish("process_mode", ctl_proc.mode) self.io.facility.ps.publish("process_burn_target", ctl_proc.burn_target) @@ -72,6 +74,7 @@ function process.init(iocontrol, coord_comms) self.io.facility.ps.publish("process_gen_target", ctl_proc.gen_target) self.io.facility.ps.publish("process_waste_product", ctl_proc.waste_product) self.io.facility.ps.publish("process_pu_fallback", ctl_proc.pu_fallback) + self.io.facility.ps.publish("process_sps_low_power", ctl_proc.sps_low_power) for id = 1, math.min(#ctl_proc.limits, self.io.facility.num_units) do local unit = self.io.units[id] ---@type ioctl_unit @@ -83,6 +86,7 @@ function process.init(iocontrol, coord_comms) -- notify supervisor of auto waste config self.comms.send_fac_command(FAC_COMMAND.SET_WASTE_MODE, ctl_proc.waste_product) self.comms.send_fac_command(FAC_COMMAND.SET_PU_FB, ctl_proc.pu_fallback) + self.comms.send_fac_command(FAC_COMMAND.SET_SPS_LP, ctl_proc.sps_low_power) end -- unit waste states @@ -259,6 +263,18 @@ function process.set_pu_fallback(enabled) _write_auto_config() end +-- set automatic process control SPS usage at low power +---@param enabled boolean whether to enable SPS usage at low power +function process.set_sps_low_power(enabled) + self.comms.send_fac_command(FAC_COMMAND.SET_SPS_LP, enabled) + + log.debug(util.c("PROCESS: SET SPS LOW POWER ", enabled)) + + -- update config table and save + self.control_states.process.sps_low_power = enabled + _write_auto_config() +end + -- save process control settings ---@param mode PROCESS control mode ---@param burn_target number burn rate target diff --git a/coordinator/ui/components/process_ctl.lua b/coordinator/ui/components/process_ctl.lua index 430409b..92ed8bd 100644 --- a/coordinator/ui/components/process_ctl.lua +++ b/coordinator/ui/components/process_ctl.lua @@ -341,31 +341,23 @@ local function new_view(root, x, y) status.register(facility.ps, "current_waste_product", status.update) local waste_prod = RadioButton{parent=rect,x=2,y=3,options=style.waste.options,callback=process.set_process_waste,radio_colors=cpair(style.theme.accent_dark,style.theme.accent_light),select_color=colors.brown} - local pu_fallback = Checkbox{parent=rect,x=2,y=7,label="Pu Fallback",callback=process.set_pu_fallback,box_fg_bg=cpair(colors.green,style.theme.checkbox_bg)} - waste_prod.register(facility.ps, "process_waste_product", waste_prod.set_value) - pu_fallback.register(facility.ps, "process_pu_fallback", pu_fallback.set_value) + local fb_active = IndicatorLight{parent=rect,x=2,y=7,label="Fallback Active",colors=ind_wht} + local sps_disabled = IndicatorLight{parent=rect,x=2,y=8,label="SPS Disabled LC",colors=ind_yel} - local fb_active = IndicatorLight{parent=rect,x=2,y=9,label="Fallback Active",colors=ind_wht} + local pu_fallback = Checkbox{parent=rect,x=2,y=10,label="Pu Fallback",callback=process.set_pu_fallback,box_fg_bg=cpair(colors.brown,style.theme.checkbox_bg)} + + TextBox{parent=rect,x=2,y=12,height=3,text="Switch to Pu when SNAs cannot keep up with waste.",fg_bg=style.label} + + local lc_sps = Checkbox{parent=rect,x=2,y=16,label="Low Charge SPS",callback=process.set_sps_low_power,box_fg_bg=cpair(colors.brown,style.theme.checkbox_bg)} + + TextBox{parent=rect,x=2,y=18,height=3,text="Use SPS at low charge, otherwise switches to Po.",fg_bg=style.label} fb_active.register(facility.ps, "pu_fallback_active", fb_active.update) - - TextBox{parent=rect,x=2,y=11,text="Plutonium Rate",height=1,width=17,fg_bg=style.label} - local pu_rate = DataIndicator{parent=rect,x=2,label="",unit="mB/t",format="%12.2f",value=0,lu_colors=lu_cpair,fg_bg=s_field,width=17} - - TextBox{parent=rect,x=2,y=14,text="Polonium Rate",height=1,width=17,fg_bg=style.label} - local po_rate = DataIndicator{parent=rect,x=2,label="",unit="mB/t",format="%12.2f",value=0,lu_colors=lu_cpair,fg_bg=s_field,width=17} - - TextBox{parent=rect,x=2,y=17,text="Antimatter Rate",height=1,width=17,fg_bg=style.label} - local am_rate = DataIndicator{parent=rect,x=2,label="",unit="\xb5B/t",format="%12d",value=0,lu_colors=lu_cpair,fg_bg=s_field,width=17} - - pu_rate.register(facility.ps, "pu_rate", pu_rate.update) - po_rate.register(facility.ps, "po_rate", po_rate.update) - am_rate.register(facility.ps, "am_rate", am_rate.update) - - local sna_count = DataIndicator{parent=rect,x=2,y=20,label="Linked SNAs:",format="%4d",value=0,lu_colors=lu_cpair,width=17} - - sna_count.register(facility.ps, "sna_count", sna_count.update) + sps_disabled.register(facility.ps, "sps_disabled_low_power", sps_disabled.update) + waste_prod.register(facility.ps, "process_waste_product", waste_prod.set_value) + pu_fallback.register(facility.ps, "process_pu_fallback", pu_fallback.set_value) + lc_sps.register(facility.ps, "process_sps_low_power", lc_sps.set_value) end return new_view diff --git a/scada-common/comms.lua b/scada-common/comms.lua index cce000c..e107d33 100644 --- a/scada-common/comms.lua +++ b/scada-common/comms.lua @@ -97,7 +97,8 @@ local FAC_COMMAND = { START = 2, -- start automatic process control ACK_ALL_ALARMS = 3, -- acknowledge all alarms on all units SET_WASTE_MODE = 4, -- set automatic waste processing mode - SET_PU_FB = 5 -- set plutonium fallback mode + SET_PU_FB = 5, -- set plutonium fallback mode + SET_SPS_LP = 6 -- set SPS at low power mode } ---@enum UNIT_COMMAND diff --git a/supervisor/facility.lua b/supervisor/facility.lua index 51283d1..94d6af1 100644 --- a/supervisor/facility.lua +++ b/supervisor/facility.lua @@ -120,6 +120,8 @@ function facility.new(config, cooling_conf) waste_product = WASTE.PLUTONIUM, current_waste_product = WASTE.PLUTONIUM, pu_fallback = false, + sps_low_power = false, + disabled_sps = false, -- alarm tones tone_states = {}, test_tone_set = false, @@ -840,9 +842,25 @@ function facility.new(config, cooling_conf) end -- update waste product - if self.waste_product == WASTE.PLUTONIUM or (self.pu_fallback and insufficent_po_rate) then + + self.current_waste_product = self.waste_product + + if (not self.sps_low_power) and (self.waste_product == WASTE.ANTI_MATTER) and (self.induction[1] ~= nil) then + local db = self.induction[1].get_db() ---@type imatrix_session_db + + if db.tanks.energy_fill >= 0.15 then + self.disabled_sps = false + elseif self.disabled_sps or ((db.tanks.last_update > 0) and (db.tanks.energy_fill < 0.1)) then + self.disabled_sps = true + self.current_waste_product = WASTE.POLONIUM + end + else + self.disabled_sps = false + end + + if self.pu_fallback and insufficent_po_rate then self.current_waste_product = WASTE.PLUTONIUM - else self.current_waste_product = self.waste_product end + end -- make sure dynamic tanks are allowing outflow if required -- set all, rather than trying to determine which is for which (simpler & safer) @@ -1099,6 +1117,14 @@ function facility.new(config, cooling_conf) return self.pu_fallback end + -- enable/disable SPS at low power + ---@param enabled boolean requested state + ---@return boolean enabled newly set value + function public.set_sps_low_power(enabled) + self.sps_low_power = enabled == true + return self.sps_low_power + end + --#endregion --#region Diagnostic Testing @@ -1203,7 +1229,8 @@ function facility.new(config, cooling_conf) self.status_text[2], self.group_map, self.current_waste_product, - (self.current_waste_product == WASTE.PLUTONIUM) and (self.waste_product ~= WASTE.PLUTONIUM) + self.pu_fallback and (self.current_waste_product == WASTE.PLUTONIUM) and (self.waste_product ~= WASTE.PLUTONIUM), + self.disabled_sps } end diff --git a/supervisor/session/coordinator.lua b/supervisor/session/coordinator.lua index c0e6482..9c9284f 100644 --- a/supervisor/session/coordinator.lua +++ b/supervisor/session/coordinator.lua @@ -270,6 +270,12 @@ function coordinator.new_session(id, s_addr, in_queue, out_queue, timeout, facil else log.debug(log_header .. "CRDN set pu fallback packet length mismatch") end + elseif cmd == FAC_COMMAND.SET_SPS_LP then + if pkt.length == 2 then + _send(CRDN_TYPE.FAC_CMD, { cmd, facility.set_sps_low_power(pkt.data[2]) }) + else + log.debug(log_header .. "CRDN set sps low power packet length mismatch") + end else log.debug(log_header .. "CRDN facility command unknown") end