From b5b67b425ac99ac4e0643bdbcefdd26546227431 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Wed, 4 Sep 2024 21:12:43 +0000 Subject: [PATCH] #498 work on command acknowledgement handling --- coordinator/coordinator.lua | 4 +- coordinator/process.lua | 103 ++++++++++++++++++---- coordinator/ui/components/process_ctl.lua | 4 +- 3 files changed, 92 insertions(+), 19 deletions(-) diff --git a/coordinator/coordinator.lua b/coordinator/coordinator.lua index a0d7169..000ce5f 100644 --- a/coordinator/coordinator.lua +++ b/coordinator/coordinator.lua @@ -576,7 +576,7 @@ function coordinator.comms(version, nic, sv_watchdog) local ack = packet.data[2] == true if cmd == FAC_COMMAND.SCRAM_ALL then - iocontrol.get_db().facility.scram_ack(ack) + process.fac_ack(cmd, ack) elseif cmd == FAC_COMMAND.STOP then iocontrol.get_db().facility.stop_ack(ack) elseif cmd == FAC_COMMAND.START then @@ -586,7 +586,7 @@ function coordinator.comms(version, nic, sv_watchdog) log.debug("SCADA_CRDN process start (with configuration) ack echo packet length mismatch") end elseif cmd == FAC_COMMAND.ACK_ALL_ALARMS then - iocontrol.get_db().facility.ack_alarms_ack(ack) + process.fac_ack(cmd, ack) elseif cmd == FAC_COMMAND.SET_WASTE_MODE then process.waste_ack_handle(packet.data[2]) elseif cmd == FAC_COMMAND.SET_PU_FB then diff --git a/coordinator/process.lua b/coordinator/process.lua index 896573f..06078e2 100644 --- a/coordinator/process.lua +++ b/coordinator/process.lua @@ -13,7 +13,7 @@ local U_CMD = comms.UNIT_COMMAND local PROCESS = types.PROCESS local PRODUCT = types.WASTE_PRODUCT -local REQUEST_TIMEOUT_MS = 5000 +local REQUEST_TIMEOUT_MS = 10000 ---@class process_controller local process = {} @@ -41,6 +41,11 @@ local pctl = { commands = { unit = {}, fac = {} } } +---@class process_command_state +---@field active boolean +---@field timeout integer +---@field requestors table + -- write auto process control to config file local function _write_auto_config() -- save config @@ -142,7 +147,7 @@ function process.create_handle() ---@class process_handle local handle = {} - local function request(cmd) + local function request(cmd, ack) local new = not cmd.active if new then @@ -150,19 +155,19 @@ function process.create_handle() cmd.timeout = util.time_ms() + REQUEST_TIMEOUT_MS end - cmd.requstors[self.id] = true + table.insert(cmd.requstors, ack) return new end - local function u_request(u_id, cmd_id) return request(pctl.commands.unit[u_id][cmd_id]) end - local function f_request(cmd_id) return request(pctl.commands.fac[cmd_id]) end + local function u_request(u_id, cmd_id, ack) return request(pctl.commands.unit[u_id][cmd_id], ack) end + local function f_request(cmd_id, ack) return request(pctl.commands.fac[cmd_id], ack) end --#region Facility Commands -- facility SCRAM command function handle.fac_scram() - if f_request(F_CMD.SCRAM_ALL) then + if f_request(F_CMD.SCRAM_ALL, handle.on_fac_scram_ack) then pctl.comms.send_fac_command(F_CMD.SCRAM_ALL) log.debug("PROCESS: FAC SCRAM ALL") end @@ -170,12 +175,26 @@ function process.create_handle() -- facility alarm acknowledge command function handle.fac_ack_alarms() - if f_request(F_CMD.ACK_ALL_ALARMS) then + if f_request(F_CMD.ACK_ALL_ALARMS, handle.on_fac_ack_alarms_ack) then pctl.comms.send_fac_command(F_CMD.ACK_ALL_ALARMS) log.debug("PROCESS: FAC ACK ALL ALARMS") end end + -- luacheck: no unused args + + -- facility SCRAM ack, override to implement + ---@param success boolean + ---@diagnostic disable-next-line: unused-local + function handle.on_fac_scram_ack(success) end + + -- facility acknowledge all alarms ack, override to implement + ---@param success boolean + ---@diagnostic disable-next-line: unused-local + function handle.on_fac_ack_alarms_ack(success) end + + -- luacheck: unused args + --#endregion --#region Unit Commands @@ -183,7 +202,7 @@ function process.create_handle() -- start a reactor ---@param id integer unit ID function handle.start(id) - if u_request(id, U_CMD.START) then + if u_request(id, U_CMD.START, handle.on_unit_start_ack) then pctl.io.units[id].control_state = true pctl.comms.send_unit_command(U_CMD.START, id) log.debug(util.c("PROCESS: UNIT[", id, "] START")) @@ -193,7 +212,7 @@ function process.create_handle() -- SCRAM reactor ---@param id integer unit ID function handle.scram(id) - if u_request(id, U_CMD.SCRAM) then + if u_request(id, U_CMD.SCRAM, handle.on_unit_scram_ack) then pctl.io.units[id].control_state = false pctl.comms.send_unit_command(U_CMD.SCRAM, id) log.debug(util.c("PROCESS: UNIT[", id, "] SCRAM")) @@ -203,7 +222,7 @@ function process.create_handle() -- reset reactor protection system ---@param id integer unit ID function handle.reset_rps(id) - if u_request(id, U_CMD.RESET_RPS) then + if u_request(id, U_CMD.RESET_RPS, handle.on_unit_rps_reset_ack) then pctl.comms.send_unit_command(U_CMD.RESET_RPS, id) log.debug(util.c("PROCESS: UNIT[", id, "] RESET RPS")) end @@ -212,29 +231,83 @@ function process.create_handle() -- acknowledge all alarms ---@param id integer unit ID function handle.ack_all_alarms(id) - if u_request(id, U_CMD.ACK_ALL_ALARMS) then + if u_request(id, U_CMD.ACK_ALL_ALARMS, handle.on_unit_ack_alarms_ack) then pctl.comms.send_unit_command(U_CMD.ACK_ALL_ALARMS, id) log.debug(util.c("PROCESS: UNIT[", id, "] ACK ALL ALARMS")) end end + -- luacheck: no unused args + + -- unit start ack, override to implement + ---@param success boolean + ---@diagnostic disable-next-line: unused-local + function handle.on_unit_start_ack(success) end + + -- unit SCRAM ack, override to implement + ---@param success boolean + ---@diagnostic disable-next-line: unused-local + function handle.on_unit_scram_ack(success) end + + -- unit RPS reset ack, override to implement + ---@param success boolean + ---@diagnostic disable-next-line: unused-local + function handle.on_unit_rps_reset_ack(success) end + + -- unit acknowledge all alarms ack, override to implement + ---@param success boolean + ---@diagnostic disable-next-line: unused-local + function handle.on_unit_ack_alarms_ack(success) end + + -- luacheck: unused args + --#endregion return handle end function process.clear_timed_out() + local now = util.time_ms() + local objs = { pctl.commands.fac, table.unpack(pctl.commands.unit) } + + for _, obj in pairs(objs) do + ---@cast obj process_command_state + + -- cancel expired requests + if obj.active and now > obj.timeout then + obj.active = false + obj.requestors = {} + end + end end +-- handle a command acknowledgement +---@param cmd_state process_command_state +---@param success boolean if the command was successful +local function cmd_ack(cmd_state, success) + if cmd_state.active then + cmd_state.active = false + + -- call all acknowledge callback functions + for i = 1, #cmd_state.requestors do + cmd_state.requestors[i](success) + end + end +end + +-- handle a facility command acknowledgement ---@param command FAC_COMMAND command -function process.fac_ack(command) - local cmd_req = pctl.commands.fac[command] +---@param success boolean if the command was successful +function process.fac_ack(command, success) + cmd_ack(pctl.commands.fac[command], success) end +-- handle a unit command acknowledgement ---@param unit integer unit ID ---@param command UNIT_COMMAND command -function process.unit_ack(unit, command) - local cmd_req = pctl.commands.unit[unit][command] +---@param success boolean if the command was successful +function process.unit_ack(unit, command, success) + cmd_ack(pctl.commands.unit[unit][command], success) end --#region One-Way Commands (no acknowledgements) diff --git a/coordinator/ui/components/process_ctl.lua b/coordinator/ui/components/process_ctl.lua index 9517823..cbfa420 100644 --- a/coordinator/ui/components/process_ctl.lua +++ b/coordinator/ui/components/process_ctl.lua @@ -66,8 +66,8 @@ local function new_view(root, x, y) local scram = HazardButton{parent=main,x=1,y=1,text="FAC SCRAM",accent=colors.yellow,dis_colors=dis_colors,callback=db.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=db.process.fac_ack_alarms,fg_bg=hzd_fg_bg} - facility.scram_ack = scram.on_response - facility.ack_alarms_ack = ack_a.on_response + db.process.on_fac_scram_ack = scram.on_response + db.process.on_fac_ack_alarms_ack = ack_a.on_response local all_ok = IndicatorLight{parent=main,y=5,label="Unit Systems Online",colors=ind_grn} local rad_mon = TriIndicatorLight{parent=main,label="Radiation Monitor",c1=style.ind_bkg,c2=ind_yel.fgd,c3=ind_grn.fgd}