#47 supervisor luadoc, bugfixes
This commit is contained in:
@@ -37,6 +37,10 @@ local PERIODICS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
-- PLC supervisor session
|
-- PLC supervisor session
|
||||||
|
---@param id integer
|
||||||
|
---@param for_reactor integer
|
||||||
|
---@param in_queue mqueue
|
||||||
|
---@param out_queue mqueue
|
||||||
plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
||||||
local log_header = "plc_session(" .. id .. "): "
|
local log_header = "plc_session(" .. id .. "): "
|
||||||
|
|
||||||
@@ -78,6 +82,7 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
rps_reset = true
|
rps_reset = true
|
||||||
},
|
},
|
||||||
-- session database
|
-- session database
|
||||||
|
---@class reactor_db
|
||||||
sDB = {
|
sDB = {
|
||||||
last_status_update = 0,
|
last_status_update = 0,
|
||||||
control_state = false,
|
control_state = false,
|
||||||
@@ -85,6 +90,7 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
degraded = false,
|
degraded = false,
|
||||||
rps_tripped = false,
|
rps_tripped = false,
|
||||||
rps_trip_cause = "ok",
|
rps_trip_cause = "ok",
|
||||||
|
---@class rps_status
|
||||||
rps_status = {
|
rps_status = {
|
||||||
dmg_crit = false,
|
dmg_crit = false,
|
||||||
ex_hcool = false,
|
ex_hcool = false,
|
||||||
@@ -94,45 +100,52 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
no_cool = false,
|
no_cool = false,
|
||||||
timed_out = false
|
timed_out = false
|
||||||
},
|
},
|
||||||
|
---@class mek_status
|
||||||
mek_status = {
|
mek_status = {
|
||||||
heating_rate = 0,
|
heating_rate = 0.0,
|
||||||
|
|
||||||
status = false,
|
status = false,
|
||||||
burn_rate = 0,
|
burn_rate = 0.0,
|
||||||
act_burn_rate = 0,
|
act_burn_rate = 0.0,
|
||||||
temp = 0,
|
temp = 0.0,
|
||||||
damage = 0,
|
damage = 0.0,
|
||||||
boil_eff = 0,
|
boil_eff = 0.0,
|
||||||
env_loss = 0,
|
env_loss = 0.0,
|
||||||
|
|
||||||
fuel = 0,
|
fuel = 0.0,
|
||||||
fuel_need = 0,
|
fuel_need = 0.0,
|
||||||
fuel_fill = 0,
|
fuel_fill = 0.0,
|
||||||
waste = 0,
|
waste = 0.0,
|
||||||
waste_need = 0,
|
waste_need = 0.0,
|
||||||
waste_fill = 0,
|
waste_fill = 0.0,
|
||||||
cool_type = "?",
|
cool_type = "?",
|
||||||
cool_amnt = 0,
|
cool_amnt = 0.0,
|
||||||
cool_need = 0,
|
cool_need = 0.0,
|
||||||
cool_fill = 0,
|
cool_fill = 0.0,
|
||||||
hcool_type = "?",
|
hcool_type = "?",
|
||||||
hcool_amnt = 0,
|
hcool_amnt = 0.0,
|
||||||
hcool_need = 0,
|
hcool_need = 0.0,
|
||||||
hcool_fill = 0
|
hcool_fill = 0.0
|
||||||
},
|
},
|
||||||
|
---@class mek_struct
|
||||||
mek_struct = {
|
mek_struct = {
|
||||||
heat_cap = 0,
|
heat_cap = 0.0,
|
||||||
fuel_asm = 0,
|
fuel_asm = 0.0,
|
||||||
fuel_sa = 0,
|
fuel_sa = 0.0,
|
||||||
fuel_cap = 0,
|
fuel_cap = 0.0,
|
||||||
waste_cap = 0,
|
waste_cap = 0.0,
|
||||||
cool_cap = 0,
|
cool_cap = 0.0,
|
||||||
hcool_cap = 0,
|
hcool_cap = 0.0,
|
||||||
max_burn = 0
|
max_burn = 0.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@class plc_session
|
||||||
|
local public = {}
|
||||||
|
|
||||||
|
-- copy in the RPS status
|
||||||
|
---@param rps_status table
|
||||||
local _copy_rps_status = function (rps_status)
|
local _copy_rps_status = function (rps_status)
|
||||||
self.sDB.rps_status.dmg_crit = rps_status[1]
|
self.sDB.rps_status.dmg_crit = rps_status[1]
|
||||||
self.sDB.rps_status.ex_hcool = rps_status[2]
|
self.sDB.rps_status.ex_hcool = rps_status[2]
|
||||||
@@ -143,6 +156,8 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
self.sDB.rps_status.timed_out = rps_status[7]
|
self.sDB.rps_status.timed_out = rps_status[7]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- copy in the reactor status
|
||||||
|
---@param mek_data table
|
||||||
local _copy_status = function (mek_data)
|
local _copy_status = function (mek_data)
|
||||||
-- copy status information
|
-- copy status information
|
||||||
self.sDB.mek_status.status = mek_data[1]
|
self.sDB.mek_status.status = mek_data[1]
|
||||||
@@ -174,6 +189,8 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- copy in the reactor structure
|
||||||
|
---@param mek_data table
|
||||||
local _copy_struct = function (mek_data)
|
local _copy_struct = function (mek_data)
|
||||||
self.sDB.mek_struct.heat_cap = mek_data[1]
|
self.sDB.mek_struct.heat_cap = mek_data[1]
|
||||||
self.sDB.mek_struct.fuel_asm = mek_data[2]
|
self.sDB.mek_struct.fuel_asm = mek_data[2]
|
||||||
@@ -186,6 +203,8 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- send an RPLC packet
|
-- send an RPLC packet
|
||||||
|
---@param msg_type RPLC_TYPES
|
||||||
|
---@param msg table
|
||||||
local _send = function (msg_type, msg)
|
local _send = function (msg_type, msg)
|
||||||
local s_pkt = comms.scada_packet()
|
local s_pkt = comms.scada_packet()
|
||||||
local r_pkt = comms.rplc_packet()
|
local r_pkt = comms.rplc_packet()
|
||||||
@@ -198,6 +217,8 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- send a SCADA management packet
|
-- send a SCADA management packet
|
||||||
|
---@param msg_type SCADA_MGMT_TYPES
|
||||||
|
---@param msg table
|
||||||
local _send_mgmt = function (msg_type, msg)
|
local _send_mgmt = function (msg_type, msg)
|
||||||
local s_pkt = comms.scada_packet()
|
local s_pkt = comms.scada_packet()
|
||||||
local m_pkt = comms.mgmt_packet()
|
local m_pkt = comms.mgmt_packet()
|
||||||
@@ -210,6 +231,8 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get an ACK status
|
-- get an ACK status
|
||||||
|
---@param pkt rplc_frame
|
||||||
|
---@return boolean|nil ack
|
||||||
local _get_ack = function (pkt)
|
local _get_ack = function (pkt)
|
||||||
if pkt.length == 1 then
|
if pkt.length == 1 then
|
||||||
return pkt.data[1]
|
return pkt.data[1]
|
||||||
@@ -220,6 +243,7 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- handle a packet
|
-- handle a packet
|
||||||
|
---@param pkt rplc_frame
|
||||||
local _handle_packet = function (pkt)
|
local _handle_packet = function (pkt)
|
||||||
-- check sequence number
|
-- check sequence number
|
||||||
if self.r_seq_num == nil then
|
if self.r_seq_num == nil then
|
||||||
@@ -378,13 +402,13 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
-- PUBLIC FUNCTIONS --
|
-- PUBLIC FUNCTIONS --
|
||||||
|
|
||||||
-- get the session ID
|
-- get the session ID
|
||||||
local get_id = function () return self.id end
|
public.get_id = function () return self.id end
|
||||||
|
|
||||||
-- get the session database
|
-- get the session database
|
||||||
local get_db = function () return self.sDB end
|
public.get_db = function () return self.sDB end
|
||||||
|
|
||||||
-- get the reactor structure
|
-- get the reactor structure
|
||||||
local get_struct = function ()
|
public.get_struct = function ()
|
||||||
if self.received_struct then
|
if self.received_struct then
|
||||||
return self.sDB.mek_struct
|
return self.sDB.mek_struct
|
||||||
else
|
else
|
||||||
@@ -393,7 +417,7 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get the reactor structure
|
-- get the reactor structure
|
||||||
local get_status = function ()
|
public.get_status = function ()
|
||||||
if self.received_status_cache then
|
if self.received_status_cache then
|
||||||
return self.sDB.mek_status
|
return self.sDB.mek_status
|
||||||
else
|
else
|
||||||
@@ -402,12 +426,12 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- check if a timer matches this session's watchdog
|
-- check if a timer matches this session's watchdog
|
||||||
local check_wd = function (timer)
|
public.check_wd = function (timer)
|
||||||
return self.plc_conn_watchdog.is_timer(timer)
|
return self.plc_conn_watchdog.is_timer(timer)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- close the connection
|
-- close the connection
|
||||||
local close = function ()
|
public.close = function ()
|
||||||
self.plc_conn_watchdog.cancel()
|
self.plc_conn_watchdog.cancel()
|
||||||
self.connected = false
|
self.connected = false
|
||||||
_send_mgmt(SCADA_MGMT_TYPES.CLOSE, {})
|
_send_mgmt(SCADA_MGMT_TYPES.CLOSE, {})
|
||||||
@@ -416,7 +440,8 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- iterate the session
|
-- iterate the session
|
||||||
local iterate = function ()
|
---@return boolean connected
|
||||||
|
public.iterate = function ()
|
||||||
if self.connected then
|
if self.connected then
|
||||||
------------------
|
------------------
|
||||||
-- handle queue --
|
-- handle queue --
|
||||||
@@ -428,6 +453,7 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
-- get a new message to process
|
-- get a new message to process
|
||||||
local message = self.in_q.pop()
|
local message = self.in_q.pop()
|
||||||
|
|
||||||
|
if message ~= nil then
|
||||||
if message.qtype == mqueue.TYPE.PACKET then
|
if message.qtype == mqueue.TYPE.PACKET then
|
||||||
-- handle a packet
|
-- handle a packet
|
||||||
_handle_packet(message.message)
|
_handle_packet(message.message)
|
||||||
@@ -469,6 +495,7 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
_send(RPLC_TYPES.MEK_BURN_RATE, { self.commanded_burn_rate, self.ramping_rate })
|
_send(RPLC_TYPES.MEK_BURN_RATE, { self.commanded_burn_rate, self.ramping_rate })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- max 100ms spent processing queue
|
-- max 100ms spent processing queue
|
||||||
if util.time() - handle_start > 100 then
|
if util.time() - handle_start > 100 then
|
||||||
@@ -567,15 +594,7 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
return self.connected
|
return self.connected
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return public
|
||||||
get_id = get_id,
|
|
||||||
get_db = get_db,
|
|
||||||
get_struct = get_struct,
|
|
||||||
get_status = get_status,
|
|
||||||
check_wd = check_wd,
|
|
||||||
close = close,
|
|
||||||
iterate = iterate
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return plc
|
return plc
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ rtu.new_session = function (id, in_queue, out_queue)
|
|||||||
elseif pkt.type == SCADA_MGMT_TYPES.RTU_ADVERT then
|
elseif pkt.type == SCADA_MGMT_TYPES.RTU_ADVERT then
|
||||||
-- RTU unit advertisement
|
-- RTU unit advertisement
|
||||||
for i = 1, pkt.length do
|
for i = 1, pkt.length do
|
||||||
local unit = pkt.data[i]
|
local unit = pkt.data[i] ---@type rtu_advertisement
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "handler received unsupported SCADA_MGMT packet type " .. pkt.type)
|
log.debug(log_header .. "handler received unsupported SCADA_MGMT packet type " .. pkt.type)
|
||||||
|
|||||||
@@ -31,16 +31,17 @@ local self = {
|
|||||||
-- PRIVATE FUNCTIONS --
|
-- PRIVATE FUNCTIONS --
|
||||||
|
|
||||||
-- iterate all the given sessions
|
-- iterate all the given sessions
|
||||||
|
---@param sessions table
|
||||||
local function _iterate(sessions)
|
local function _iterate(sessions)
|
||||||
for i = 1, #sessions do
|
for i = 1, #sessions do
|
||||||
local session = sessions[i]
|
local session = sessions[i] ---@type plc_session_struct
|
||||||
if session.open then
|
if session.open then
|
||||||
local ok = session.instance.iterate()
|
local ok = session.instance.iterate()
|
||||||
if ok then
|
if ok then
|
||||||
-- send packets in out queue
|
-- send packets in out queue
|
||||||
while session.out_queue.ready() do
|
while session.out_queue.ready() do
|
||||||
local msg = session.out_queue.pop()
|
local msg = session.out_queue.pop()
|
||||||
if msg.qtype == mqueue.TYPE.PACKET then
|
if msg ~= nil and msg.qtype == mqueue.TYPE.PACKET then
|
||||||
self.modem.transmit(session.r_port, session.l_port, msg.message.raw_sendable())
|
self.modem.transmit(session.r_port, session.l_port, msg.message.raw_sendable())
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -52,6 +53,7 @@ local function _iterate(sessions)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- cleanly close a session
|
-- cleanly close a session
|
||||||
|
---@param session plc_session_struct
|
||||||
local function _shutdown(session)
|
local function _shutdown(session)
|
||||||
session.open = false
|
session.open = false
|
||||||
session.instance.close()
|
session.instance.close()
|
||||||
@@ -59,7 +61,7 @@ local function _shutdown(session)
|
|||||||
-- send packets in out queue (namely the close packet)
|
-- send packets in out queue (namely the close packet)
|
||||||
while session.out_queue.ready() do
|
while session.out_queue.ready() do
|
||||||
local msg = session.out_queue.pop()
|
local msg = session.out_queue.pop()
|
||||||
if msg.qtype == mqueue.TYPE.PACKET then
|
if msg ~= nil and msg.qtype == mqueue.TYPE.PACKET then
|
||||||
self.modem.transmit(session.r_port, session.l_port, msg.message.raw_sendable())
|
self.modem.transmit(session.r_port, session.l_port, msg.message.raw_sendable())
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -68,9 +70,10 @@ local function _shutdown(session)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- close connections
|
-- close connections
|
||||||
|
---@param sessions table
|
||||||
local function _close(sessions)
|
local function _close(sessions)
|
||||||
for i = 1, #sessions do
|
for i = 1, #sessions do
|
||||||
local session = sessions[i]
|
local session = sessions[i] ---@type plc_session_struct
|
||||||
if session.open then
|
if session.open then
|
||||||
_shutdown(session)
|
_shutdown(session)
|
||||||
end
|
end
|
||||||
@@ -78,9 +81,11 @@ local function _close(sessions)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- check if a watchdog timer event matches that of one of the provided sessions
|
-- check if a watchdog timer event matches that of one of the provided sessions
|
||||||
|
---@param sessions table
|
||||||
|
---@param timer_event number
|
||||||
local function _check_watchdogs(sessions, timer_event)
|
local function _check_watchdogs(sessions, timer_event)
|
||||||
for i = 1, #sessions do
|
for i = 1, #sessions do
|
||||||
local session = sessions[i]
|
local session = sessions[i] ---@type plc_session_struct
|
||||||
if session.open then
|
if session.open then
|
||||||
local triggered = session.instance.check_wd(timer_event)
|
local triggered = session.instance.check_wd(timer_event)
|
||||||
if triggered then
|
if triggered then
|
||||||
@@ -92,10 +97,11 @@ local function _check_watchdogs(sessions, timer_event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- delete any closed sessions
|
-- delete any closed sessions
|
||||||
|
---@param sessions table
|
||||||
local function _free_closed(sessions)
|
local function _free_closed(sessions)
|
||||||
local move_to = 1
|
local move_to = 1
|
||||||
for i = 1, #sessions do
|
for i = 1, #sessions do
|
||||||
local session = sessions[i]
|
local session = sessions[i] ---@type plc_session_struct
|
||||||
if session ~= nil then
|
if session ~= nil then
|
||||||
if session.open then
|
if session.open then
|
||||||
if sessions[move_to] == nil then
|
if sessions[move_to] == nil then
|
||||||
@@ -113,11 +119,15 @@ end
|
|||||||
|
|
||||||
-- PUBLIC FUNCTIONS --
|
-- PUBLIC FUNCTIONS --
|
||||||
|
|
||||||
|
-- link the modem
|
||||||
|
---@param modem table
|
||||||
svsessions.link_modem = function (modem)
|
svsessions.link_modem = function (modem)
|
||||||
self.modem = modem
|
self.modem = modem
|
||||||
end
|
end
|
||||||
|
|
||||||
-- find a session by the remote port
|
-- find a session by the remote port
|
||||||
|
---@param remote_port integer
|
||||||
|
---@return plc_session_struct|nil
|
||||||
svsessions.find_session = function (remote_port)
|
svsessions.find_session = function (remote_port)
|
||||||
-- check RTU sessions
|
-- check RTU sessions
|
||||||
for i = 1, #self.rtu_sessions do
|
for i = 1, #self.rtu_sessions do
|
||||||
@@ -144,6 +154,8 @@ svsessions.find_session = function (remote_port)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get a session by reactor ID
|
-- get a session by reactor ID
|
||||||
|
---@param reactor integer
|
||||||
|
---@return plc_session_struct session
|
||||||
svsessions.get_reactor_session = function (reactor)
|
svsessions.get_reactor_session = function (reactor)
|
||||||
local session = nil
|
local session = nil
|
||||||
|
|
||||||
@@ -157,8 +169,13 @@ svsessions.get_reactor_session = function (reactor)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- establish a new PLC session
|
-- establish a new PLC session
|
||||||
|
---@param local_port integer
|
||||||
|
---@param remote_port integer
|
||||||
|
---@param for_reactor integer
|
||||||
|
---@return integer|false session_id
|
||||||
svsessions.establish_plc_session = function (local_port, remote_port, for_reactor)
|
svsessions.establish_plc_session = function (local_port, remote_port, for_reactor)
|
||||||
if svsessions.get_reactor_session(for_reactor) == nil then
|
if svsessions.get_reactor_session(for_reactor) == nil then
|
||||||
|
---@class plc_session_struct
|
||||||
local plc_s = {
|
local plc_s = {
|
||||||
open = true,
|
open = true,
|
||||||
reactor = for_reactor,
|
reactor = for_reactor,
|
||||||
@@ -185,6 +202,7 @@ svsessions.establish_plc_session = function (local_port, remote_port, for_reacto
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- attempt to identify which session's watchdog timer fired
|
-- attempt to identify which session's watchdog timer fired
|
||||||
|
---@param timer_event number
|
||||||
svsessions.check_all_watchdogs = function (timer_event)
|
svsessions.check_all_watchdogs = function (timer_event)
|
||||||
-- check RTU session watchdogs
|
-- check RTU session watchdogs
|
||||||
_check_watchdogs(self.rtu_sessions, timer_event)
|
_check_watchdogs(self.rtu_sessions, timer_event)
|
||||||
|
|||||||
@@ -6,15 +6,12 @@ local log = require("scada-common.log")
|
|||||||
local ppm = require("scada-common.ppm")
|
local ppm = require("scada-common.ppm")
|
||||||
local util = require("scada-common.util")
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
local coordinator = require("supervisor.session.coordinator")
|
|
||||||
local plc = require("supervisor.session.plc")
|
|
||||||
local rtu = require("supervisor.session.rtu")
|
|
||||||
local svsessions = require("supervisor.session.svsessions")
|
local svsessions = require("supervisor.session.svsessions")
|
||||||
|
|
||||||
local config = require("supervisor.config")
|
local config = require("supervisor.config")
|
||||||
local supervisor = require("supervisor.supervisor")
|
local supervisor = require("supervisor.supervisor")
|
||||||
|
|
||||||
local SUPERVISOR_VERSION = "alpha-v0.3.4"
|
local SUPERVISOR_VERSION = "alpha-v0.3.5"
|
||||||
|
|
||||||
local print = util.print
|
local print = util.print
|
||||||
local println = util.println
|
local println = util.println
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ local print_ts = util.print_ts
|
|||||||
local println_ts = util.println_ts
|
local println_ts = util.println_ts
|
||||||
|
|
||||||
-- supervisory controller communications
|
-- supervisory controller communications
|
||||||
|
---@param num_reactors integer
|
||||||
|
---@param modem table
|
||||||
|
---@param dev_listen integer
|
||||||
|
---@param coord_listen integer
|
||||||
supervisor.comms = function (num_reactors, modem, dev_listen, coord_listen)
|
supervisor.comms = function (num_reactors, modem, dev_listen, coord_listen)
|
||||||
local self = {
|
local self = {
|
||||||
ln_seq_num = 0,
|
ln_seq_num = 0,
|
||||||
@@ -30,6 +34,9 @@ supervisor.comms = function (num_reactors, modem, dev_listen, coord_listen)
|
|||||||
reactor_struct_cache = nil
|
reactor_struct_cache = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@class superv_comms
|
||||||
|
local public = {}
|
||||||
|
|
||||||
-- PRIVATE FUNCTIONS --
|
-- PRIVATE FUNCTIONS --
|
||||||
|
|
||||||
-- open all channels
|
-- open all channels
|
||||||
@@ -50,6 +57,8 @@ supervisor.comms = function (num_reactors, modem, dev_listen, coord_listen)
|
|||||||
svsessions.link_modem(self.modem)
|
svsessions.link_modem(self.modem)
|
||||||
|
|
||||||
-- send PLC link request responses
|
-- send PLC link request responses
|
||||||
|
---@param dest integer
|
||||||
|
---@param msg table
|
||||||
local _send_plc_linking = function (dest, msg)
|
local _send_plc_linking = function (dest, msg)
|
||||||
local s_pkt = comms.scada_packet()
|
local s_pkt = comms.scada_packet()
|
||||||
local r_pkt = comms.rplc_packet()
|
local r_pkt = comms.rplc_packet()
|
||||||
@@ -64,14 +73,22 @@ supervisor.comms = function (num_reactors, modem, dev_listen, coord_listen)
|
|||||||
-- PUBLIC FUNCTIONS --
|
-- PUBLIC FUNCTIONS --
|
||||||
|
|
||||||
-- reconnect a newly connected modem
|
-- reconnect a newly connected modem
|
||||||
local reconnect_modem = function (modem)
|
---@param modem table
|
||||||
|
---@diagnostic disable-next-line: redefined-local
|
||||||
|
public.reconnect_modem = function (modem)
|
||||||
self.modem = modem
|
self.modem = modem
|
||||||
svsessions.link_modem(self.modem)
|
svsessions.link_modem(self.modem)
|
||||||
_open_channels()
|
_open_channels()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- parse a packet
|
-- parse a packet
|
||||||
local parse_packet = function(side, sender, reply_to, message, distance)
|
---@param side string
|
||||||
|
---@param sender integer
|
||||||
|
---@param reply_to integer
|
||||||
|
---@param message any
|
||||||
|
---@param distance integer
|
||||||
|
---@return modbus_frame|rplc_frame|mgmt_frame|coord_frame|nil packet
|
||||||
|
public.parse_packet = function(side, sender, reply_to, message, distance)
|
||||||
local pkt = nil
|
local pkt = nil
|
||||||
local s_pkt = comms.scada_packet()
|
local s_pkt = comms.scada_packet()
|
||||||
|
|
||||||
@@ -111,7 +128,9 @@ supervisor.comms = function (num_reactors, modem, dev_listen, coord_listen)
|
|||||||
return pkt
|
return pkt
|
||||||
end
|
end
|
||||||
|
|
||||||
local handle_packet = function(packet)
|
-- handle a packet
|
||||||
|
---@param packet modbus_frame|rplc_frame|mgmt_frame|coord_frame
|
||||||
|
public.handle_packet = function(packet)
|
||||||
if packet ~= nil then
|
if packet ~= nil then
|
||||||
local l_port = packet.scada_frame.local_port()
|
local l_port = packet.scada_frame.local_port()
|
||||||
local r_port = packet.scada_frame.remote_port()
|
local r_port = packet.scada_frame.remote_port()
|
||||||
@@ -126,7 +145,7 @@ supervisor.comms = function (num_reactors, modem, dev_listen, coord_listen)
|
|||||||
-- MODBUS response
|
-- MODBUS response
|
||||||
elseif protocol == PROTOCOLS.RPLC then
|
elseif protocol == PROTOCOLS.RPLC then
|
||||||
-- reactor PLC packet
|
-- reactor PLC packet
|
||||||
if session then
|
if session ~= nil then
|
||||||
if packet.type == RPLC_TYPES.LINK_REQ then
|
if packet.type == RPLC_TYPES.LINK_REQ then
|
||||||
-- new device on this port? that's a collision
|
-- new device on this port? that's a collision
|
||||||
log.debug("PLC_LNK: request from existing connection received on " .. r_port .. ", responding with collision")
|
log.debug("PLC_LNK: request from existing connection received on " .. r_port .. ", responding with collision")
|
||||||
@@ -162,7 +181,7 @@ supervisor.comms = function (num_reactors, modem, dev_listen, coord_listen)
|
|||||||
end
|
end
|
||||||
elseif protocol == PROTOCOLS.SCADA_MGMT then
|
elseif protocol == PROTOCOLS.SCADA_MGMT then
|
||||||
-- SCADA management packet
|
-- SCADA management packet
|
||||||
if session then
|
if session ~= nil then
|
||||||
-- pass the packet onto the session handler
|
-- pass the packet onto the session handler
|
||||||
session.in_queue.push_packet(packet)
|
session.in_queue.push_packet(packet)
|
||||||
end
|
end
|
||||||
@@ -184,11 +203,7 @@ supervisor.comms = function (num_reactors, modem, dev_listen, coord_listen)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return public
|
||||||
reconnect_modem = reconnect_modem,
|
|
||||||
parse_packet = parse_packet,
|
|
||||||
handle_packet = handle_packet
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return supervisor
|
return supervisor
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
local unit = {}
|
local unit = {}
|
||||||
|
|
||||||
|
-- create a new reactor unit
|
||||||
|
---@param for_reactor integer
|
||||||
unit.new = function (for_reactor)
|
unit.new = function (for_reactor)
|
||||||
local public = {}
|
|
||||||
|
|
||||||
local self = {
|
local self = {
|
||||||
r_id = for_reactor,
|
r_id = for_reactor,
|
||||||
plc_s = nil,
|
plc_s = nil,
|
||||||
@@ -11,6 +11,7 @@ unit.new = function (for_reactor)
|
|||||||
energy_storage = {},
|
energy_storage = {},
|
||||||
redstone = {},
|
redstone = {},
|
||||||
db = {
|
db = {
|
||||||
|
---@class annunciator
|
||||||
annunciator = {
|
annunciator = {
|
||||||
-- RPS
|
-- RPS
|
||||||
-- reactor
|
-- reactor
|
||||||
@@ -37,18 +38,36 @@ unit.new = function (for_reactor)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@class reactor_unit
|
||||||
|
local public = {}
|
||||||
|
|
||||||
|
-- PRIVATE FUNCTIONS --
|
||||||
|
|
||||||
|
-- update the annunciator
|
||||||
|
local _update_annunciator = function ()
|
||||||
|
self.db.annunciator.PLCOnline = (self.plc_s ~= nil) and (self.plc_s.open)
|
||||||
|
self.db.annunciator.ReactorTrip = false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- PUBLIC FUNCTIONS --
|
||||||
|
|
||||||
|
-- link the PLC
|
||||||
|
---@param plc_session plc_session_struct
|
||||||
public.link_plc_session = function (plc_session)
|
public.link_plc_session = function (plc_session)
|
||||||
self.plc_s = plc_session
|
self.plc_s = plc_session
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- link a turbine RTU
|
||||||
public.add_turbine = function (turbine)
|
public.add_turbine = function (turbine)
|
||||||
table.insert(self.turbines, turbine)
|
table.insert(self.turbines, turbine)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- link a boiler RTU
|
||||||
public.add_boiler = function (boiler)
|
public.add_boiler = function (boiler)
|
||||||
table.insert(self.boilers, boiler)
|
table.insert(self.boilers, boiler)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- link a redstone RTU capability
|
||||||
public.add_redstone = function (field, accessor)
|
public.add_redstone = function (field, accessor)
|
||||||
-- ensure field exists
|
-- ensure field exists
|
||||||
if self.redstone[field] == nil then
|
if self.redstone[field] == nil then
|
||||||
@@ -59,11 +78,7 @@ unit.new = function (for_reactor)
|
|||||||
table.insert(self.redstone[field], accessor)
|
table.insert(self.redstone[field], accessor)
|
||||||
end
|
end
|
||||||
|
|
||||||
local _update_annunciator = function ()
|
-- update (iterate) this session
|
||||||
self.db.annunciator.PLCOnline = (self.plc_s ~= nil) and (self.plc_s.open)
|
|
||||||
self.db.annunciator.ReactorTrip = false
|
|
||||||
end
|
|
||||||
|
|
||||||
public.update = function ()
|
public.update = function ()
|
||||||
-- unlink PLC if session was closed
|
-- unlink PLC if session was closed
|
||||||
if not self.plc_s.open then
|
if not self.plc_s.open then
|
||||||
@@ -74,6 +89,7 @@ unit.new = function (for_reactor)
|
|||||||
_update_annunciator()
|
_update_annunciator()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- get the annunciator status
|
||||||
public.get_annunciator = function () return self.db.annunciator end
|
public.get_annunciator = function () return self.db.annunciator end
|
||||||
|
|
||||||
return public
|
return public
|
||||||
|
|||||||
Reference in New Issue
Block a user