From ab757e14a73fb7afa594d36e1c18722274fae422 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 20 Oct 2022 12:22:03 -0400 Subject: [PATCH] #100 work in progress on command acks for reactive buttons --- coordinator/coordinator.lua | 23 +++++++++++++-- coordinator/iocontrol.lua | 47 ++++++++++++++++++------------ coordinator/startup.lua | 2 +- supervisor/session/coordinator.lua | 17 ++++++----- supervisor/session/plc.lua | 30 +++++++++++++++++++ supervisor/session/svqtypes.lua | 4 ++- supervisor/session/svsessions.lua | 45 +++++++++++++++------------- supervisor/startup.lua | 2 +- 8 files changed, 118 insertions(+), 52 deletions(-) diff --git a/coordinator/coordinator.lua b/coordinator/coordinator.lua index 22e79d9..655ce58 100644 --- a/coordinator/coordinator.lua +++ b/coordinator/coordinator.lua @@ -18,6 +18,7 @@ local println_ts = util.println_ts local PROTOCOLS = comms.PROTOCOLS local SCADA_MGMT_TYPES = comms.SCADA_MGMT_TYPES local SCADA_CRDN_TYPES = comms.SCADA_CRDN_TYPES +local CRDN_COMMANDS = comms.CRDN_COMMANDS -- request the user to select a monitor ---@param names table available monitors @@ -306,11 +307,11 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, sv_wa end -- send a unit command - ---@param unit integer unit ID ---@param cmd CRDN_COMMANDS command + ---@param unit integer unit ID ---@param option any? optional options (like burn rate) - function public.send_command(unit, cmd, option) - _send_sv(PROTOCOLS.SCADA_CRDN, SCADA_CRDN_TYPES.COMMAND_UNIT, { unit, cmd, option }) + function public.send_command(cmd, unit, option) + _send_sv(PROTOCOLS.SCADA_CRDN, SCADA_CRDN_TYPES.COMMAND_UNIT, { cmd, unit, option }) end -- parse a packet @@ -425,6 +426,22 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, sv_wa log.error("received invalid unit statuses packet") end elseif packet.type == SCADA_CRDN_TYPES.COMMAND_UNIT then + -- unit command acknowledgement + if packet.length == 3 then + local cmd = packet.data[1] + local unit = packet.data[2] + local ack = packet.data[3] + + if cmd == CRDN_COMMANDS.SCRAM then + elseif cmd == CRDN_COMMANDS.START then + elseif cmd == CRDN_COMMANDS.RESET_RPS then + elseif cmd == CRDN_COMMANDS.SET_BURN then + elseif cmd == CRDN_COMMANDS.SET_WASTE then + else + end + else + log.debug("unit command ack packet length mismatch") + end elseif packet.type == SCADA_CRDN_TYPES.ALARM then else log.warning("received unknown SCADA_CRDN packet type " .. packet.type) diff --git a/coordinator/iocontrol.lua b/coordinator/iocontrol.lua index bc93f05..339ad63 100644 --- a/coordinator/iocontrol.lua +++ b/coordinator/iocontrol.lua @@ -34,25 +34,10 @@ function iocontrol.init(conf, comms) burn_rate_cmd = 0.0, waste_control = 0, - start = function () - comms.send_command(i, CRDN_COMMANDS.START) - log.debug(util.c("sent unit ", i, ": START")) - end, - - scram = function () - comms.send_command(i, CRDN_COMMANDS.SCRAM) - log.debug(util.c("sent unit ", i, ": SCRAM")) - end, - - reset_rps = function () - comms.send_command(i, CRDN_COMMANDS.RESET_RPS) - log.debug(util.c("sent unit ", i, ": RESET_RPS")) - end, - - set_burn = function (rate) - comms.send_command(i, CRDN_COMMANDS.SET_BURN, rate) - log.debug(util.c("sent unit ", i, ": SET_BURN = ", rate)) - end, + start = function () end, + scram = function () end, + reset_rps = function () end, + set_burn = function (rate) end, reactor_ps = psil.create(), reactor_data = {}, ---@type reactor_db @@ -64,12 +49,36 @@ function iocontrol.init(conf, comms) turbine_data_tbl = {} } + function entry.start() + entry.control_state = true + comms.send_command(CRDN_COMMANDS.START, i) + log.debug(util.c("UNIT[", i, "]: START")) + end + + function entry.scram() + entry.control_state = false + comms.send_command(CRDN_COMMANDS.SCRAM, i) + log.debug(util.c("UNIT[", i, "]: SCRAM")) + end + + function entry.reset_rps() + comms.send_command(CRDN_COMMANDS.RESET_RPS, i) + log.debug(util.c("UNIT[", i, "]: RESET_RPS")) + end + + function entry.set_burn(rate) + comms.send_command(CRDN_COMMANDS.SET_BURN, i, rate) + log.debug(util.c("UNIT[", i, "]: SET_BURN = ", rate)) + end + + -- create boiler tables for _ = 1, conf.defs[(i * 2) - 1] do local data = {} ---@type boilerv_session_db table.insert(entry.boiler_ps_tbl, psil.create()) table.insert(entry.boiler_data_tbl, data) end + -- create turbine tables for _ = 1, conf.defs[i * 2] do local data = {} ---@type turbinev_session_db table.insert(entry.turbine_ps_tbl, psil.create()) diff --git a/coordinator/startup.lua b/coordinator/startup.lua index aed8ac0..915cb26 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.5.4" +local COORDINATOR_VERSION = "alpha-v0.5.5" local print = util.print local println = util.println diff --git a/supervisor/session/coordinator.lua b/supervisor/session/coordinator.lua index e3c80f7..3db1da7 100644 --- a/supervisor/session/coordinator.lua +++ b/supervisor/session/coordinator.lua @@ -182,26 +182,29 @@ function coordinator.new_session(id, in_queue, out_queue, facility_units) elseif pkt.type == SCADA_CRDN_TYPES.COMMAND_UNIT then if pkt.length >= 2 then -- get command and unit id - local uid = pkt.data[1] - local cmd = pkt.data[2] + local cmd = pkt.data[1] + local uid = pkt.data[2] + + -- pkt.data[3] will be nil except for some commands + local data = { uid, pkt.data[3] } -- continue if valid unit id if util.is_int(uid) and uid > 0 and uid <= #self.units then if cmd == CRDN_COMMANDS.START then - self.out_q.push_data(SV_Q_DATA.START, uid) + self.out_q.push_data(SV_Q_DATA.START, data) elseif cmd == CRDN_COMMANDS.SCRAM then - self.out_q.push_data(SV_Q_DATA.SCRAM, uid) + self.out_q.push_data(SV_Q_DATA.SCRAM, data) elseif cmd == CRDN_COMMANDS.RESET_RPS then - self.out_q.push_data(SV_Q_DATA.RESET_RPS, uid) + self.out_q.push_data(SV_Q_DATA.RESET_RPS, data) elseif cmd == CRDN_COMMANDS.SET_BURN then if pkt.length == 3 then - self.out_q.push_data(SV_Q_DATA.SET_BURN, { uid, pkt.data[3] }) + self.out_q.push_data(SV_Q_DATA.SET_BURN, data) else log.debug(log_header .. "CRDN command unit burn rate missing option") end elseif cmd == CRDN_COMMANDS.SET_WASTE then if pkt.length == 3 then - self.out_q.push_data(SV_Q_DATA.SET_WASTE, { uid, pkt.data[3] }) + self.out_q.push_data(SV_Q_DATA.SET_WASTE, data) else log.debug(log_header .. "CRDN command unit set waste missing option") end diff --git a/supervisor/session/plc.lua b/supervisor/session/plc.lua index a233387..514cd60 100644 --- a/supervisor/session/plc.lua +++ b/supervisor/session/plc.lua @@ -11,6 +11,8 @@ local PROTOCOLS = comms.PROTOCOLS local RPLC_TYPES = comms.RPLC_TYPES local SCADA_MGMT_TYPES = comms.SCADA_MGMT_TYPES +local CRDN_COMMANDS = comms.CRDN_COMMANDS + local print = util.print local println = util.println local print_ts = util.print_ts @@ -336,6 +338,13 @@ function plc.new_session(id, for_reactor, in_queue, out_queue) elseif ack == false then log.debug(log_header .. "burn rate update failed!") end + + -- send acknowledgement to coordinator + self.out_q.push_data(svqtypes.SV_Q_DATA.CRDN_ACK, { + unit = self.for_reactor, + cmd = CRDN_COMMANDS.SET_BURN, + ack = ack + }) elseif pkt.type == RPLC_TYPES.RPS_ENABLE then -- enable acknowledgement local ack = _get_ack(pkt) @@ -345,6 +354,13 @@ function plc.new_session(id, for_reactor, in_queue, out_queue) elseif ack == false then log.debug(log_header .. "enable failed!") end + + -- send acknowledgement to coordinator + self.out_q.push_data(svqtypes.SV_Q_DATA.CRDN_ACK, { + unit = self.for_reactor, + cmd = CRDN_COMMANDS.START, + ack = ack + }) elseif pkt.type == RPLC_TYPES.RPS_SCRAM then -- SCRAM acknowledgement local ack = _get_ack(pkt) @@ -354,6 +370,13 @@ function plc.new_session(id, for_reactor, in_queue, out_queue) elseif ack == false then log.debug(log_header .. "SCRAM failed!") end + + -- send acknowledgement to coordinator + self.out_q.push_data(svqtypes.SV_Q_DATA.CRDN_ACK, { + unit = self.for_reactor, + cmd = CRDN_COMMANDS.SCRAM, + ack = ack + }) elseif pkt.type == RPLC_TYPES.RPS_STATUS then -- RPS status packet received, copy data if pkt.length == 9 then @@ -392,6 +415,13 @@ function plc.new_session(id, for_reactor, in_queue, out_queue) elseif ack == false then log.debug(log_header .. "RPS reset failed") end + + -- send acknowledgement to coordinator + self.out_q.push_data(svqtypes.SV_Q_DATA.CRDN_ACK, { + unit = self.for_reactor, + cmd = CRDN_COMMANDS.RESET_RPS, + ack = ack + }) else log.debug(log_header .. "handler received unsupported RPLC packet type " .. pkt.type) end diff --git a/supervisor/session/svqtypes.lua b/supervisor/session/svqtypes.lua index 175f98b..19f9d54 100644 --- a/supervisor/session/svqtypes.lua +++ b/supervisor/session/svqtypes.lua @@ -9,7 +9,9 @@ local SV_Q_DATA = { SCRAM = 2, RESET_RPS = 3, SET_BURN = 4, - SET_WASTE = 5 + SET_WASTE = 5, + __END_PLC_CMDS__ = 6, + CRDN_ACK = 7 } svqtypes.SV_Q_CMDS = SV_Q_CMDS diff --git a/supervisor/session/svsessions.lua b/supervisor/session/svsessions.lua index 2c42f91..d2ccad0 100644 --- a/supervisor/session/svsessions.lua +++ b/supervisor/session/svsessions.lua @@ -70,25 +70,30 @@ local function _sv_handle_outq(session) elseif msg.qtype == mqueue.TYPE.DATA then -- instruction/notification with body local cmd = msg.message ---@type queue_data - local plc_s = nil - if type(cmd.val) == "table" then - plc_s = svsessions.get_reactor_session(cmd.val[1]) - elseif type(cmd.val) == "number" then - plc_s = svsessions.get_reactor_session(cmd.val) - end + if cmd.key < SV_Q_DATA.__END_PLC_CMDS__ then + -- PLC commands from coordinator + local crdn_sid = session.instance.get_id() + local plc_s = svsessions.get_reactor_session(cmd.val[1]) - if plc_s ~= nil then - if cmd.key == SV_Q_DATA.START then - plc_s.in_queue.push_command(PLC_S_CMDS.ENABLE) - elseif cmd.key == SV_Q_DATA.SCRAM then - plc_s.in_queue.push_command(PLC_S_CMDS.SCRAM) - elseif cmd.key == SV_Q_DATA.RESET_RPS then - plc_s.in_queue.push_command(PLC_S_CMDS.RPS_RESET) - elseif cmd.key == SV_Q_DATA.SET_BURN and type(cmd.val) == "table" and #cmd.val == 2 then - plc_s.in_queue.push_data(PLC_S_DATA.BURN_RATE, cmd.val[2]) - elseif cmd.key == SV_Q_DATA.SET_WASTE and type(cmd.val) == "table" and #cmd.val == 2 then - ---@todo set waste + if plc_s ~= nil then + if cmd.key == SV_Q_DATA.START then + plc_s.in_queue.push_command(PLC_S_CMDS.ENABLE) + elseif cmd.key == SV_Q_DATA.SCRAM then + plc_s.in_queue.push_command(PLC_S_CMDS.SCRAM) + elseif cmd.key == SV_Q_DATA.RESET_RPS then + plc_s.in_queue.push_command(PLC_S_CMDS.RPS_RESET) + elseif cmd.key == SV_Q_DATA.SET_BURN and type(cmd.val) == "table" and #cmd.val == 2 then + plc_s.in_queue.push_data(PLC_S_DATA.BURN_RATE, cmd.val[2]) + elseif cmd.key == SV_Q_DATA.SET_WASTE and type(cmd.val) == "table" and #cmd.val == 2 then + ---@todo set waste + else + log.debug(util.c("unknown PLC SV queue command ", cmd.key)) + end + end + else + if cmd.key == SV_Q_DATA.CRDN_ACK then + ---@todo ack to be sent to coordinator end end end @@ -279,7 +284,7 @@ function svsessions.establish_plc_session(local_port, remote_port, for_reactor, r_port = remote_port, in_queue = mqueue.new(), out_queue = mqueue.new(), - instance = nil + instance = nil ---@type plc_session } plc_s.instance = plc.new_session(self.next_plc_id, for_reactor, plc_s.in_queue, plc_s.out_queue) @@ -317,7 +322,7 @@ function svsessions.establish_rtu_session(local_port, remote_port, advertisement r_port = remote_port, in_queue = mqueue.new(), out_queue = mqueue.new(), - instance = nil + instance = nil ---@type rtu_session } rtu_s.instance = rtu.new_session(self.next_rtu_id, rtu_s.in_queue, rtu_s.out_queue, advertisement, self.facility_units) @@ -346,7 +351,7 @@ function svsessions.establish_coord_session(local_port, remote_port, version) r_port = remote_port, in_queue = mqueue.new(), out_queue = mqueue.new(), - instance = nil + instance = nil ---@type coord_session } coord_s.instance = coordinator.new_session(self.next_coord_id, coord_s.in_queue, coord_s.out_queue, self.facility_units) diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 7d1fae1..b7acdfb 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -13,7 +13,7 @@ local svsessions = require("supervisor.session.svsessions") local config = require("supervisor.config") local supervisor = require("supervisor.supervisor") -local SUPERVISOR_VERSION = "beta-v0.6.3" +local SUPERVISOR_VERSION = "beta-v0.6.4" local print = util.print local println = util.println