diff --git a/coordinator/database.lua b/coordinator/database.lua index ecb72b3..0238429 100644 --- a/coordinator/database.lua +++ b/coordinator/database.lua @@ -119,32 +119,115 @@ function database.update_statuses(statuses) local unit = db.units[i] ---@type coord_db_entry local status = statuses[i] - -- reactor status + -- reactor PLC status local reactor_status = status[1] - local mek_status = reactor_status[1] - local rps_status = reactor_status[2] - local gen_status = reactor_status[3] - unit.reactor_data.last_status_update = gen_status[1] - unit.reactor_data.control_state = gen_status[2] - unit.reactor_data.overridden = gen_status[3] - unit.reactor_data.degraded = gen_status[4] - unit.reactor_data.rps_tripped = gen_status[5] - unit.reactor_data.rps_trip_cause = gen_status[6] + if #reactor_status == 0 then + unit.reactor_ps.publish("computed_status", 1) -- disconnected + else + local mek_status = reactor_status[1] + local rps_status = reactor_status[2] + local gen_status = reactor_status[3] - unit.reactor_data.rps_status = rps_status ---@type rps_status - unit.reactor_data.mek_status = mek_status ---@type mek_status + unit.reactor_data.last_status_update = gen_status[1] + unit.reactor_data.control_state = gen_status[2] + unit.reactor_data.overridden = gen_status[3] + unit.reactor_data.degraded = gen_status[4] + unit.reactor_data.rps_tripped = gen_status[5] + unit.reactor_data.rps_trip_cause = gen_status[6] - for key, val in pairs(unit.reactor_data) do - if key ~= "mek_struct" then - unit.reactor_ps.publish(key, val) + unit.reactor_data.rps_status = rps_status ---@type rps_status + unit.reactor_data.mek_status = mek_status ---@type mek_status + + if unit.reactor_data.mek_status.status then + unit.reactor_ps.publish("computed_status", 3) -- running + else + if unit.reactor_data.degraded then + unit.reactor_ps.publish("computed_status", 5) -- faulted + elseif unit.reactor_data.rps_tripped and unit.reactor_data.rps_trip_cause ~= "manual" then + unit.reactor_ps.publish("computed_status", 4) -- SCRAM + else + unit.reactor_ps.publish("computed_status", 2) -- disabled + end + end + + for key, val in pairs(unit.reactor_data) do + if key ~= "mek_struct" then + unit.reactor_ps.publish(key, val) + end end end + -- RTU statuses + + local rtu_statuses = status[2] + -- boiler statuses + for id = 1, #unit.boiler_data_tbl do + if rtu_statuses.boilers[i] == nil then + -- disconnected + unit.boiler_ps_tbl[id].publish(id .. "_computed_status", 1) + end + end + + for id, boiler in pairs(rtu_statuses.boilers) do + unit.boiler_data_tbl[id].state = boiler[1] ---@type table + unit.boiler_data_tbl[id].tanks = boiler[2] ---@type table + + local key_prefix = id .. "_" + + local data = unit.boiler_data_tbl[id] ---@type boiler_session_db|boilerv_session_db + + if data.state.boil_rate > 0 then + unit.boiler_ps_tbl[id].publish(id .. "_computed_status", 3) -- active + else + unit.boiler_ps_tbl[id].publish(id .. "_computed_status", 2) -- idle + end + + for key, val in pairs(unit.boiler_data_tbl[id].state) do + unit.boiler_ps_tbl[id].publish(key_prefix .. key, val) + end + + for key, val in pairs(unit.boiler_data_tbl[id].tanks) do + unit.boiler_ps_tbl[id].publish(key_prefix .. key, val) + end + end + -- turbine statuses + + for id = 1, #unit.turbine_ps_tbl do + if rtu_statuses.turbines[i] == nil then + -- disconnected + unit.turbine_ps_tbl[id].publish(id .. "_computed_status", 1) + end + end + + for id, turbine in pairs(rtu_statuses.turbines) do + unit.turbine_data_tbl[id].state = turbine[1] ---@type table + unit.turbine_data_tbl[id].tanks = turbine[2] ---@type table + + local key_prefix = id .. "_" + + local data = unit.turbine_data_tbl[id] ---@type turbine_session_db|turbinev_session_db + + if data.tanks.steam_fill >= 0.99 then + unit.turbine_ps_tbl[id].publish(id .. "_computed_status", 4) -- trip + elseif data.state.flow_rate < 100 then + unit.turbine_ps_tbl[id].publish(id .. "_computed_status", 2) -- idle + else + unit.turbine_ps_tbl[id].publish(id .. "_computed_status", 3) -- active + end + + for key, val in pairs(unit.turbine_data_tbl[id].state) do + unit.turbine_ps_tbl[id].publish(key_prefix .. key, val) + end + + for key, val in pairs(unit.turbine_data_tbl[id].tanks) do + unit.turbine_ps_tbl[id].publish(key_prefix .. key, val) + end + end end end diff --git a/coordinator/startup.lua b/coordinator/startup.lua index 544cec8..ef3555c 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -16,7 +16,7 @@ local config = require("coordinator.config") local coordinator = require("coordinator.coordinator") local renderer = require("coordinator.renderer") -local COORDINATOR_VERSION = "alpha-v0.4.1" +local COORDINATOR_VERSION = "alpha-v0.4.2" local print = util.print local println = util.println diff --git a/coordinator/ui/components/boiler.lua b/coordinator/ui/components/boiler.lua index 761366a..0d36a2f 100644 --- a/coordinator/ui/components/boiler.lua +++ b/coordinator/ui/components/boiler.lua @@ -1,6 +1,6 @@ -local core = require("graphics.core") +local core = require("graphics.core") -local style = require("coordinator.ui.style") +local style = require("coordinator.ui.style") local DataIndicator = require("graphics.elements.indicators.data") local StateIndicator = require("graphics.elements.indicators.state") @@ -17,20 +17,24 @@ local border = core.graphics.border ---@param root graphics_element ---@param x integer ---@param y integer +---@param id integer +---@param data boiler_session_db|boilerv_session_db ---@param ps psil -local function new_view(root, x, y, ps) +local function new_view(root, x, y, id, data, ps) + local tag = id .. "_" + local boiler = Rectangle{parent=root,border=border(1, colors.gray, true),width=31,height=7,x=x,y=y} local text_fg_bg = cpair(colors.black, colors.lightGray) local lu_col = cpair(colors.gray, colors.gray) - local status = StateIndicator{parent=boiler,x=10,y=1,states=style.boiler.states,value=3,min_width=10} - local temp = DataIndicator{parent=boiler,x=5,y=3,lu_colors=lu_col,label="Temp:",unit="K",format="%10.2f",value=1900,width=22,fg_bg=text_fg_bg} - local boil_r = DataIndicator{parent=boiler,x=5,y=4,lu_colors=lu_col,label="Boil:",unit="mB/t",format="%10.0f",value=801523,commas=true,width=22,fg_bg=text_fg_bg} + local status = StateIndicator{parent=boiler,x=10,y=1,states=style.boiler.states,value=1,min_width=10} + local temp = DataIndicator{parent=boiler,x=5,y=3,lu_colors=lu_col,label="Temp:",unit="K",format="%10.2f",value=data.state.temperature,width=22,fg_bg=text_fg_bg} + local boil_r = DataIndicator{parent=boiler,x=5,y=4,lu_colors=lu_col,label="Boil:",unit="mB/t",format="%10.0f",value=data.state.boil_rate,commas=true,width=22,fg_bg=text_fg_bg} - ps.subscribe("status", status.update) - ps.subscribe("temp", temp.update) - ps.subscribe("boil_rate", boil_r.update) + ps.subscribe(tag .. "computed_status", status.update) + ps.subscribe(tag .. "temperature", temp.update) + ps.subscribe(tag .. "boil_rate", boil_r.update) TextBox{parent=boiler,text="H",x=2,y=5,height=1,width=1,fg_bg=text_fg_bg} TextBox{parent=boiler,text="W",x=3,y=5,height=1,width=1,fg_bg=text_fg_bg} @@ -42,16 +46,15 @@ local function new_view(root, x, y, ps) local steam = VerticalBar{parent=boiler,x=27,y=1,fg_bg=cpair(colors.white,colors.gray),height=4,width=1} local ccool = VerticalBar{parent=boiler,x=28,y=1,fg_bg=cpair(colors.lightBlue,colors.gray),height=4,width=1} - ps.subscribe("hcool", hcool.update) - ps.subscribe("water", water.update) - ps.subscribe("steam", steam.update) - ps.subscribe("ccool", ccool.update) + ps.subscribe(tag .. "hcool_fill", hcool.update) + ps.subscribe(tag .. "water_fill", water.update) + ps.subscribe(tag .. "steam_fill", steam.update) + ps.subscribe(tag .. "ccool_fill", ccool.update) - ---@fixme test code - hcool.update(0.22) - water.update(1) - steam.update(0.05) - ccool.update(0.13) + hcool.update(data.tanks.hcool_fill) + water.update(data.tanks.water_fill) + steam.update(data.tanks.steam_fill) + ccool.update(data.tanks.ccool_fill) end return new_view diff --git a/coordinator/ui/components/reactor.lua b/coordinator/ui/components/reactor.lua index e7cda02..523a949 100644 --- a/coordinator/ui/components/reactor.lua +++ b/coordinator/ui/components/reactor.lua @@ -1,6 +1,8 @@ -local core = require("graphics.core") +local util = require("scada-common.util") -local style = require("coordinator.ui.style") +local core = require("graphics.core") + +local style = require("coordinator.ui.style") local HorizontalBar = require("graphics.elements.indicators.hbar") local DataIndicator = require("graphics.elements.indicators.data") @@ -16,19 +18,20 @@ local border = core.graphics.border ---@param root graphics_element ---@param x integer ---@param y integer +---@param data reactor_db ---@param ps psil -local function new_view(root, x, y, ps) +local function new_view(root, x, y, data, ps) local reactor = Rectangle{parent=root,border=border(1, colors.gray, true),width=30,height=7,x=x,y=y} local text_fg_bg = cpair(colors.black, colors.lightGray) local lu_col = cpair(colors.gray, colors.gray) - local status = StateIndicator{parent=reactor,x=8,y=1,states=style.reactor.states,value=3,min_width=14} - local core_temp = DataIndicator{parent=reactor,x=2,y=3,lu_colors=lu_col,label="Core Temp:",unit="K",format="%10.2f",value=451.12,width=26,fg_bg=text_fg_bg} - local burn_r = DataIndicator{parent=reactor,x=2,y=4,lu_colors=lu_col,label="Burn Rate:",unit="mB/t",format="%10.1f",value=40.1,width=26,fg_bg=text_fg_bg} - local heating_r = DataIndicator{parent=reactor,x=2,y=5,lu_colors=lu_col,label="Heating:",unit="mB/t",format="%12.0f",value=8015342,commas=true,width=26,fg_bg=text_fg_bg} + local status = StateIndicator{parent=reactor,x=8,y=1,states=style.reactor.states,value=1,min_width=14} + local core_temp = DataIndicator{parent=reactor,x=2,y=3,lu_colors=lu_col,label="Core Temp:",unit="K",format="%10.2f",value=data.mek_status.temp,width=26,fg_bg=text_fg_bg} + local burn_r = DataIndicator{parent=reactor,x=2,y=4,lu_colors=lu_col,label="Burn Rate:",unit="mB/t",format="%10.1f",value=data.mek_status.act_burn_rate,width=26,fg_bg=text_fg_bg} + local heating_r = DataIndicator{parent=reactor,x=2,y=5,lu_colors=lu_col,label="Heating:",unit="mB/t",format="%12.0f",value=data.mek_status.heating_rate,commas=true,width=26,fg_bg=text_fg_bg} - ps.subscribe("status", status.update) + ps.subscribe("computed_status", status.update) ps.subscribe("temp", core_temp.update) ps.subscribe("burn_rate", burn_r.update) ps.subscribe("heating_rate", heating_r.update) @@ -40,21 +43,23 @@ local function new_view(root, x, y, ps) TextBox{parent=reactor_fills,text="HCOOL",x=2,y=4,height=1,fg_bg=text_fg_bg} TextBox{parent=reactor_fills,text="WASTE",x=2,y=5,height=1,fg_bg=text_fg_bg} + local ccool_color = util.trinary(data.mek_status.ccool_type == "sodium", cpair(colors.lightBlue,colors.gray), cpair(colors.blue,colors.gray)) + local hcool_color = util.trinary(data.mek_status.hcool_type == "superheated_sodium", cpair(colors.orange,colors.gray), cpair(colors.white,colors.gray)) + local fuel = HorizontalBar{parent=reactor_fills,x=8,y=1,show_percent=true,bar_fg_bg=cpair(colors.black,colors.gray),height=1,width=14} - local ccool = HorizontalBar{parent=reactor_fills,x=8,y=2,show_percent=true,bar_fg_bg=cpair(colors.lightBlue,colors.gray),height=1,width=14} - local hcool = HorizontalBar{parent=reactor_fills,x=8,y=4,show_percent=true,bar_fg_bg=cpair(colors.orange,colors.gray),height=1,width=14} + local ccool = HorizontalBar{parent=reactor_fills,x=8,y=2,show_percent=true,bar_fg_bg=ccool_color,height=1,width=14} + local hcool = HorizontalBar{parent=reactor_fills,x=8,y=4,show_percent=true,bar_fg_bg=hcool_color,height=1,width=14} local waste = HorizontalBar{parent=reactor_fills,x=8,y=5,show_percent=true,bar_fg_bg=cpair(colors.brown,colors.gray),height=1,width=14} - ps.subscribe("fuel", fuel.update) - ps.subscribe("ccool", ccool.update) - ps.subscribe("hcool", hcool.update) - ps.subscribe("waste", waste.update) + ps.subscribe("fuel_fill", fuel.update) + ps.subscribe("ccool_fill", ccool.update) + ps.subscribe("hcool_fill", hcool.update) + ps.subscribe("waste_fill", waste.update) - ---@fixme test code - fuel.update(1) - ccool.update(0.85) - hcool.update(0.08) - waste.update(0.32) + fuel.update(data.mek_status.fuel_fill) + ccool.update(data.mek_status.ccool_fill) + hcool.update(data.mek_status.hcool_fill) + waste.update(data.mek_status.waste_fill) end return new_view diff --git a/coordinator/ui/components/turbine.lua b/coordinator/ui/components/turbine.lua index 7609e3c..705d2ea 100644 --- a/coordinator/ui/components/turbine.lua +++ b/coordinator/ui/components/turbine.lua @@ -1,6 +1,6 @@ -local core = require("graphics.core") +local core = require("graphics.core") -local style = require("coordinator.ui.style") +local style = require("coordinator.ui.style") local DataIndicator = require("graphics.elements.indicators.data") local StateIndicator = require("graphics.elements.indicators.state") @@ -17,27 +17,30 @@ local border = core.graphics.border ---@param root graphics_element ---@param x integer ---@param y integer +---@param id integer +---@param data turbine_session_db|turbinev_session_db ---@param ps psil -local function new_view(root, x, y, ps) +local function new_view(root, x, y, id, data, ps) + local tag = id .. "_" + local turbine = Rectangle{parent=root,border=border(1, colors.gray, true),width=23,height=7,x=x,y=y} local text_fg_bg = cpair(colors.black, colors.lightGray) local lu_col = cpair(colors.gray, colors.gray) - local status = StateIndicator{parent=turbine,x=8,y=1,states=style.turbine.states,value=3,min_width=10} - local prod_rate = DataIndicator{parent=turbine,x=5,y=3,lu_colors=lu_col,label="",unit="MFE",format="%10.2f",value=3.2,width=16,fg_bg=text_fg_bg} - local flow_rate = DataIndicator{parent=turbine,x=5,y=4,lu_colors=lu_col,label="",unit="mB/t",format="%10.0f",value=801523,commas=true,width=16,fg_bg=text_fg_bg} + local status = StateIndicator{parent=turbine,x=8,y=1,states=style.turbine.states,value=1,min_width=10} + local prod_rate = DataIndicator{parent=turbine,x=5,y=3,lu_colors=lu_col,label="",unit="MFE",format="%10.2f",value=data.state.prod_rate,width=16,fg_bg=text_fg_bg} + local flow_rate = DataIndicator{parent=turbine,x=5,y=4,lu_colors=lu_col,label="",unit="mB/t",format="%10.0f",value=data.state.flow_rate,commas=true,width=16,fg_bg=text_fg_bg} - ps.subscribe("status", status.update) - ps.subscribe("prod_rate", prod_rate.update) - ps.subscribe("flow_rate", flow_rate.update) + ps.subscribe(tag .. "computed_status", status.update) + ps.subscribe(tag .. "prod_rate", prod_rate.update) + ps.subscribe(tag .. "flow_rate", flow_rate.update) local steam = VerticalBar{parent=turbine,x=2,y=1,fg_bg=cpair(colors.white,colors.gray),height=5,width=2} - ps.subscribe("steam", steam.update) + ps.subscribe(tag .. "steam_fill", steam.update) - ---@fixme test code - steam.update(0.12) + steam.update(data.tanks.steam_fill) end return new_view diff --git a/coordinator/ui/components/unit_overview.lua b/coordinator/ui/components/unit_overview.lua index 0f70ad8..12ed1de 100644 --- a/coordinator/ui/components/unit_overview.lua +++ b/coordinator/ui/components/unit_overview.lua @@ -50,7 +50,7 @@ local function make(parent, x, y, unit) -- REACTOR -- ------------- - reactor_view(root, 1, 3, unit.reactor_ps) + reactor_view(root, 1, 3, unit.reactor_data, unit.reactor_ps) if num_boilers > 0 then local coolant_pipes = {} @@ -73,8 +73,8 @@ local function make(parent, x, y, unit) -- BOILERS -- ------------- - if num_boilers >= 1 then boiler_view(root, 16, 11, unit.boiler_ps_tbl[1]) end - if num_boilers >= 2 then boiler_view(root, 16, 19, unit.boiler_ps_tbl[2]) end + if num_boilers >= 1 then boiler_view(root, 16, 11, 1, unit.boiler_data_tbl[1], unit.boiler_ps_tbl[1]) end + if num_boilers >= 2 then boiler_view(root, 16, 19, 2, unit.boiler_data_tbl[2], unit.boiler_ps_tbl[2]) end -------------- -- TURBINES -- @@ -84,17 +84,17 @@ local function make(parent, x, y, unit) local no_boilers = num_boilers == 0 if (num_turbines >= 3) or no_boilers or (num_boilers == 1 and num_turbines >= 2) then - turbine_view(root, 58, 3, unit.turbine_ps_tbl[t_idx]) + turbine_view(root, 58, 3, t_idx, unit.turbine_data_tbl[t_idx], unit.turbine_ps_tbl[t_idx]) t_idx = t_idx + 1 end if (num_turbines >= 1 and not no_boilers) or num_turbines >= 2 then - turbine_view(root, 58, 11, unit.turbine_ps_tbl[t_idx]) + turbine_view(root, 58, 11, t_idx, unit.turbine_data_tbl[t_idx], unit.turbine_ps_tbl[t_idx]) t_idx = t_idx + 1 end if (num_turbines >= 2 and num_boilers >= 2) or num_turbines >= 3 then - turbine_view(root, 58, 19, unit.turbine_ps_tbl[t_idx]) + turbine_view(root, 58, 19, t_idx, unit.turbine_data_tbl[t_idx], unit.turbine_ps_tbl[t_idx]) end local steam_pipes_b = {} diff --git a/coordinator/ui/style.lua b/coordinator/ui/style.lua index 897372f..08b0b9b 100644 --- a/coordinator/ui/style.lua +++ b/coordinator/ui/style.lua @@ -50,6 +50,10 @@ style.reactor = { { color = cpair(colors.black, colors.red), text = "SCRAM!" + }, + { + color = cpair(colors.black, colors.orange), + text = "PLC FAULT!" } } }