mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2025-07-26 03:22:51 +00:00
#498 coordinator process handle system for manual controls
This commit is contained in:
@ -591,6 +591,8 @@ function coordinator.comms(version, nic, sv_watchdog)
|
||||
process.waste_ack_handle(packet.data[2])
|
||||
elseif cmd == FAC_COMMAND.SET_PU_FB then
|
||||
process.pu_fb_ack_handle(packet.data[2])
|
||||
elseif cmd == FAC_COMMAND.SET_SPS_LP then
|
||||
---@todo
|
||||
else
|
||||
log.debug(util.c("received facility command ack with unknown command ", cmd))
|
||||
end
|
||||
@ -625,17 +627,17 @@ function coordinator.comms(version, nic, sv_watchdog)
|
||||
|
||||
if unit ~= nil then
|
||||
if cmd == UNIT_COMMAND.SCRAM then
|
||||
unit.scram_ack(ack)
|
||||
process.unit_ack(unit_id, cmd, ack)
|
||||
elseif cmd == UNIT_COMMAND.START then
|
||||
unit.start_ack(ack)
|
||||
process.unit_ack(unit_id, cmd, ack)
|
||||
elseif cmd == UNIT_COMMAND.RESET_RPS then
|
||||
unit.reset_rps_ack(ack)
|
||||
process.unit_ack(unit_id, cmd, ack)
|
||||
elseif cmd == UNIT_COMMAND.SET_BURN then
|
||||
-- this also doesn't exist
|
||||
elseif cmd == UNIT_COMMAND.SET_WASTE then
|
||||
-- updated by unit updates
|
||||
elseif cmd == UNIT_COMMAND.ACK_ALL_ALARMS then
|
||||
unit.ack_alarms_ack(ack)
|
||||
process.unit_ack(unit_id, cmd, ack)
|
||||
elseif cmd == UNIT_COMMAND.SET_GROUP then
|
||||
-- updated by unit updates
|
||||
else
|
||||
|
@ -82,9 +82,6 @@ function iocontrol.init(conf, comms, temp_scale, energy_scale)
|
||||
io.energy_convert_to_fe = util.joules_to_fe_rf
|
||||
end
|
||||
|
||||
-- coordinator's process handle
|
||||
io.process = process.create_handle()
|
||||
|
||||
-- facility data structure
|
||||
---@class ioctl_facility
|
||||
io.facility = {
|
||||
@ -121,8 +118,6 @@ function iocontrol.init(conf, comms, temp_scale, energy_scale)
|
||||
save_cfg_ack = __generic_ack,
|
||||
start_ack = __generic_ack,
|
||||
stop_ack = __generic_ack,
|
||||
scram_ack = __generic_ack,
|
||||
ack_alarms_ack = __generic_ack,
|
||||
|
||||
alarm_tones = { false, false, false, false, false, false, false, false },
|
||||
|
||||
@ -198,11 +193,6 @@ function iocontrol.init(conf, comms, temp_scale, energy_scale)
|
||||
|
||||
set_group = function (grp) process.set_group(i, grp) end, ---@param grp integer|0 group ID or 0 for manual
|
||||
|
||||
start_ack = __generic_ack,
|
||||
scram_ack = __generic_ack,
|
||||
reset_rps_ack = __generic_ack,
|
||||
ack_alarms_ack = __generic_ack,
|
||||
|
||||
alarm_callbacks = {
|
||||
c_breach = { ack = function () ack(1) end, reset = function () reset(1) end },
|
||||
radiation = { ack = function () ack(2) end, reset = function () reset(2) end },
|
||||
@ -282,6 +272,9 @@ function iocontrol.init(conf, comms, temp_scale, energy_scale)
|
||||
|
||||
-- pass IO control here since it can't be require'd due to a require loop
|
||||
process.init(io, comms)
|
||||
|
||||
-- coordinator's process handle
|
||||
io.process = process.create_handle()
|
||||
end
|
||||
|
||||
--#region Front Panel PSIL
|
||||
|
@ -19,8 +19,8 @@ local REQUEST_TIMEOUT_MS = 10000
|
||||
local process = {}
|
||||
|
||||
local pctl = {
|
||||
io = nil, ---@type ioctl
|
||||
comms = nil, ---@type coord_comms
|
||||
io = nil, ---@type ioctl
|
||||
comms = nil, ---@type coord_comms
|
||||
---@class sys_control_states
|
||||
control_states = {
|
||||
---@class sys_auto_config
|
||||
@ -37,14 +37,16 @@ local pctl = {
|
||||
waste_modes = {},
|
||||
priority_groups = {}
|
||||
},
|
||||
next_handle = 0,
|
||||
commands = { unit = {}, fac = {} }
|
||||
commands = {
|
||||
unit = {}, ---@type process_command_state[][]
|
||||
fac = {} ---@type process_command_state[]
|
||||
}
|
||||
}
|
||||
|
||||
---@class process_command_state
|
||||
---@field active boolean
|
||||
---@field timeout integer
|
||||
---@field requestors table
|
||||
---@field active boolean if this command is live
|
||||
---@field timeout integer expiration time of this command request
|
||||
---@field requestors table list of callbacks from the requestors
|
||||
|
||||
-- write auto process control to config file
|
||||
local function _write_auto_config()
|
||||
@ -138,15 +140,12 @@ end
|
||||
|
||||
-- create a handle to process control for usage of commands that get acknowledgements
|
||||
function process.create_handle()
|
||||
local self = {
|
||||
id = pctl.next_handle
|
||||
}
|
||||
|
||||
pctl.next_handle = pctl.next_handle + 1
|
||||
|
||||
---@class process_handle
|
||||
local handle = {}
|
||||
|
||||
-- add this handle to the requestors and activate the command if inactive
|
||||
---@param cmd process_command_state
|
||||
---@param ack function
|
||||
local function request(cmd, ack)
|
||||
local new = not cmd.active
|
||||
|
||||
@ -155,7 +154,7 @@ function process.create_handle()
|
||||
cmd.timeout = util.time_ms() + REQUEST_TIMEOUT_MS
|
||||
end
|
||||
|
||||
table.insert(cmd.requstors, ack)
|
||||
table.insert(cmd.requestors, ack)
|
||||
|
||||
return new
|
||||
end
|
||||
@ -167,7 +166,7 @@ function process.create_handle()
|
||||
|
||||
-- facility SCRAM command
|
||||
function handle.fac_scram()
|
||||
if f_request(F_CMD.SCRAM_ALL, handle.on_fac_scram_ack) then
|
||||
if f_request(F_CMD.SCRAM_ALL, handle.fac_ack.on_scram) then
|
||||
pctl.comms.send_fac_command(F_CMD.SCRAM_ALL)
|
||||
log.debug("PROCESS: FAC SCRAM ALL")
|
||||
end
|
||||
@ -175,23 +174,25 @@ function process.create_handle()
|
||||
|
||||
-- facility alarm acknowledge command
|
||||
function handle.fac_ack_alarms()
|
||||
if f_request(F_CMD.ACK_ALL_ALARMS, handle.on_fac_ack_alarms_ack) then
|
||||
if f_request(F_CMD.ACK_ALL_ALARMS, handle.fac_ack.on_ack_alarms) then
|
||||
pctl.comms.send_fac_command(F_CMD.ACK_ALL_ALARMS)
|
||||
log.debug("PROCESS: FAC ACK ALL ALARMS")
|
||||
end
|
||||
end
|
||||
|
||||
handle.fac_ack = {}
|
||||
|
||||
-- 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
|
||||
function handle.fac_ack.on_scram(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
|
||||
function handle.fac_ack.on_ack_alarms(success) end
|
||||
|
||||
-- luacheck: unused args
|
||||
|
||||
@ -202,7 +203,7 @@ function process.create_handle()
|
||||
-- start a reactor
|
||||
---@param id integer unit ID
|
||||
function handle.start(id)
|
||||
if u_request(id, U_CMD.START, handle.on_unit_start_ack) then
|
||||
if u_request(id, U_CMD.START, handle.unit_ack[id].on_start) 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"))
|
||||
@ -212,7 +213,7 @@ function process.create_handle()
|
||||
-- SCRAM reactor
|
||||
---@param id integer unit ID
|
||||
function handle.scram(id)
|
||||
if u_request(id, U_CMD.SCRAM, handle.on_unit_scram_ack) then
|
||||
if u_request(id, U_CMD.SCRAM, handle.unit_ack[id].on_scram) 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"))
|
||||
@ -222,7 +223,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, handle.on_unit_rps_reset_ack) then
|
||||
if u_request(id, U_CMD.RESET_RPS, handle.unit_ack[id].on_rps_reset) then
|
||||
pctl.comms.send_unit_command(U_CMD.RESET_RPS, id)
|
||||
log.debug(util.c("PROCESS: UNIT[", id, "] RESET RPS"))
|
||||
end
|
||||
@ -231,52 +232,64 @@ 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, handle.on_unit_ack_alarms_ack) then
|
||||
if u_request(id, U_CMD.ACK_ALL_ALARMS, handle.unit_ack[id].on_ack_alarms) 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 command acknowledgement callbacks, indexed by unit ID
|
||||
---@type process_unit_ack[]
|
||||
handle.unit_ack = {}
|
||||
|
||||
-- unit start ack, override to implement
|
||||
---@param success boolean
|
||||
---@diagnostic disable-next-line: unused-local
|
||||
function handle.on_unit_start_ack(success) end
|
||||
for u = 1, pctl.io.facility.num_units do
|
||||
handle.unit_ack[u] = {}
|
||||
|
||||
-- unit SCRAM ack, override to implement
|
||||
---@param success boolean
|
||||
---@diagnostic disable-next-line: unused-local
|
||||
function handle.on_unit_scram_ack(success) end
|
||||
---@class process_unit_ack
|
||||
local u_ack = handle.unit_ack[u]
|
||||
|
||||
-- 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
|
||||
-- luacheck: no unused args
|
||||
|
||||
-- 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
|
||||
-- unit start ack, override to implement
|
||||
---@param success boolean
|
||||
---@diagnostic disable-next-line: unused-local
|
||||
function u_ack.on_start(success) end
|
||||
|
||||
-- luacheck: unused args
|
||||
-- unit SCRAM ack, override to implement
|
||||
---@param success boolean
|
||||
---@diagnostic disable-next-line: unused-local
|
||||
function u_ack.on_scram(success) end
|
||||
|
||||
-- unit RPS reset ack, override to implement
|
||||
---@param success boolean
|
||||
---@diagnostic disable-next-line: unused-local
|
||||
function u_ack.on_rps_reset(success) end
|
||||
|
||||
-- unit acknowledge all alarms ack, override to implement
|
||||
---@param success boolean
|
||||
---@diagnostic disable-next-line: unused-local
|
||||
function u_ack.on_ack_alarms(success) end
|
||||
|
||||
-- luacheck: unused args
|
||||
end
|
||||
|
||||
--#endregion
|
||||
|
||||
return handle
|
||||
end
|
||||
|
||||
-- clear outstanding process commands that have timed out
|
||||
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 = {}
|
||||
for _, cmd in pairs(obj) do
|
||||
if cmd.active and now > cmd.timeout then
|
||||
cmd.active = false
|
||||
cmd.requestors = {}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -303,11 +316,13 @@ function process.fac_ack(command, success)
|
||||
end
|
||||
|
||||
-- handle a unit command acknowledgement
|
||||
---@param unit integer unit ID
|
||||
---@param unit any unit ID (invalid index protected)
|
||||
---@param command UNIT_COMMAND command
|
||||
---@param success boolean if the command was successful
|
||||
function process.unit_ack(unit, command, success)
|
||||
cmd_ack(pctl.commands.unit[unit][command], success)
|
||||
if pctl.commands.unit[unit] then
|
||||
cmd_ack(pctl.commands.unit[unit][command], success)
|
||||
end
|
||||
end
|
||||
|
||||
--#region One-Way Commands (no acknowledgements)
|
||||
|
@ -6,6 +6,7 @@ local util = require("scada-common.util")
|
||||
|
||||
local coordinator = require("coordinator.coordinator")
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local process = require("coordinator.process")
|
||||
local renderer = require("coordinator.renderer")
|
||||
local sounder = require("coordinator.sounder")
|
||||
|
||||
@ -147,6 +148,9 @@ function threads.thread__main(smem)
|
||||
apisessions.iterate_all()
|
||||
apisessions.free_all_closed()
|
||||
|
||||
-- clear timed out process commands
|
||||
process.clear_timed_out()
|
||||
|
||||
if renderer.ui_ready() then
|
||||
-- update clock used on main and flow monitors
|
||||
iocontrol.get_db().facility.ps.publish("date_time", os.date(smem.date_format))
|
||||
|
@ -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}
|
||||
|
||||
db.process.on_fac_scram_ack = scram.on_response
|
||||
db.process.on_fac_ack_alarms_ack = ack_a.on_response
|
||||
db.process.fac_ack.on_scram = scram.on_response
|
||||
db.process.fac_ack.on_ack_alarms = 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}
|
||||
|
@ -373,10 +373,10 @@ local function init(parent, id)
|
||||
local scram = HazardButton{parent=main,x=2,y=32,text="SCRAM",accent=colors.yellow,dis_colors=dis_colors,callback=unit.scram,fg_bg=hzd_fg_bg}
|
||||
local reset = HazardButton{parent=main,x=22,y=32,text="RESET",accent=colors.red,dis_colors=dis_colors,callback=unit.reset_rps,fg_bg=hzd_fg_bg}
|
||||
|
||||
unit.start_ack = start.on_response
|
||||
unit.scram_ack = scram.on_response
|
||||
unit.reset_rps_ack = reset.on_response
|
||||
unit.ack_alarms_ack = ack_a.on_response
|
||||
db.process.unit_ack[id].on_start = start.on_response
|
||||
db.process.unit_ack[id].on_scram = scram.on_response
|
||||
db.process.unit_ack[id].on_rps_reset = reset.on_response
|
||||
db.process.unit_ack[id].on_ack_alarms = ack_a.on_response
|
||||
|
||||
local function start_button_en_check()
|
||||
if (unit.reactor_data ~= nil) and (unit.reactor_data.mek_status ~= nil) then
|
||||
|
Reference in New Issue
Block a user