diff --git a/coordinator/iocontrol.lua b/coordinator/iocontrol.lua index 24e839c..a15a236 100644 --- a/coordinator/iocontrol.lua +++ b/coordinator/iocontrol.lua @@ -739,12 +739,14 @@ function iocontrol.update_unit_statuses(statuses) local unit_state = status[5] if type(unit_state) == "table" then - if #unit_state == 5 then + if #unit_state == 6 then unit.unit_ps.publish("U_StatusLine1", unit_state[1]) unit.unit_ps.publish("U_StatusLine2", unit_state[2]) - unit.unit_ps.publish("U_WasteMode", unit_state[3]) - unit.unit_ps.publish("U_AutoReady", unit_state[4]) - unit.unit_ps.publish("U_AutoDegraded", unit_state[5]) + unit.unit_ps.publish("U_AutoReady", unit_state[3]) + unit.unit_ps.publish("U_AutoDegraded", unit_state[4]) + unit.unit_ps.publish("U_AutoWaste", unit_state[5] == types.WASTE_MODE.AUTO) + unit.unit_ps.publish("U_WasteMode", unit_state[5]) + unit.unit_ps.publish("U_WasteProduct", unit_state[6]) else log.debug(log_header .. "unit state length mismatch") valid = false diff --git a/coordinator/ui/components/processctl.lua b/coordinator/ui/components/process_ctl.lua similarity index 70% rename from coordinator/ui/components/processctl.lua rename to coordinator/ui/components/process_ctl.lua index eaeb8ab..b945914 100644 --- a/coordinator/ui/components/processctl.lua +++ b/coordinator/ui/components/process_ctl.lua @@ -15,8 +15,10 @@ local TextBox = require("graphics.elements.textbox") local DataIndicator = require("graphics.elements.indicators.data") local IndicatorLight = require("graphics.elements.indicators.light") local RadIndicator = require("graphics.elements.indicators.rad") +local StateIndicator = require("graphics.elements.indicators.state") local TriIndicatorLight = require("graphics.elements.indicators.trilight") +local Checkbox = require("graphics.elements.controls.checkbox") local HazardButton = require("graphics.elements.controls.hazard_button") local RadioButton = require("graphics.elements.controls.radio_button") local SpinboxNumeric = require("graphics.elements.controls.spinbox_numeric") @@ -43,7 +45,7 @@ local function new_view(root, x, y) local lu_cpair = cpair(colors.gray, colors.gray) local dis_colors = cpair(colors.white, colors.lightGray) - local main = Div{parent=root,width=104,height=24,x=x,y=y} + local main = Div{parent=root,width=128,height=24,x=x,y=y} local scram = HazardButton{parent=main,x=1,y=1,text="FAC SCRAM",accent=colors.yellow,dis_colors=dis_colors,callback=process.fac_scram,fg_bg=hzd_fg_bg} local ack_a = HazardButton{parent=main,x=16,y=1,text="ACK \x13",accent=colors.orange,dis_colors=dis_colors,callback=process.fac_ack_alarms,fg_bg=hzd_fg_bg} @@ -52,8 +54,9 @@ local function new_view(root, x, y) facility.ack_alarms_ack = ack_a.on_response local all_ok = IndicatorLight{parent=main,y=5,label="Unit Systems Online",colors=cpair(colors.green,colors.red)} - local ind_mat = IndicatorLight{parent=main,label="Induction Matrix",colors=cpair(colors.green,colors.gray)} local rad_mon = TriIndicatorLight{parent=main,label="Radiation Monitor",c1=colors.gray,c2=colors.yellow,c3=colors.green} + local ind_mat = IndicatorLight{parent=main,label="Induction Matrix",colors=cpair(colors.green,colors.gray)} + local sps = IndicatorLight{parent=main,label="SPS Online",colors=cpair(colors.green,colors.gray)} all_ok.register(facility.ps, "all_sys_ok", all_ok.update) ind_mat.register(facility.induction_ps_tbl[1], "computed_status", function (status) ind_mat.update(status > 1) end) @@ -99,7 +102,7 @@ local function new_view(root, x, y) -- process control -- --------------------- - local proc = Div{parent=main,width=78,height=24,x=27,y=1} + local proc = Div{parent=main,width=103,height=24,x=27,y=1} ----------------------------- -- process control targets -- @@ -148,46 +151,77 @@ local function new_view(root, x, y) local rate_limits = {} - for i = 1, facility.num_units do - local unit = units[i] ---@type ioctl_unit + for i = 1, 4 do + local unit + local tag_fg_bg = cpair(colors.gray,colors.white) + local lim_fg_bg = cpair(colors.lightGray,colors.white) + local ctl_fg = colors.lightGray + local cur_fg_bg = cpair(colors.lightGray,colors.white) + local cur_lu = colors.lightGray + + if i <= facility.num_units then + unit = units[i] ---@type ioctl_unit + tag_fg_bg = cpair(colors.black,colors.lightBlue) + lim_fg_bg = bw_fg_bg + ctl_fg = colors.gray + cur_fg_bg = cpair(colors.black,colors.brown) + cur_lu = colors.black + end local _y = ((i - 1) * 5) + 1 - local unit_tag = Div{parent=limit_div,x=1,y=_y,width=8,height=4,fg_bg=cpair(colors.black,colors.lightBlue)} + local unit_tag = Div{parent=limit_div,x=1,y=_y,width=8,height=4,fg_bg=tag_fg_bg} TextBox{parent=unit_tag,x=2,y=2,text="Unit "..i.." Limit",width=7,height=2} - local lim_ctl = Div{parent=limit_div,x=9,y=_y,width=14,height=3,fg_bg=cpair(colors.gray,colors.white)} - rate_limits[i] = SpinboxNumeric{parent=lim_ctl,x=2,y=1,whole_num_precision=4,fractional_precision=1,min=0.1,arrow_fg_bg=cpair(colors.gray,colors.white),fg_bg=bw_fg_bg} + local lim_ctl = Div{parent=limit_div,x=9,y=_y,width=14,height=3,fg_bg=cpair(ctl_fg,colors.white)} + local lim = SpinboxNumeric{parent=lim_ctl,x=2,y=1,whole_num_precision=4,fractional_precision=1,min=0.1,arrow_fg_bg=cpair(colors.gray,colors.white),fg_bg=lim_fg_bg} TextBox{parent=lim_ctl,x=9,y=2,text="mB/t",width=4,height=1} - rate_limits[i].register(unit.unit_ps, "max_burn", rate_limits[i].set_max) - rate_limits[i].register(unit.unit_ps, "burn_limit", rate_limits[i].set_value) + local cur_burn = DataIndicator{parent=limit_div,x=9,y=_y+3,label="",format="%7.1f",value=0,unit="mB/t",commas=false,lu_colors=cpair(cur_lu,cur_lu),width=14,fg_bg=cur_fg_bg} - local cur_burn = DataIndicator{parent=limit_div,x=9,y=_y+3,label="",format="%7.1f",value=0,unit="mB/t",commas=false,lu_colors=cpair(colors.black,colors.black),width=14,fg_bg=cpair(colors.black,colors.brown)} + if i <= facility.num_units then + rate_limits[i] = lim + rate_limits[i].register(unit.unit_ps, "max_burn", rate_limits[i].set_max) + rate_limits[i].register(unit.unit_ps, "burn_limit", rate_limits[i].set_value) - cur_burn.register(unit.unit_ps, "act_burn_rate", cur_burn.update) + cur_burn.register(unit.unit_ps, "act_burn_rate", cur_burn.update) + else + lim.disable() + end end ------------------- -- unit statuses -- ------------------- - local stat_div = Div{parent=proc,width=38,height=19,x=57,y=6} + local stat_div = Div{parent=proc,width=22,height=24,x=57,y=6} - for i = 1, facility.num_units do - local unit = units[i] ---@type ioctl_unit + for i = 1, 4 do + local tag_fg_bg = cpair(colors.gray,colors.white) + local ind_fg_bg = cpair(colors.lightGray,colors.white) + local ind_off = colors.lightGray + + if i <= facility.num_units then + tag_fg_bg = cpair(colors.black,colors.cyan) + ind_fg_bg = bw_fg_bg + ind_off = colors.gray + end local _y = ((i - 1) * 5) + 1 - local unit_tag = Div{parent=stat_div,x=1,y=_y,width=8,height=4,fg_bg=cpair(colors.black,colors.lightBlue)} + local unit_tag = Div{parent=stat_div,x=1,y=_y,width=8,height=4,fg_bg=tag_fg_bg} TextBox{parent=unit_tag,x=2,y=2,text="Unit "..i.." Status",width=7,height=2} - local lights = Div{parent=stat_div,x=9,y=_y,width=12,height=4,fg_bg=bw_fg_bg} - local ready = IndicatorLight{parent=lights,x=2,y=2,label="Ready",colors=cpair(colors.green,colors.gray)} - local degraded = IndicatorLight{parent=lights,x=2,y=3,label="Degraded",colors=cpair(colors.red,colors.gray),flash=true,period=period.BLINK_250_MS} + local lights = Div{parent=stat_div,x=9,y=_y,width=14,height=4,fg_bg=ind_fg_bg} + local ready = IndicatorLight{parent=lights,x=2,y=2,label="Ready",colors=cpair(colors.green,ind_off)} + local degraded = IndicatorLight{parent=lights,x=2,y=3,label="Degraded",colors=cpair(colors.red,ind_off),flash=true,period=period.BLINK_250_MS} - ready.register(unit.unit_ps, "U_AutoReady", ready.update) - degraded.register(unit.unit_ps, "U_AutoDegraded", degraded.update) + if i <= facility.num_units then + local unit = units[i] ---@type ioctl_unit + + ready.register(unit.unit_ps, "U_AutoReady", ready.update) + degraded.register(unit.unit_ps, "U_AutoDegraded", degraded.update) + end end ------------------------- @@ -195,7 +229,7 @@ local function new_view(root, x, y) ------------------------- local ctl_opts = { "Monitored Max Burn", "Combined Burn Rate", "Charge Level", "Generation Rate" } - local mode = RadioButton{parent=proc,x=34,y=1,options=ctl_opts,callback=function()end,radio_colors=cpair(colors.purple,colors.black),radio_bg=colors.gray} + local mode = RadioButton{parent=proc,x=34,y=1,options=ctl_opts,callback=function()end,radio_colors=cpair(colors.white,colors.black),radio_bg=colors.purple} mode.register(facility.ps, "process_mode", mode.set_value) @@ -261,6 +295,52 @@ local function new_view(root, x, y) for i = 1, #rate_limits do rate_limits[i].enable() end end end) + + ------------------------------ + -- waste production control -- + ------------------------------ + + local waste_status = Div{parent=proc,width=24,height=4,x=57,y=1,} + + for i = 1, facility.num_units do + local unit = units[i] ---@type ioctl_unit + + TextBox{parent=waste_status,y=i,text="U"..i.." Waste",width=8,height=1} + local a_waste = IndicatorLight{parent=waste_status,x=10,y=i,label="Auto",colors=cpair(colors.white,colors.gray)} + local waste_m = StateIndicator{parent=waste_status,x=17,y=i,states=style.waste.states_abbrv,value=1,min_width=6} + + a_waste.register(unit.unit_ps, "U_AutoWaste", a_waste.update) + waste_m.register(unit.unit_ps, "U_WasteProduct", waste_m.update) + end + + local waste_sel = Div{parent=proc,width=21,height=24,x=81,y=1} + + TextBox{parent=waste_sel,text=" ",width=21,height=1,x=1,y=1,fg_bg=cpair(colors.black,colors.brown)} + TextBox{parent=waste_sel,text="WASTE PRODUCTION",alignment=TEXT_ALIGN.CENTER,width=21,height=1,x=1,y=2,fg_bg=cpair(colors.lightGray,colors.brown)} + + local rect = Rectangle{parent=waste_sel,border=border(1,colors.brown,true),width=21,height=22,x=1,y=3} + local status = StateIndicator{parent=rect,x=2,y=1,states=style.waste.states,value=1,min_width=17} + + RadioButton{parent=rect,x=2,y=3,options=style.waste.options,callback=status.update,radio_colors=cpair(colors.white,colors.black),radio_bg=colors.brown} + + local pu_fallback = Checkbox{parent=rect,x=2,y=7,label="Pu Fallback",callback=function()end,box_fg_bg=cpair(colors.green,colors.black)} + + local fb_active = IndicatorLight{parent=rect,x=2,y=9,label="Fallback Active",colors=cpair(colors.white,colors.gray)} + + 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=bw_fg_bg,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=bw_fg_bg,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="mB/t",format="%12.2f",value=0,lu_colors=lu_cpair,fg_bg=bw_fg_bg,width=17} + + local sna_count = DataIndicator{parent=rect,x=2,y=20,label="Linked SNAs:",format="%4d",value=0,lu_colors=lu_cpair,width=17} + + -- local text_fg_bg = cpair(colors.black, colors.lightGray) + -- local label_fg_bg = cpair(colors.gray, colors.lightGray) + -- local lu_col = cpair(colors.gray, colors.gray) end return new_view diff --git a/coordinator/ui/components/unit_detail.lua b/coordinator/ui/components/unit_detail.lua index 30e2044..7d7bc92 100644 --- a/coordinator/ui/components/unit_detail.lua +++ b/coordinator/ui/components/unit_detail.lua @@ -33,41 +33,21 @@ local border = core.border local period = core.flasher.PERIOD -local waste_opts = { - { - text = "Auto", - fg_bg = cpair(colors.black, colors.lightGray), - active_fg_bg = cpair(colors.white, colors.gray) - }, - { - text = "Pu", - fg_bg = cpair(colors.black, colors.lightGray), - active_fg_bg = cpair(colors.black, colors.green) - }, - { - text = "Po", - fg_bg = cpair(colors.black, colors.lightGray), - active_fg_bg = cpair(colors.black, colors.cyan) - }, - { - text = "AM", - fg_bg = cpair(colors.black, colors.lightGray), - active_fg_bg = cpair(colors.black, colors.purple) - } -} - -- create a unit view ---@param parent graphics_element parent ---@param id integer local function init(parent, id) local unit = iocontrol.get_db().units[id] ---@type ioctl_unit local f_ps = iocontrol.get_db().facility.ps + + local main = Div{parent=parent,x=1,y=1} + + if unit == nil then return main end + local u_ps = unit.unit_ps local b_ps = unit.boiler_ps_tbl local t_ps = unit.turbine_ps_tbl - local main = Div{parent=parent,x=1,y=1} - TextBox{parent=main,text="Reactor Unit #" .. id,alignment=TEXT_ALIGN.CENTER,height=1,fg_bg=style.header} local bw_fg_bg = cpair(colors.black, colors.white) @@ -398,7 +378,7 @@ local function init(parent, id) local waste_proc = Rectangle{parent=main,border=border(1,colors.brown,true),thin=true,width=33,height=3,x=46,y=49} local waste_div = Div{parent=waste_proc,x=2,y=1,width=31,height=1} - local waste_mode = MultiButton{parent=waste_div,x=1,y=1,options=waste_opts,callback=unit.set_waste,min_width=6} + local waste_mode = MultiButton{parent=waste_div,x=1,y=1,options=style.waste.unit_opts,callback=unit.set_waste,min_width=6} waste_mode.register(u_ps, "U_WasteMode", waste_mode.set_value) diff --git a/coordinator/ui/layout/main_view.lua b/coordinator/ui/layout/main_view.lua index a7b3c86..a1b3b5b 100644 --- a/coordinator/ui/layout/main_view.lua +++ b/coordinator/ui/layout/main_view.lua @@ -9,7 +9,7 @@ local iocontrol = require("coordinator.iocontrol") local style = require("coordinator.ui.style") local imatrix = require("coordinator.ui.components.imatrix") -local process_ctl = require("coordinator.ui.components.processctl") +local process_ctl = require("coordinator.ui.components.process_ctl") local unit_overview = require("coordinator.ui.components.unit_overview") local core = require("graphics.core") diff --git a/coordinator/ui/style.lua b/coordinator/ui/style.lua index b78fc91..5db54d5 100644 --- a/coordinator/ui/style.lua +++ b/coordinator/ui/style.lua @@ -151,7 +151,68 @@ style.imatrix = { { color = cpair(colors.black, colors.yellow), text = "HIGH CHARGE" + } + } +} + +style.waste = { + -- auto waste processing states + states = { + { + color = cpair(colors.black, colors.green), + text = "PLUTONIUM" }, + { + color = cpair(colors.black, colors.green), + text = "PLUTONIUM (FB)" + }, + { + color = cpair(colors.black, colors.cyan), + text = "POLONIUM" + }, + { + color = cpair(colors.black, colors.purple), + text = "ANTI MATTER" + } + }, + states_abbrv = { + { + color = cpair(colors.black, colors.green), + text = "Pu" + }, + { + color = cpair(colors.black, colors.cyan), + text = "Po" + }, + { + color = cpair(colors.black, colors.purple), + text = "AM" + } + }, + -- process radio button options + options = { "Plutonium", "Polonium", "Antimatter" }, + -- unit waste selection + unit_opts = { + { + text = "Auto", + fg_bg = cpair(colors.black, colors.lightGray), + active_fg_bg = cpair(colors.white, colors.gray) + }, + { + text = "Pu", + fg_bg = cpair(colors.black, colors.lightGray), + active_fg_bg = cpair(colors.black, colors.green) + }, + { + text = "Po", + fg_bg = cpair(colors.black, colors.lightGray), + active_fg_bg = cpair(colors.black, colors.cyan) + }, + { + text = "AM", + fg_bg = cpair(colors.black, colors.lightGray), + active_fg_bg = cpair(colors.black, colors.purple) + } } } diff --git a/graphics/elements/controls/checkbox.lua b/graphics/elements/controls/checkbox.lua index 42dd937..2867d8b 100644 --- a/graphics/elements/controls/checkbox.lua +++ b/graphics/elements/controls/checkbox.lua @@ -44,8 +44,9 @@ local function checkbox(args) e.window.write("\x95") else -- show as unselected + e.window.setTextColor(e.fg_bg.bkg) e.window.setBackgroundColor(args.box_fg_bg.bkg) - e.window.write("\x80") + e.window.write("\x88") e.window.setTextColor(args.box_fg_bg.bkg) e.window.setBackgroundColor(e.fg_bg.bkg) e.window.write("\x95") diff --git a/install_manifest.json b/install_manifest.json index b93e2b4..b3accc3 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.5a", "bootloader": "0.2", "comms": "2.1.0", "graphics": "1.0.0", "lockbox": "1.0", "reactor-plc": "v1.5.0", "rtu": "v1.4.0", "supervisor": "v0.18.0", "coordinator": "v0.17.1", "pocket": "alpha-v0.5.1"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua", "scada-common/network.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/digest/md5.lua", "lockbox/mac/hmac.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics", "lockbox"], "rtu": ["system", "common", "graphics", "lockbox"], "supervisor": ["system", "common", "graphics", "lockbox"], "coordinator": ["system", "common", "graphics", "lockbox"], "pocket": ["system", "common", "graphics", "lockbox"]}, "sizes": {"manifest": 5568, "system": 1991, "common": 97109, "graphics": 144556, "lockbox": 34900, "reactor-plc": 97595, "rtu": 102247, "supervisor": 315425, "coordinator": 198188, "pocket": 37633}} \ No newline at end of file +{"versions": {"installer": "v1.5a", "bootloader": "0.2", "comms": "2.1.1", "graphics": "1.0.0", "lockbox": "1.0", "reactor-plc": "v1.5.0", "rtu": "v1.4.0", "supervisor": "v0.18.0", "coordinator": "v0.17.1", "pocket": "alpha-v0.5.1"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua", "scada-common/network.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/tabbar.lua", "graphics/elements/controls/checkbox.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/digest/md5.lua", "lockbox/mac/hmac.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/process_ctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/pocket.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics", "lockbox"], "rtu": ["system", "common", "graphics", "lockbox"], "supervisor": ["system", "common", "graphics", "lockbox"], "coordinator": ["system", "common", "graphics", "lockbox"], "pocket": ["system", "common", "graphics", "lockbox"]}, "sizes": {"manifest": 5612, "system": 1991, "common": 97342, "graphics": 147195, "lockbox": 34900, "reactor-plc": 97595, "rtu": 102247, "supervisor": 316739, "coordinator": 203382, "pocket": 37633}} \ No newline at end of file diff --git a/scada-common/comms.lua b/scada-common/comms.lua index 88e8631..8d52e45 100644 --- a/scada-common/comms.lua +++ b/scada-common/comms.lua @@ -14,7 +14,7 @@ local max_distance = nil ---@type number|nil maximum acceptable t ---@class comms local comms = {} -comms.version = "2.1.0" +comms.version = "2.1.1" ---@enum PROTOCOL local PROTOCOL = { diff --git a/scada-common/types.lua b/scada-common/types.lua index 21429b5..9e68632 100644 --- a/scada-common/types.lua +++ b/scada-common/types.lua @@ -158,13 +158,26 @@ types.PROCESS_NAMES = { ---@enum WASTE_MODE types.WASTE_MODE = { AUTO = 1, - PLUTONIUM = 2, - POLONIUM = 3, - ANTI_MATTER = 4 + MANUAL_PLUTONIUM = 2, + MANUAL_POLONIUM = 3, + MANUAL_ANTI_MATTER = 4 } types.WASTE_MODE_NAMES = { "AUTO", + "MANUAL_PLUTONIUM", + "MANUAL_POLONIUM", + "MANUAL_ANTI_MATTER" +} + +---@enum WASTE_PRODUCT +types.WASTE_PRODUCT = { + PLUTONIUM = 1, + POLONIUM = 2, + ANTI_MATTER = 3 +} + +types.WASTE_PRODUCT_NAMES = { "PLUTONIUM", "POLONIUM", "ANTI_MATTER" diff --git a/supervisor/facility.lua b/supervisor/facility.lua index 5864ea5..87c99b2 100644 --- a/supervisor/facility.lua +++ b/supervisor/facility.lua @@ -205,7 +205,7 @@ function facility.new(num_reactors, cooling_conf) table.insert(self.redstone, rs_unit) end - -- link an imatrix RTU session + -- link an induction matrix RTU session ---@param imatrix unit_session function public.add_imatrix(imatrix) table.insert(self.induction, imatrix) diff --git a/supervisor/session/coordinator.lua b/supervisor/session/coordinator.lua index 1b75078..92303d8 100644 --- a/supervisor/session/coordinator.lua +++ b/supervisor/session/coordinator.lua @@ -294,9 +294,9 @@ function coordinator.new_session(id, s_addr, in_queue, out_queue, timeout, facil end elseif cmd == UNIT_COMMAND.SET_WASTE then if (pkt.length == 3) and (type(pkt.data[3]) == "number") and (pkt.data[3] > 0) and (pkt.data[3] <= 4) then - unit.set_waste(pkt.data[3]) + unit.set_waste_mode(pkt.data[3]) else - log.debug(log_header .. "CRDN unit command set waste missing option") + log.debug(log_header .. "CRDN unit command set waste missing/invalid option") end elseif cmd == UNIT_COMMAND.ACK_ALL_ALARMS then unit.ack_all() diff --git a/supervisor/session/rtu.lua b/supervisor/session/rtu.lua index 69ba796..fdf6f55 100644 --- a/supervisor/session/rtu.lua +++ b/supervisor/session/rtu.lua @@ -138,6 +138,10 @@ function rtu.new_session(id, s_addr, in_queue, out_queue, timeout, advertisement -- turbine unit = svrs_turbinev.new(id, i, unit_advert, self.modbus_q) if type(unit) ~= "nil" then target_unit.add_turbine(unit) end + elseif u_type == RTU_UNIT_TYPE.SNA then + -- solar neutron activator + unit = svrs_sna.new(id, i, unit_advert, self.modbus_q) + if type(unit) ~= "nil" then target_unit.add_sna(unit) end elseif u_type == RTU_UNIT_TYPE.ENV_DETECTOR then -- environment detector unit = svrs_envd.new(id, i, unit_advert, self.modbus_q) @@ -161,9 +165,6 @@ function rtu.new_session(id, s_addr, in_queue, out_queue, timeout, advertisement elseif u_type == RTU_UNIT_TYPE.SPS then -- super-critical phase shifter unit = svrs_sps.new(id, i, unit_advert, self.modbus_q) - elseif u_type == RTU_UNIT_TYPE.SNA then - -- solar neutron activator - unit = svrs_sna.new(id, i, unit_advert, self.modbus_q) elseif u_type == RTU_UNIT_TYPE.ENV_DETECTOR then -- environment detector unit = svrs_envd.new(id, i, unit_advert, self.modbus_q) diff --git a/supervisor/unit.lua b/supervisor/unit.lua index 0d7246a..acf03b5 100644 --- a/supervisor/unit.lua +++ b/supervisor/unit.lua @@ -12,6 +12,7 @@ local rsctl = require("supervisor.session.rsctl") local unit = {} local WASTE_MODE = types.WASTE_MODE +local WASTE = types.WASTE_PRODUCT local ALARM = types.ALARM local PRIO = types.ALARM_PRIORITY local ALARM_STATE = types.ALARM_STATE @@ -71,6 +72,7 @@ function unit.new(reactor_id, num_boilers, num_turbines) redstone = {}, boilers = {}, turbines = {}, + sna = {}, envd = {}, -- redstone control io_ctl = nil, ---@type rs_controller @@ -89,7 +91,8 @@ function unit.new(reactor_id, num_boilers, num_turbines) damage_start = 0, damage_last = 0, damage_est_last = 0, - waste_mode = WASTE_MODE.AUTO, + waste_mode = WASTE_MODE.AUTO, ---@type WASTE_MODE + waste_product = WASTE.PLUTONIUM, ---@type WASTE_PRODUCT status_text = { "UNKNOWN", "awaiting connection..." }, -- logic for alarms had_reactor = false, @@ -341,6 +344,32 @@ function unit.new(reactor_id, num_boilers, num_turbines) emer_cool = emer_cool } + -- route reactor waste for a given waste product + ---@param product WASTE_PRODUCT waste product to route valves for + local function _set_waste_valves(product) + self.waste_product = product + + if product == WASTE.PLUTONIUM then + -- route through plutonium generation + waste_pu.open() + waste_sna.close() + waste_po.close() + waste_sps.close() + elseif product == WASTE.POLONIUM then + -- route through polonium generation into pellets + waste_pu.close() + waste_sna.open() + waste_po.open() + waste_sps.close() + elseif product == WASTE.ANTI_MATTER then + -- route through polonium generation into SPS + waste_pu.close() + waste_sna.open() + waste_po.close() + waste_sps.open() + end + end + --#endregion -- unlink disconnected units @@ -378,7 +407,7 @@ function unit.new(reactor_id, num_boilers, num_turbines) table.insert(self.redstone, rs_unit) -- send or re-send waste settings - public.set_waste(self.waste_mode) + _set_waste_valves(self.waste_product) end -- link a turbine RTU session @@ -415,6 +444,12 @@ function unit.new(reactor_id, num_boilers, num_turbines) end end + -- link a solar neutron activator RTU session + ---@param sna unit_session + function public.add_sna(sna) + table.insert(self.sna, sna) + end + -- link an environment detector RTU session ---@param envd unit_session function public.add_envd(envd) @@ -427,6 +462,7 @@ function unit.new(reactor_id, num_boilers, num_turbines) util.filter_table(self.redstone, function (s) return s.get_session_id() ~= session end) util.filter_table(self.boilers, function (s) return s.get_session_id() ~= session end) util.filter_table(self.turbines, function (s) return s.get_session_id() ~= session end) + util.filter_table(self.sna, function (s) return s.get_session_id() ~= session end) util.filter_table(self.envd, function (s) return s.get_session_id() ~= session end) end @@ -577,6 +613,15 @@ function unit.new(reactor_id, num_boilers, num_turbines) end end + -- set automatic waste product if mode is set to auto + ---@param product WASTE_PRODUCT waste product to generate + function public.auto_set_waste(product) + if self.waste_mode == WASTE_MODE.AUTO then + self.waste_product = product + _set_waste_valves(product) + end + end + --#endregion -- OPERATIONS -- @@ -621,34 +666,18 @@ function unit.new(reactor_id, num_boilers, num_turbines) end end - -- route reactor waste - ---@param mode WASTE_MODE waste handling mode - function public.set_waste(mode) - if mode == WASTE_MODE.AUTO then - ---@todo automatic waste routing - self.waste_mode = mode - elseif mode == WASTE_MODE.PLUTONIUM then - -- route through plutonium generation - self.waste_mode = mode - waste_pu.open() - waste_sna.close() - waste_po.close() - waste_sps.close() - elseif mode == WASTE_MODE.POLONIUM then - -- route through polonium generation into pellets - self.waste_mode = mode - waste_pu.close() - waste_sna.open() - waste_po.open() - waste_sps.close() - elseif mode == WASTE_MODE.ANTI_MATTER then - -- route through polonium generation into SPS - self.waste_mode = mode - waste_pu.close() - waste_sna.open() - waste_po.close() - waste_sps.open() - else + -- set waste processing mode + ---@param mode WASTE_MODE processing mode + function public.set_waste_mode(mode) + self.waste_mode = mode + + if mode == WASTE_MODE.MANUAL_PLUTONIUM then + _set_waste_valves(WASTE.PLUTONIUM) + elseif mode == WASTE_MODE.MANUAL_POLONIUM then + _set_waste_valves(WASTE.POLONIUM) + elseif mode == WASTE_MODE.MANUAL_ANTI_MATTER then + _set_waste_valves(WASTE.ANTI_MATTER) + elseif mode > WASTE_MODE.MANUAL_ANTI_MATTER then log.debug(util.c("invalid waste mode setting ", mode)) end end @@ -787,7 +816,14 @@ function unit.new(reactor_id, num_boilers, num_turbines) -- get unit state ---@nodiscard function public.get_state() - return { self.status_text[1], self.status_text[2], self.waste_mode, self.db.control.ready, self.db.control.degraded } + return { + self.status_text[1], + self.status_text[2], + self.db.control.ready, + self.db.control.degraded, + self.waste_mode, + self.waste_product + } end -- get the reactor ID