#64 supervisor code cleanup
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
local comms = require("scada-common.comms")
|
local comms = require("scada-common.comms")
|
||||||
local log = require("scada-common.log")
|
local log = require("scada-common.log")
|
||||||
local mqueue = require("scada-common.mqueue")
|
local mqueue = require("scada-common.mqueue")
|
||||||
local util = require("scada-common.util")
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
local plc = {}
|
local plc = {}
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ local PERIODICS = {
|
|||||||
---@param for_reactor integer
|
---@param for_reactor integer
|
||||||
---@param in_queue mqueue
|
---@param in_queue mqueue
|
||||||
---@param out_queue mqueue
|
---@param out_queue mqueue
|
||||||
plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
function plc.new_session(id, for_reactor, in_queue, out_queue)
|
||||||
local log_header = "plc_session(" .. id .. "): "
|
local log_header = "plc_session(" .. id .. "): "
|
||||||
|
|
||||||
local self = {
|
local self = {
|
||||||
@@ -146,7 +146,7 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
|
|
||||||
-- copy in the RPS status
|
-- copy in the RPS status
|
||||||
---@param rps_status table
|
---@param rps_status table
|
||||||
local _copy_rps_status = function (rps_status)
|
local function _copy_rps_status(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]
|
||||||
self.sDB.rps_status.ex_waste = rps_status[3]
|
self.sDB.rps_status.ex_waste = rps_status[3]
|
||||||
@@ -158,7 +158,7 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
|
|
||||||
-- copy in the reactor status
|
-- copy in the reactor status
|
||||||
---@param mek_data table
|
---@param mek_data table
|
||||||
local _copy_status = function (mek_data)
|
local function _copy_status(mek_data)
|
||||||
-- copy status information
|
-- copy status information
|
||||||
self.sDB.mek_status.status = mek_data[1]
|
self.sDB.mek_status.status = mek_data[1]
|
||||||
self.sDB.mek_status.burn_rate = mek_data[2]
|
self.sDB.mek_status.burn_rate = mek_data[2]
|
||||||
@@ -191,7 +191,7 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
|
|
||||||
-- copy in the reactor structure
|
-- copy in the reactor structure
|
||||||
---@param mek_data table
|
---@param mek_data table
|
||||||
local _copy_struct = function (mek_data)
|
local function _copy_struct(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]
|
||||||
self.sDB.mek_struct.fuel_sa = mek_data[3]
|
self.sDB.mek_struct.fuel_sa = mek_data[3]
|
||||||
@@ -203,7 +203,7 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- mark this PLC session as closed, stop watchdog
|
-- mark this PLC session as closed, stop watchdog
|
||||||
local _close = function ()
|
local function _close()
|
||||||
self.plc_conn_watchdog.cancel()
|
self.plc_conn_watchdog.cancel()
|
||||||
self.connected = false
|
self.connected = false
|
||||||
end
|
end
|
||||||
@@ -211,7 +211,7 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
-- send an RPLC packet
|
-- send an RPLC packet
|
||||||
---@param msg_type RPLC_TYPES
|
---@param msg_type RPLC_TYPES
|
||||||
---@param msg table
|
---@param msg table
|
||||||
local _send = function (msg_type, msg)
|
local function _send(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()
|
||||||
|
|
||||||
@@ -225,7 +225,7 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
-- send a SCADA management packet
|
-- send a SCADA management packet
|
||||||
---@param msg_type SCADA_MGMT_TYPES
|
---@param msg_type SCADA_MGMT_TYPES
|
||||||
---@param msg table
|
---@param msg table
|
||||||
local _send_mgmt = function (msg_type, msg)
|
local function _send_mgmt(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()
|
||||||
|
|
||||||
@@ -239,7 +239,7 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
-- get an ACK status
|
-- get an ACK status
|
||||||
---@param pkt rplc_frame
|
---@param pkt rplc_frame
|
||||||
---@return boolean|nil ack
|
---@return boolean|nil ack
|
||||||
local _get_ack = function (pkt)
|
local function _get_ack(pkt)
|
||||||
if pkt.length == 1 then
|
if pkt.length == 1 then
|
||||||
return pkt.data[1]
|
return pkt.data[1]
|
||||||
else
|
else
|
||||||
@@ -250,7 +250,7 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
|
|
||||||
-- handle a packet
|
-- handle a packet
|
||||||
---@param pkt rplc_frame
|
---@param pkt rplc_frame
|
||||||
local _handle_packet = function (pkt)
|
local function _handle_packet(pkt)
|
||||||
-- check sequence number
|
-- check sequence number
|
||||||
if self.r_seq_num == nil then
|
if self.r_seq_num == nil then
|
||||||
self.r_seq_num = pkt.scada_frame.seq_num()
|
self.r_seq_num = pkt.scada_frame.seq_num()
|
||||||
@@ -408,13 +408,13 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
-- PUBLIC FUNCTIONS --
|
-- PUBLIC FUNCTIONS --
|
||||||
|
|
||||||
-- get the session ID
|
-- get the session ID
|
||||||
public.get_id = function () return self.id end
|
function public.get_id() return self.id end
|
||||||
|
|
||||||
-- get the session database
|
-- get the session database
|
||||||
public.get_db = function () return self.sDB end
|
function public.get_db() return self.sDB end
|
||||||
|
|
||||||
-- get the reactor structure
|
-- get the reactor structure
|
||||||
public.get_struct = function ()
|
function public.get_struct()
|
||||||
if self.received_struct then
|
if self.received_struct then
|
||||||
return self.sDB.mek_struct
|
return self.sDB.mek_struct
|
||||||
else
|
else
|
||||||
@@ -423,7 +423,7 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get the reactor status
|
-- get the reactor status
|
||||||
public.get_status = function ()
|
function public.get_status()
|
||||||
if self.received_status_cache then
|
if self.received_status_cache then
|
||||||
return self.sDB.mek_status
|
return self.sDB.mek_status
|
||||||
else
|
else
|
||||||
@@ -432,12 +432,12 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get the reactor RPS status
|
-- get the reactor RPS status
|
||||||
public.get_rps = function ()
|
function public.get_rps()
|
||||||
return self.sDB.rps_status
|
return self.sDB.rps_status
|
||||||
end
|
end
|
||||||
|
|
||||||
-- get the general status information
|
-- get the general status information
|
||||||
public.get_general_status = function ()
|
function public.get_general_status()
|
||||||
return {
|
return {
|
||||||
last_status_update = self.sDB.last_status_update,
|
last_status_update = self.sDB.last_status_update,
|
||||||
control_state = self.sDB.control_state,
|
control_state = self.sDB.control_state,
|
||||||
@@ -449,12 +449,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
|
||||||
public.check_wd = function (timer)
|
function public.check_wd(timer)
|
||||||
return self.plc_conn_watchdog.is_timer(timer) and self.connected
|
return self.plc_conn_watchdog.is_timer(timer) and self.connected
|
||||||
end
|
end
|
||||||
|
|
||||||
-- close the connection
|
-- close the connection
|
||||||
public.close = function ()
|
function public.close()
|
||||||
_close()
|
_close()
|
||||||
_send_mgmt(SCADA_MGMT_TYPES.CLOSE, {})
|
_send_mgmt(SCADA_MGMT_TYPES.CLOSE, {})
|
||||||
println("connection to reactor " .. self.for_reactor .. " PLC closed by server")
|
println("connection to reactor " .. self.for_reactor .. " PLC closed by server")
|
||||||
@@ -463,7 +463,7 @@ plc.new_session = function (id, for_reactor, in_queue, out_queue)
|
|||||||
|
|
||||||
-- iterate the session
|
-- iterate the session
|
||||||
---@return boolean connected
|
---@return boolean connected
|
||||||
public.iterate = function ()
|
function public.iterate()
|
||||||
if self.connected then
|
if self.connected then
|
||||||
------------------
|
------------------
|
||||||
-- handle queue --
|
-- handle queue --
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
local comms = require("scada-common.comms")
|
local comms = require("scada-common.comms")
|
||||||
local log = require("scada-common.log")
|
local log = require("scada-common.log")
|
||||||
local mqueue = require("scada-common.mqueue")
|
local mqueue = require("scada-common.mqueue")
|
||||||
local rsio = require("scada-common.rsio")
|
local rsio = require("scada-common.rsio")
|
||||||
local util = require("scada-common.util")
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
-- supervisor rtu sessions (svrs)
|
-- supervisor rtu sessions (svrs)
|
||||||
local svrs_boiler = require("supervisor.session.rtu.boiler")
|
local svrs_boiler = require("supervisor.session.rtu.boiler")
|
||||||
local svrs_emachine = require("supervisor.session.rtu.emachine")
|
local svrs_emachine = require("supervisor.session.rtu.emachine")
|
||||||
local svrs_redstone = require("supervisor.session.rtu.redstone")
|
local svrs_redstone = require("supervisor.session.rtu.redstone")
|
||||||
local svrs_turbine = require("supervisor.session.rtu.turbine")
|
local svrs_turbine = require("supervisor.session.rtu.turbine")
|
||||||
|
|
||||||
local rtu = {}
|
local rtu = {}
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ local PERIODICS = {
|
|||||||
---@param in_queue mqueue
|
---@param in_queue mqueue
|
||||||
---@param out_queue mqueue
|
---@param out_queue mqueue
|
||||||
---@param advertisement table
|
---@param advertisement table
|
||||||
rtu.new_session = function (id, in_queue, out_queue, advertisement)
|
function rtu.new_session(id, in_queue, out_queue, advertisement)
|
||||||
local log_header = "rtu_session(" .. id .. "): "
|
local log_header = "rtu_session(" .. id .. "): "
|
||||||
|
|
||||||
local self = {
|
local self = {
|
||||||
@@ -68,7 +68,7 @@ rtu.new_session = function (id, in_queue, out_queue, advertisement)
|
|||||||
local public = {}
|
local public = {}
|
||||||
|
|
||||||
-- parse the recorded advertisement and create unit sub-sessions
|
-- parse the recorded advertisement and create unit sub-sessions
|
||||||
local _handle_advertisement = function ()
|
local function _handle_advertisement()
|
||||||
self.units = {}
|
self.units = {}
|
||||||
self.rs_io_q = {}
|
self.rs_io_q = {}
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ rtu.new_session = function (id, in_queue, out_queue, advertisement)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- mark this RTU session as closed, stop watchdog
|
-- mark this RTU session as closed, stop watchdog
|
||||||
local _close = function ()
|
local function _close()
|
||||||
self.rtu_conn_watchdog.cancel()
|
self.rtu_conn_watchdog.cancel()
|
||||||
self.connected = false
|
self.connected = false
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ rtu.new_session = function (id, in_queue, out_queue, advertisement)
|
|||||||
-- send a SCADA management packet
|
-- send a SCADA management packet
|
||||||
---@param msg_type SCADA_MGMT_TYPES
|
---@param msg_type SCADA_MGMT_TYPES
|
||||||
---@param msg table
|
---@param msg table
|
||||||
local _send_mgmt = function (msg_type, msg)
|
local function _send_mgmt(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()
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ rtu.new_session = function (id, in_queue, out_queue, advertisement)
|
|||||||
|
|
||||||
-- handle a packet
|
-- handle a packet
|
||||||
---@param pkt modbus_frame|mgmt_frame
|
---@param pkt modbus_frame|mgmt_frame
|
||||||
local _handle_packet = function (pkt)
|
local function _handle_packet(pkt)
|
||||||
-- check sequence number
|
-- check sequence number
|
||||||
if self.r_seq_num == nil then
|
if self.r_seq_num == nil then
|
||||||
self.r_seq_num = pkt.scada_frame.seq_num()
|
self.r_seq_num = pkt.scada_frame.seq_num()
|
||||||
@@ -212,16 +212,16 @@ rtu.new_session = function (id, in_queue, out_queue, advertisement)
|
|||||||
-- PUBLIC FUNCTIONS --
|
-- PUBLIC FUNCTIONS --
|
||||||
|
|
||||||
-- get the session ID
|
-- get the session ID
|
||||||
public.get_id = function () return self.id end
|
function public.get_id() return self.id end
|
||||||
|
|
||||||
-- check if a timer matches this session's watchdog
|
-- check if a timer matches this session's watchdog
|
||||||
---@param timer number
|
---@param timer number
|
||||||
public.check_wd = function (timer)
|
function public.check_wd(timer)
|
||||||
return self.rtu_conn_watchdog.is_timer(timer) and self.connected
|
return self.rtu_conn_watchdog.is_timer(timer) and self.connected
|
||||||
end
|
end
|
||||||
|
|
||||||
-- close the connection
|
-- close the connection
|
||||||
public.close = function ()
|
function public.close()
|
||||||
_close()
|
_close()
|
||||||
_send_mgmt(SCADA_MGMT_TYPES.CLOSE, {})
|
_send_mgmt(SCADA_MGMT_TYPES.CLOSE, {})
|
||||||
println(log_header .. "connection to RTU closed by server")
|
println(log_header .. "connection to RTU closed by server")
|
||||||
@@ -230,7 +230,7 @@ rtu.new_session = function (id, in_queue, out_queue, advertisement)
|
|||||||
|
|
||||||
-- iterate the session
|
-- iterate the session
|
||||||
---@return boolean connected
|
---@return boolean connected
|
||||||
public.iterate = function ()
|
function public.iterate()
|
||||||
if self.connected then
|
if self.connected then
|
||||||
------------------
|
------------------
|
||||||
-- handle queue --
|
-- handle queue --
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
local comms = require("scada-common.comms")
|
local comms = require("scada-common.comms")
|
||||||
local log = require("scada-common.log")
|
local log = require("scada-common.log")
|
||||||
local types = require("scada-common.types")
|
local types = require("scada-common.types")
|
||||||
|
|
||||||
local unit_session = require("supervisor.session.rtu.unit_session")
|
local unit_session = require("supervisor.session.rtu.unit_session")
|
||||||
@@ -32,7 +32,7 @@ local PERIODICS = {
|
|||||||
---@param unit_id integer
|
---@param unit_id integer
|
||||||
---@param advert rtu_advertisement
|
---@param advert rtu_advertisement
|
||||||
---@param out_queue mqueue
|
---@param out_queue mqueue
|
||||||
boiler.new = function (session_id, unit_id, advert, out_queue)
|
function boiler.new(session_id, unit_id, advert, out_queue)
|
||||||
-- type check
|
-- type check
|
||||||
if advert.type ~= RTU_UNIT_TYPES.BOILER then
|
if advert.type ~= RTU_UNIT_TYPES.BOILER then
|
||||||
log.error("attempt to instantiate boiler RTU for type '" .. advert.type .. "'. this is a bug.")
|
log.error("attempt to instantiate boiler RTU for type '" .. advert.type .. "'. this is a bug.")
|
||||||
@@ -86,19 +86,19 @@ boiler.new = function (session_id, unit_id, advert, out_queue)
|
|||||||
-- PRIVATE FUNCTIONS --
|
-- PRIVATE FUNCTIONS --
|
||||||
|
|
||||||
-- query the build of the device
|
-- query the build of the device
|
||||||
local _request_build = function ()
|
local function _request_build()
|
||||||
-- read input registers 1 through 7 (start = 1, count = 7)
|
-- read input registers 1 through 7 (start = 1, count = 7)
|
||||||
self.session.send_request(TXN_TYPES.BUILD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 7 })
|
self.session.send_request(TXN_TYPES.BUILD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 7 })
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the state of the device
|
-- query the state of the device
|
||||||
local _request_state = function ()
|
local function _request_state()
|
||||||
-- read input registers 8 through 9 (start = 8, count = 2)
|
-- read input registers 8 through 9 (start = 8, count = 2)
|
||||||
self.session.send_request(TXN_TYPES.STATE, MODBUS_FCODE.READ_INPUT_REGS, { 8, 2 })
|
self.session.send_request(TXN_TYPES.STATE, MODBUS_FCODE.READ_INPUT_REGS, { 8, 2 })
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the tanks of the device
|
-- query the tanks of the device
|
||||||
local _request_tanks = function ()
|
local function _request_tanks()
|
||||||
-- read input registers 10 through 21 (start = 10, count = 12)
|
-- read input registers 10 through 21 (start = 10, count = 12)
|
||||||
self.session.send_request(TXN_TYPES.TANKS, MODBUS_FCODE.READ_INPUT_REGS, { 10, 12 })
|
self.session.send_request(TXN_TYPES.TANKS, MODBUS_FCODE.READ_INPUT_REGS, { 10, 12 })
|
||||||
end
|
end
|
||||||
@@ -107,7 +107,7 @@ boiler.new = function (session_id, unit_id, advert, out_queue)
|
|||||||
|
|
||||||
-- handle a packet
|
-- handle a packet
|
||||||
---@param m_pkt modbus_frame
|
---@param m_pkt modbus_frame
|
||||||
public.handle_packet = function (m_pkt)
|
function public.handle_packet(m_pkt)
|
||||||
local txn_type = self.session.try_resolve(m_pkt.txn_id)
|
local txn_type = self.session.try_resolve(m_pkt.txn_id)
|
||||||
if txn_type == false then
|
if txn_type == false then
|
||||||
-- nothing to do
|
-- nothing to do
|
||||||
@@ -162,7 +162,7 @@ boiler.new = function (session_id, unit_id, advert, out_queue)
|
|||||||
|
|
||||||
-- update this runner
|
-- update this runner
|
||||||
---@param time_now integer milliseconds
|
---@param time_now integer milliseconds
|
||||||
public.update = function (time_now)
|
function public.update(time_now)
|
||||||
if not self.periodics.has_build and self.periodics.next_build_req <= time_now then
|
if not self.periodics.has_build and self.periodics.next_build_req <= time_now then
|
||||||
_request_build()
|
_request_build()
|
||||||
self.periodics.next_build_req = time_now + PERIODICS.BUILD
|
self.periodics.next_build_req = time_now + PERIODICS.BUILD
|
||||||
@@ -180,7 +180,7 @@ boiler.new = function (session_id, unit_id, advert, out_queue)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get the unit session database
|
-- get the unit session database
|
||||||
public.get_db = function () return self.db end
|
function public.get_db() return self.db end
|
||||||
|
|
||||||
return public
|
return public
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
local comms = require("scada-common.comms")
|
local comms = require("scada-common.comms")
|
||||||
local log = require("scada-common.log")
|
local log = require("scada-common.log")
|
||||||
local types = require("scada-common.types")
|
local types = require("scada-common.types")
|
||||||
|
|
||||||
local unit_session = require("supervisor.session.rtu.unit_session")
|
local unit_session = require("supervisor.session.rtu.unit_session")
|
||||||
@@ -29,7 +29,7 @@ local PERIODICS = {
|
|||||||
---@param unit_id integer
|
---@param unit_id integer
|
||||||
---@param advert rtu_advertisement
|
---@param advert rtu_advertisement
|
||||||
---@param out_queue mqueue
|
---@param out_queue mqueue
|
||||||
emachine.new = function (session_id, unit_id, advert, out_queue)
|
function emachine.new(session_id, unit_id, advert, out_queue)
|
||||||
-- type check
|
-- type check
|
||||||
if advert.type ~= RTU_UNIT_TYPES.EMACHINE then
|
if advert.type ~= RTU_UNIT_TYPES.EMACHINE then
|
||||||
log.error("attempt to instantiate emachine RTU for type '" .. advert.type .. "'. this is a bug.")
|
log.error("attempt to instantiate emachine RTU for type '" .. advert.type .. "'. this is a bug.")
|
||||||
@@ -63,13 +63,13 @@ emachine.new = function (session_id, unit_id, advert, out_queue)
|
|||||||
-- PRIVATE FUNCTIONS --
|
-- PRIVATE FUNCTIONS --
|
||||||
|
|
||||||
-- query the build of the device
|
-- query the build of the device
|
||||||
local _request_build = function ()
|
local function _request_build()
|
||||||
-- read input register 1 (start = 1, count = 1)
|
-- read input register 1 (start = 1, count = 1)
|
||||||
self.session.send_request(TXN_TYPES.BUILD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 1 })
|
self.session.send_request(TXN_TYPES.BUILD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 1 })
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the state of the energy storage
|
-- query the state of the energy storage
|
||||||
local _request_storage = function ()
|
local function _request_storage()
|
||||||
-- read input registers 2 through 4 (start = 2, count = 3)
|
-- read input registers 2 through 4 (start = 2, count = 3)
|
||||||
self.session.send_request(TXN_TYPES.STORAGE, MODBUS_FCODE.READ_INPUT_REGS, { 2, 3 })
|
self.session.send_request(TXN_TYPES.STORAGE, MODBUS_FCODE.READ_INPUT_REGS, { 2, 3 })
|
||||||
end
|
end
|
||||||
@@ -78,7 +78,7 @@ emachine.new = function (session_id, unit_id, advert, out_queue)
|
|||||||
|
|
||||||
-- handle a packet
|
-- handle a packet
|
||||||
---@param m_pkt modbus_frame
|
---@param m_pkt modbus_frame
|
||||||
public.handle_packet = function (m_pkt)
|
function public.handle_packet(m_pkt)
|
||||||
local txn_type = self.session.try_resolve(m_pkt.txn_id)
|
local txn_type = self.session.try_resolve(m_pkt.txn_id)
|
||||||
if txn_type == false then
|
if txn_type == false then
|
||||||
-- nothing to do
|
-- nothing to do
|
||||||
@@ -107,7 +107,7 @@ emachine.new = function (session_id, unit_id, advert, out_queue)
|
|||||||
|
|
||||||
-- update this runner
|
-- update this runner
|
||||||
---@param time_now integer milliseconds
|
---@param time_now integer milliseconds
|
||||||
public.update = function (time_now)
|
function public.update(time_now)
|
||||||
if not self.has_build and self.periodics.next_build_req <= time_now then
|
if not self.has_build and self.periodics.next_build_req <= time_now then
|
||||||
_request_build()
|
_request_build()
|
||||||
self.periodics.next_build_req = time_now + PERIODICS.BUILD
|
self.periodics.next_build_req = time_now + PERIODICS.BUILD
|
||||||
@@ -120,7 +120,7 @@ emachine.new = function (session_id, unit_id, advert, out_queue)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get the unit session database
|
-- get the unit session database
|
||||||
public.get_db = function () return self.db end
|
function public.get_db() return self.db end
|
||||||
|
|
||||||
return public
|
return public
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
local comms = require("scada-common.comms")
|
local comms = require("scada-common.comms")
|
||||||
local log = require("scada-common.log")
|
local log = require("scada-common.log")
|
||||||
local mqueue= require("scada-common.mqueue")
|
local mqueue = require("scada-common.mqueue")
|
||||||
local rsio = require("scada-common.rsio")
|
local rsio = require("scada-common.rsio")
|
||||||
local types = require("scada-common.types")
|
local types = require("scada-common.types")
|
||||||
local util = require("scada-common.util")
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
local unit_session = require("supervisor.session.rtu.unit_session")
|
local unit_session = require("supervisor.session.rtu.unit_session")
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ local PERIODICS = {
|
|||||||
---@param unit_id integer
|
---@param unit_id integer
|
||||||
---@param advert rtu_advertisement
|
---@param advert rtu_advertisement
|
||||||
---@param out_queue mqueue
|
---@param out_queue mqueue
|
||||||
redstone.new = function (session_id, unit_id, advert, out_queue)
|
function redstone.new(session_id, unit_id, advert, out_queue)
|
||||||
-- type check
|
-- type check
|
||||||
if advert.type ~= RTU_UNIT_TYPES.REDSTONE then
|
if advert.type ~= RTU_UNIT_TYPES.REDSTONE then
|
||||||
log.error("attempt to instantiate redstone RTU for type '" .. advert.type .. "'. this is a bug.")
|
log.error("attempt to instantiate redstone RTU for type '" .. advert.type .. "'. this is a bug.")
|
||||||
@@ -113,22 +113,22 @@ redstone.new = function (session_id, unit_id, advert, out_queue)
|
|||||||
-- PRIVATE FUNCTIONS --
|
-- PRIVATE FUNCTIONS --
|
||||||
|
|
||||||
-- query discrete inputs
|
-- query discrete inputs
|
||||||
local _request_discrete_inputs = function ()
|
local function _request_discrete_inputs()
|
||||||
self.session.send_request(TXN_TYPES.DI_READ, MODBUS_FCODE.READ_DISCRETE_INPUTS, { 1, #self.io_list.digital_in })
|
self.session.send_request(TXN_TYPES.DI_READ, MODBUS_FCODE.READ_DISCRETE_INPUTS, { 1, #self.io_list.digital_in })
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query input registers
|
-- query input registers
|
||||||
local _request_input_registers = function ()
|
local function _request_input_registers()
|
||||||
self.session.send_request(TXN_TYPES.INPUT_REG_READ, MODBUS_FCODE.READ_INPUT_REGS, { 1, #self.io_list.analog_in })
|
self.session.send_request(TXN_TYPES.INPUT_REG_READ, MODBUS_FCODE.READ_INPUT_REGS, { 1, #self.io_list.analog_in })
|
||||||
end
|
end
|
||||||
|
|
||||||
-- write coil output
|
-- write coil output
|
||||||
local _write_coil = function (coil, value)
|
local function _write_coil(coil, value)
|
||||||
self.session.send_request(TXN_TYPES.COIL_WRITE, MODBUS_FCODE.WRITE_MUL_COILS, { coil, value })
|
self.session.send_request(TXN_TYPES.COIL_WRITE, MODBUS_FCODE.WRITE_MUL_COILS, { coil, value })
|
||||||
end
|
end
|
||||||
|
|
||||||
-- write holding register output
|
-- write holding register output
|
||||||
local _write_holding_register = function (reg, value)
|
local function _write_holding_register(reg, value)
|
||||||
self.session.send_request(TXN_TYPES.HOLD_REG_WRITE, MODBUS_FCODE.WRITE_MUL_HOLD_REGS, { reg, value })
|
self.session.send_request(TXN_TYPES.HOLD_REG_WRITE, MODBUS_FCODE.WRITE_MUL_HOLD_REGS, { reg, value })
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ redstone.new = function (session_id, unit_id, advert, out_queue)
|
|||||||
|
|
||||||
-- handle a packet
|
-- handle a packet
|
||||||
---@param m_pkt modbus_frame
|
---@param m_pkt modbus_frame
|
||||||
public.handle_packet = function (m_pkt)
|
function public.handle_packet(m_pkt)
|
||||||
local txn_type = self.session.try_resolve(m_pkt.txn_id)
|
local txn_type = self.session.try_resolve(m_pkt.txn_id)
|
||||||
if txn_type == false then
|
if txn_type == false then
|
||||||
-- nothing to do
|
-- nothing to do
|
||||||
@@ -173,7 +173,7 @@ redstone.new = function (session_id, unit_id, advert, out_queue)
|
|||||||
|
|
||||||
-- update this runner
|
-- update this runner
|
||||||
---@param time_now integer milliseconds
|
---@param time_now integer milliseconds
|
||||||
public.update = function (time_now)
|
function public.update(time_now)
|
||||||
-- check command queue
|
-- check command queue
|
||||||
while self.in_q.ready() do
|
while self.in_q.ready() do
|
||||||
-- get a new message to process
|
-- get a new message to process
|
||||||
@@ -246,7 +246,7 @@ redstone.new = function (session_id, unit_id, advert, out_queue)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get the unit session database
|
-- get the unit session database
|
||||||
public.get_db = function () return self.db end
|
function public.get_db() return self.db end
|
||||||
|
|
||||||
return public, self.in_q
|
return public, self.in_q
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
local comms = require("scada-common.comms")
|
local comms = require("scada-common.comms")
|
||||||
local log = require("scada-common.log")
|
local log = require("scada-common.log")
|
||||||
local types = require("scada-common.types")
|
local types = require("scada-common.types")
|
||||||
|
|
||||||
local unit_session = require("supervisor.session.rtu.unit_session")
|
local unit_session = require("supervisor.session.rtu.unit_session")
|
||||||
@@ -33,7 +33,7 @@ local PERIODICS = {
|
|||||||
---@param unit_id integer
|
---@param unit_id integer
|
||||||
---@param advert rtu_advertisement
|
---@param advert rtu_advertisement
|
||||||
---@param out_queue mqueue
|
---@param out_queue mqueue
|
||||||
turbine.new = function (session_id, unit_id, advert, out_queue)
|
function turbine.new(session_id, unit_id, advert, out_queue)
|
||||||
-- type check
|
-- type check
|
||||||
if advert.type ~= RTU_UNIT_TYPES.TURBINE then
|
if advert.type ~= RTU_UNIT_TYPES.TURBINE then
|
||||||
log.error("attempt to instantiate turbine RTU for type '" .. advert.type .. "'. this is a bug.")
|
log.error("attempt to instantiate turbine RTU for type '" .. advert.type .. "'. this is a bug.")
|
||||||
@@ -82,19 +82,19 @@ turbine.new = function (session_id, unit_id, advert, out_queue)
|
|||||||
-- PRIVATE FUNCTIONS --
|
-- PRIVATE FUNCTIONS --
|
||||||
|
|
||||||
-- query the build of the device
|
-- query the build of the device
|
||||||
local _request_build = function ()
|
local function _request_build()
|
||||||
-- read input registers 1 through 9 (start = 1, count = 9)
|
-- read input registers 1 through 9 (start = 1, count = 9)
|
||||||
self.session.send_request(TXN_TYPES.BUILD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 9 })
|
self.session.send_request(TXN_TYPES.BUILD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 9 })
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the state of the device
|
-- query the state of the device
|
||||||
local _request_state = function ()
|
local function _request_state()
|
||||||
-- read input registers 10 through 13 (start = 10, count = 4)
|
-- read input registers 10 through 13 (start = 10, count = 4)
|
||||||
self.session.send_request(TXN_TYPES.STATE, MODBUS_FCODE.READ_INPUT_REGS, { 10, 4 })
|
self.session.send_request(TXN_TYPES.STATE, MODBUS_FCODE.READ_INPUT_REGS, { 10, 4 })
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the tanks of the device
|
-- query the tanks of the device
|
||||||
local _request_tanks = function ()
|
local function _request_tanks()
|
||||||
-- read input registers 14 through 16 (start = 14, count = 3)
|
-- read input registers 14 through 16 (start = 14, count = 3)
|
||||||
self.session.send_request(TXN_TYPES.TANKS, MODBUS_FCODE.READ_INPUT_REGS, { 14, 3 })
|
self.session.send_request(TXN_TYPES.TANKS, MODBUS_FCODE.READ_INPUT_REGS, { 14, 3 })
|
||||||
end
|
end
|
||||||
@@ -103,7 +103,7 @@ turbine.new = function (session_id, unit_id, advert, out_queue)
|
|||||||
|
|
||||||
-- handle a packet
|
-- handle a packet
|
||||||
---@param m_pkt modbus_frame
|
---@param m_pkt modbus_frame
|
||||||
public.handle_packet = function (m_pkt)
|
function public.handle_packet(m_pkt)
|
||||||
local txn_type = self.session.try_resolve(m_pkt.txn_id)
|
local txn_type = self.session.try_resolve(m_pkt.txn_id)
|
||||||
if txn_type == false then
|
if txn_type == false then
|
||||||
-- nothing to do
|
-- nothing to do
|
||||||
@@ -150,7 +150,7 @@ turbine.new = function (session_id, unit_id, advert, out_queue)
|
|||||||
|
|
||||||
-- update this runner
|
-- update this runner
|
||||||
---@param time_now integer milliseconds
|
---@param time_now integer milliseconds
|
||||||
public.update = function (time_now)
|
function public.update(time_now)
|
||||||
if not self.has_build and self.periodics.next_build_req <= time_now then
|
if not self.has_build and self.periodics.next_build_req <= time_now then
|
||||||
_request_build()
|
_request_build()
|
||||||
self.periodics.next_build_req = time_now + PERIODICS.BUILD
|
self.periodics.next_build_req = time_now + PERIODICS.BUILD
|
||||||
@@ -168,7 +168,7 @@ turbine.new = function (session_id, unit_id, advert, out_queue)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get the unit session database
|
-- get the unit session database
|
||||||
public.get_db = function () return self.db end
|
function public.get_db() return self.db end
|
||||||
|
|
||||||
return public
|
return public
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ local txnctrl = {}
|
|||||||
local TIMEOUT = 2000 -- 2000ms max wait
|
local TIMEOUT = 2000 -- 2000ms max wait
|
||||||
|
|
||||||
-- create a new transaction controller
|
-- create a new transaction controller
|
||||||
txnctrl.new = function ()
|
function txnctrl.new()
|
||||||
local self = {
|
local self = {
|
||||||
list = {},
|
list = {},
|
||||||
next_id = 0
|
next_id = 0
|
||||||
@@ -21,19 +21,19 @@ txnctrl.new = function ()
|
|||||||
local insert = table.insert
|
local insert = table.insert
|
||||||
|
|
||||||
-- get the length of the transaction list
|
-- get the length of the transaction list
|
||||||
public.length = function ()
|
function public.length()
|
||||||
return #self.list
|
return #self.list
|
||||||
end
|
end
|
||||||
|
|
||||||
-- check if there are no active transactions
|
-- check if there are no active transactions
|
||||||
public.empty = function ()
|
function public.empty()
|
||||||
return #self.list == 0
|
return #self.list == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
-- create a new transaction of the given type
|
-- create a new transaction of the given type
|
||||||
---@param txn_type integer
|
---@param txn_type integer
|
||||||
---@return integer txn_id
|
---@return integer txn_id
|
||||||
public.create = function (txn_type)
|
function public.create(txn_type)
|
||||||
local txn_id = self.next_id
|
local txn_id = self.next_id
|
||||||
|
|
||||||
insert(self.list, {
|
insert(self.list, {
|
||||||
@@ -50,7 +50,7 @@ txnctrl.new = function ()
|
|||||||
-- mark a transaction as resolved to get its transaction type
|
-- mark a transaction as resolved to get its transaction type
|
||||||
---@param txn_id integer
|
---@param txn_id integer
|
||||||
---@return integer txn_type
|
---@return integer txn_type
|
||||||
public.resolve = function (txn_id)
|
function public.resolve(txn_id)
|
||||||
local txn_type = nil
|
local txn_type = nil
|
||||||
|
|
||||||
for i = 1, public.length() do
|
for i = 1, public.length() do
|
||||||
@@ -66,7 +66,7 @@ txnctrl.new = function ()
|
|||||||
-- renew a transaction by re-inserting it with its ID and type
|
-- renew a transaction by re-inserting it with its ID and type
|
||||||
---@param txn_id integer
|
---@param txn_id integer
|
||||||
---@param txn_type integer
|
---@param txn_type integer
|
||||||
public.renew = function (txn_id, txn_type)
|
function public.renew(txn_id, txn_type)
|
||||||
insert(self.list, {
|
insert(self.list, {
|
||||||
txn_id = txn_id,
|
txn_id = txn_id,
|
||||||
txn_type = txn_type,
|
txn_type = txn_type,
|
||||||
@@ -75,13 +75,13 @@ txnctrl.new = function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- close timed-out transactions
|
-- close timed-out transactions
|
||||||
public.cleanup = function ()
|
function public.cleanup()
|
||||||
local now = util.time()
|
local now = util.time()
|
||||||
util.filter_table(self.list, function (txn) return txn.expiry > now end)
|
util.filter_table(self.list, function (txn) return txn.expiry > now end)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- clear the transaction list
|
-- clear the transaction list
|
||||||
public.clear = function ()
|
function public.clear()
|
||||||
self.list = {}
|
self.list = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
local comms = require("scada-common.comms")
|
local comms = require("scada-common.comms")
|
||||||
local log = require("scada-common.log")
|
local log = require("scada-common.log")
|
||||||
local types = require("scada-common.types")
|
local types = require("scada-common.types")
|
||||||
|
|
||||||
local txnctrl = require("supervisor.session.rtu.txnctrl")
|
local txnctrl = require("supervisor.session.rtu.txnctrl")
|
||||||
@@ -16,7 +16,7 @@ local MODBUS_EXCODE = types.MODBUS_EXCODE
|
|||||||
---@param out_queue mqueue send queue
|
---@param out_queue mqueue send queue
|
||||||
---@param log_tag string logging tag
|
---@param log_tag string logging tag
|
||||||
---@param txn_tags table transaction log tags
|
---@param txn_tags table transaction log tags
|
||||||
unit_session.new = function (unit_id, advert, out_queue, log_tag, txn_tags)
|
function unit_session.new(unit_id, advert, out_queue, log_tag, txn_tags)
|
||||||
local self = {
|
local self = {
|
||||||
log_tag = log_tag,
|
log_tag = log_tag,
|
||||||
txn_tags = txn_tags,
|
txn_tags = txn_tags,
|
||||||
@@ -41,7 +41,7 @@ unit_session.new = function (unit_id, advert, out_queue, log_tag, txn_tags)
|
|||||||
---@param txn_type integer transaction type
|
---@param txn_type integer transaction type
|
||||||
---@param f_code MODBUS_FCODE function code
|
---@param f_code MODBUS_FCODE function code
|
||||||
---@param register_param table register range or register and values
|
---@param register_param table register range or register and values
|
||||||
protected.send_request = function (txn_type, f_code, register_param)
|
function protected.send_request(txn_type, f_code, register_param)
|
||||||
local m_pkt = comms.modbus_packet()
|
local m_pkt = comms.modbus_packet()
|
||||||
local txn_id = self.transaction_controller.create(txn_type)
|
local txn_id = self.transaction_controller.create(txn_type)
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ unit_session.new = function (unit_id, advert, out_queue, log_tag, txn_tags)
|
|||||||
-- try to resolve a MODBUS transaction
|
-- try to resolve a MODBUS transaction
|
||||||
---@param m_pkt modbus_frame MODBUS packet
|
---@param m_pkt modbus_frame MODBUS packet
|
||||||
---@return integer|false txn_type transaction type or false on error/busy
|
---@return integer|false txn_type transaction type or false on error/busy
|
||||||
protected.try_resolve = function (m_pkt)
|
function protected.try_resolve(m_pkt)
|
||||||
if m_pkt.scada_frame.protocol() == PROTOCOLS.MODBUS_TCP then
|
if m_pkt.scada_frame.protocol() == PROTOCOLS.MODBUS_TCP then
|
||||||
if m_pkt.unit_id == self.unit_id then
|
if m_pkt.unit_id == self.unit_id then
|
||||||
local txn_type = self.transaction_controller.resolve(m_pkt.txn_id)
|
local txn_type = self.transaction_controller.resolve(m_pkt.txn_id)
|
||||||
@@ -112,42 +112,42 @@ unit_session.new = function (unit_id, advert, out_queue, log_tag, txn_tags)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get the public interface
|
-- get the public interface
|
||||||
protected.get = function () return public end
|
function protected.get() return public end
|
||||||
|
|
||||||
-- PUBLIC FUNCTIONS --
|
-- PUBLIC FUNCTIONS --
|
||||||
|
|
||||||
-- get the unit ID
|
-- get the unit ID
|
||||||
public.get_unit_id = function () return self.unit_id end
|
function public.get_unit_id() return self.unit_id end
|
||||||
-- get the device index
|
-- get the device index
|
||||||
public.get_device_idx = function () return self.device_index end
|
function public.get_device_idx() return self.device_index end
|
||||||
-- get the reactor ID
|
-- get the reactor ID
|
||||||
public.get_reactor = function () return self.reactor end
|
function public.get_reactor() return self.reactor end
|
||||||
|
|
||||||
-- close this unit
|
-- close this unit
|
||||||
public.close = function () self.connected = false end
|
function public.close() self.connected = false end
|
||||||
-- check if this unit is connected
|
-- check if this unit is connected
|
||||||
public.is_connected = function () return self.connected end
|
function public.is_connected() return self.connected end
|
||||||
-- check if this unit is faulted
|
-- check if this unit is faulted
|
||||||
public.is_faulted = function () return self.device_fail end
|
function public.is_faulted() return self.device_fail end
|
||||||
|
|
||||||
-- PUBLIC TEMPLATE FUNCTIONS --
|
-- PUBLIC TEMPLATE FUNCTIONS --
|
||||||
|
|
||||||
-- handle a packet
|
-- handle a packet
|
||||||
---@param m_pkt modbus_frame
|
---@param m_pkt modbus_frame
|
||||||
---@diagnostic disable-next-line: unused-local
|
---@diagnostic disable-next-line: unused-local
|
||||||
public.handle_packet = function (m_pkt)
|
function public.handle_packet(m_pkt)
|
||||||
log.debug("template unit_session.handle_packet() called", true)
|
log.debug("template unit_session.handle_packet() called", true)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- update this runner
|
-- update this runner
|
||||||
---@param time_now integer milliseconds
|
---@param time_now integer milliseconds
|
||||||
---@diagnostic disable-next-line: unused-local
|
---@diagnostic disable-next-line: unused-local
|
||||||
public.update = function (time_now)
|
function public.update(time_now)
|
||||||
log.debug("template unit_session.update() called", true)
|
log.debug("template unit_session.update() called", true)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- get the unit session database
|
-- get the unit session database
|
||||||
public.get_db = function () return {} end
|
function public.get_db() return {} end
|
||||||
|
|
||||||
return protected
|
return protected
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
local log = require("scada-common.log")
|
local log = require("scada-common.log")
|
||||||
local mqueue = require("scada-common.mqueue")
|
local mqueue = require("scada-common.mqueue")
|
||||||
local util = require("scada-common.util")
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
local coordinator = require("supervisor.session.coordinator")
|
local coordinator = require("supervisor.session.coordinator")
|
||||||
local plc = require("supervisor.session.plc")
|
local plc = require("supervisor.session.plc")
|
||||||
local rtu = require("supervisor.session.rtu")
|
local rtu = require("supervisor.session.rtu")
|
||||||
|
|
||||||
-- Supervisor Sessions Handler
|
-- Supervisor Sessions Handler
|
||||||
|
|
||||||
@@ -121,14 +121,14 @@ end
|
|||||||
|
|
||||||
-- link the modem
|
-- link the modem
|
||||||
---@param modem table
|
---@param modem table
|
||||||
svsessions.link_modem = function (modem)
|
function svsessions.link_modem(modem)
|
||||||
self.modem = modem
|
self.modem = modem
|
||||||
end
|
end
|
||||||
|
|
||||||
-- find an RTU session by the remote port
|
-- find an RTU session by the remote port
|
||||||
---@param remote_port integer
|
---@param remote_port integer
|
||||||
---@return rtu_session_struct|nil
|
---@return rtu_session_struct|nil
|
||||||
svsessions.find_rtu_session = function (remote_port)
|
function svsessions.find_rtu_session(remote_port)
|
||||||
-- check RTU sessions
|
-- check RTU sessions
|
||||||
return _find_session(self.rtu_sessions, remote_port)
|
return _find_session(self.rtu_sessions, remote_port)
|
||||||
end
|
end
|
||||||
@@ -136,7 +136,7 @@ end
|
|||||||
-- find a PLC session by the remote port
|
-- find a PLC session by the remote port
|
||||||
---@param remote_port integer
|
---@param remote_port integer
|
||||||
---@return plc_session_struct|nil
|
---@return plc_session_struct|nil
|
||||||
svsessions.find_plc_session = function (remote_port)
|
function svsessions.find_plc_session(remote_port)
|
||||||
-- check PLC sessions
|
-- check PLC sessions
|
||||||
return _find_session(self.plc_sessions, remote_port)
|
return _find_session(self.plc_sessions, remote_port)
|
||||||
end
|
end
|
||||||
@@ -144,7 +144,7 @@ end
|
|||||||
-- find a PLC/RTU session by the remote port
|
-- find a PLC/RTU session by the remote port
|
||||||
---@param remote_port integer
|
---@param remote_port integer
|
||||||
---@return plc_session_struct|rtu_session_struct|nil
|
---@return plc_session_struct|rtu_session_struct|nil
|
||||||
svsessions.find_device_session = function (remote_port)
|
function svsessions.find_device_session(remote_port)
|
||||||
-- check RTU sessions
|
-- check RTU sessions
|
||||||
local s = _find_session(self.rtu_sessions, remote_port)
|
local s = _find_session(self.rtu_sessions, remote_port)
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ end
|
|||||||
-- find a coordinator session by the remote port
|
-- find a coordinator session by the remote port
|
||||||
---@param remote_port integer
|
---@param remote_port integer
|
||||||
---@return nil
|
---@return nil
|
||||||
svsessions.find_coord_session = function (remote_port)
|
function svsessions.find_coord_session(remote_port)
|
||||||
-- check coordinator sessions
|
-- check coordinator sessions
|
||||||
return _find_session(self.coord_sessions, remote_port)
|
return _find_session(self.coord_sessions, remote_port)
|
||||||
end
|
end
|
||||||
@@ -165,7 +165,7 @@ end
|
|||||||
-- get a session by reactor ID
|
-- get a session by reactor ID
|
||||||
---@param reactor integer
|
---@param reactor integer
|
||||||
---@return plc_session_struct|nil session
|
---@return plc_session_struct|nil session
|
||||||
svsessions.get_reactor_session = function (reactor)
|
function svsessions.get_reactor_session(reactor)
|
||||||
local session = nil
|
local session = nil
|
||||||
|
|
||||||
for i = 1, #self.plc_sessions do
|
for i = 1, #self.plc_sessions do
|
||||||
@@ -183,7 +183,7 @@ end
|
|||||||
---@param for_reactor integer
|
---@param for_reactor integer
|
||||||
---@param version string
|
---@param version string
|
||||||
---@return integer|false session_id
|
---@return integer|false session_id
|
||||||
svsessions.establish_plc_session = function (local_port, remote_port, for_reactor, version)
|
function svsessions.establish_plc_session(local_port, remote_port, for_reactor, version)
|
||||||
if svsessions.get_reactor_session(for_reactor) == nil then
|
if svsessions.get_reactor_session(for_reactor) == nil then
|
||||||
---@class plc_session_struct
|
---@class plc_session_struct
|
||||||
local plc_s = {
|
local plc_s = {
|
||||||
@@ -217,7 +217,7 @@ end
|
|||||||
---@param remote_port integer
|
---@param remote_port integer
|
||||||
---@param advertisement table
|
---@param advertisement table
|
||||||
---@return integer session_id
|
---@return integer session_id
|
||||||
svsessions.establish_rtu_session = function (local_port, remote_port, advertisement)
|
function svsessions.establish_rtu_session(local_port, remote_port, advertisement)
|
||||||
-- pull version from advertisement
|
-- pull version from advertisement
|
||||||
local version = table.remove(advertisement, 1)
|
local version = table.remove(advertisement, 1)
|
||||||
|
|
||||||
@@ -245,7 +245,7 @@ end
|
|||||||
|
|
||||||
-- attempt to identify which session's watchdog timer fired
|
-- attempt to identify which session's watchdog timer fired
|
||||||
---@param timer_event number
|
---@param timer_event number
|
||||||
svsessions.check_all_watchdogs = function (timer_event)
|
function svsessions.check_all_watchdogs(timer_event)
|
||||||
-- check RTU session watchdogs
|
-- check RTU session watchdogs
|
||||||
_check_watchdogs(self.rtu_sessions, timer_event)
|
_check_watchdogs(self.rtu_sessions, timer_event)
|
||||||
|
|
||||||
@@ -257,7 +257,7 @@ svsessions.check_all_watchdogs = function (timer_event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- iterate all sessions
|
-- iterate all sessions
|
||||||
svsessions.iterate_all = function ()
|
function svsessions.iterate_all()
|
||||||
-- iterate RTU sessions
|
-- iterate RTU sessions
|
||||||
_iterate(self.rtu_sessions)
|
_iterate(self.rtu_sessions)
|
||||||
|
|
||||||
@@ -269,7 +269,7 @@ svsessions.iterate_all = function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- delete all closed sessions
|
-- delete all closed sessions
|
||||||
svsessions.free_all_closed = function ()
|
function svsessions.free_all_closed()
|
||||||
-- free closed RTU sessions
|
-- free closed RTU sessions
|
||||||
_free_closed(self.rtu_sessions)
|
_free_closed(self.rtu_sessions)
|
||||||
|
|
||||||
@@ -281,7 +281,7 @@ svsessions.free_all_closed = function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- close all open connections
|
-- close all open connections
|
||||||
svsessions.close_all = function ()
|
function svsessions.close_all()
|
||||||
-- close sessions
|
-- close sessions
|
||||||
_close(self.rtu_sessions)
|
_close(self.rtu_sessions)
|
||||||
_close(self.plc_sessions)
|
_close(self.plc_sessions)
|
||||||
|
|||||||
@@ -4,16 +4,16 @@
|
|||||||
|
|
||||||
require("/initenv").init_env()
|
require("/initenv").init_env()
|
||||||
|
|
||||||
local log = require("scada-common.log")
|
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 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 = "beta-v0.4.1"
|
local SUPERVISOR_VERSION = "beta-v0.4.2"
|
||||||
|
|
||||||
local print = util.print
|
local print = util.print
|
||||||
local println = util.println
|
local println = util.println
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
local comms = require("scada-common.comms")
|
local comms = require("scada-common.comms")
|
||||||
local log = require("scada-common.log")
|
local log = require("scada-common.log")
|
||||||
local util = require("scada-common.util")
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
local svsessions = require("supervisor.session.svsessions")
|
local svsessions = require("supervisor.session.svsessions")
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ local println_ts = util.println_ts
|
|||||||
---@param modem table
|
---@param modem table
|
||||||
---@param dev_listen integer
|
---@param dev_listen integer
|
||||||
---@param coord_listen integer
|
---@param coord_listen integer
|
||||||
supervisor.comms = function (version, num_reactors, modem, dev_listen, coord_listen)
|
function supervisor.comms(version, num_reactors, modem, dev_listen, coord_listen)
|
||||||
local self = {
|
local self = {
|
||||||
version = version,
|
version = version,
|
||||||
num_reactors = num_reactors,
|
num_reactors = num_reactors,
|
||||||
@@ -41,7 +41,7 @@ supervisor.comms = function (version, num_reactors, modem, dev_listen, coord_lis
|
|||||||
-- PRIVATE FUNCTIONS --
|
-- PRIVATE FUNCTIONS --
|
||||||
|
|
||||||
-- open all channels
|
-- open all channels
|
||||||
local _open_channels = function ()
|
local function _open_channels()
|
||||||
if not self.modem.isOpen(self.dev_listen) then
|
if not self.modem.isOpen(self.dev_listen) then
|
||||||
self.modem.open(self.dev_listen)
|
self.modem.open(self.dev_listen)
|
||||||
end
|
end
|
||||||
@@ -60,7 +60,7 @@ supervisor.comms = function (version, num_reactors, modem, dev_listen, coord_lis
|
|||||||
-- send PLC link request responses
|
-- send PLC link request responses
|
||||||
---@param dest integer
|
---@param dest integer
|
||||||
---@param msg table
|
---@param msg table
|
||||||
local _send_plc_linking = function (seq_id, dest, msg)
|
local function _send_plc_linking(seq_id, 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()
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ supervisor.comms = function (version, num_reactors, modem, dev_listen, coord_lis
|
|||||||
-- send RTU advertisement responses
|
-- send RTU advertisement responses
|
||||||
---@param seq_id integer
|
---@param seq_id integer
|
||||||
---@param dest integer
|
---@param dest integer
|
||||||
local _send_remote_linked = function (seq_id, dest)
|
local function _send_remote_linked(seq_id, dest)
|
||||||
local s_pkt = comms.scada_packet()
|
local s_pkt = comms.scada_packet()
|
||||||
local m_pkt = comms.mgmt_packet()
|
local m_pkt = comms.mgmt_packet()
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ supervisor.comms = function (version, num_reactors, modem, dev_listen, coord_lis
|
|||||||
-- reconnect a newly connected modem
|
-- reconnect a newly connected modem
|
||||||
---@param modem table
|
---@param modem table
|
||||||
---@diagnostic disable-next-line: redefined-local
|
---@diagnostic disable-next-line: redefined-local
|
||||||
public.reconnect_modem = function (modem)
|
function public.reconnect_modem(modem)
|
||||||
self.modem = modem
|
self.modem = modem
|
||||||
svsessions.link_modem(self.modem)
|
svsessions.link_modem(self.modem)
|
||||||
_open_channels()
|
_open_channels()
|
||||||
@@ -101,7 +101,7 @@ supervisor.comms = function (version, num_reactors, modem, dev_listen, coord_lis
|
|||||||
---@param message any
|
---@param message any
|
||||||
---@param distance integer
|
---@param distance integer
|
||||||
---@return modbus_frame|rplc_frame|mgmt_frame|coord_frame|nil packet
|
---@return modbus_frame|rplc_frame|mgmt_frame|coord_frame|nil packet
|
||||||
public.parse_packet = function(side, sender, reply_to, message, distance)
|
function public.parse_packet(side, sender, reply_to, message, distance)
|
||||||
local pkt = nil
|
local pkt = nil
|
||||||
local s_pkt = comms.scada_packet()
|
local s_pkt = comms.scada_packet()
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ supervisor.comms = function (version, num_reactors, modem, dev_listen, coord_lis
|
|||||||
|
|
||||||
-- handle a packet
|
-- handle a packet
|
||||||
---@param packet modbus_frame|rplc_frame|mgmt_frame|coord_frame
|
---@param packet modbus_frame|rplc_frame|mgmt_frame|coord_frame
|
||||||
public.handle_packet = function(packet)
|
function public.handle_packet(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()
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ local DT_KEYS = {
|
|||||||
---@param for_reactor integer reactor unit number
|
---@param for_reactor integer reactor unit number
|
||||||
---@param num_boilers integer number of boilers expected
|
---@param num_boilers integer number of boilers expected
|
||||||
---@param num_turbines integer number of turbines expected
|
---@param num_turbines integer number of turbines expected
|
||||||
unit.new = function (for_reactor, num_boilers, num_turbines)
|
function unit.new(for_reactor, num_boilers, num_turbines)
|
||||||
local self = {
|
local self = {
|
||||||
r_id = for_reactor,
|
r_id = for_reactor,
|
||||||
plc_s = nil, ---@class plc_session
|
plc_s = nil, ---@class plc_session
|
||||||
@@ -82,7 +82,7 @@ unit.new = function (for_reactor, num_boilers, num_turbines)
|
|||||||
-- compute a change with respect to time of the given value
|
-- compute a change with respect to time of the given value
|
||||||
---@param key string value key
|
---@param key string value key
|
||||||
---@param value number value
|
---@param value number value
|
||||||
local _compute_dt = function (key, value)
|
local function _compute_dt(key, value)
|
||||||
if self.deltas[key] then
|
if self.deltas[key] then
|
||||||
local data = self.deltas[key]
|
local data = self.deltas[key]
|
||||||
|
|
||||||
@@ -101,14 +101,14 @@ unit.new = function (for_reactor, num_boilers, num_turbines)
|
|||||||
|
|
||||||
-- clear a delta
|
-- clear a delta
|
||||||
---@param key string value key
|
---@param key string value key
|
||||||
local _reset_dt = function (key)
|
local function _reset_dt(key)
|
||||||
self.deltas[key] = nil
|
self.deltas[key] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
-- get the delta t of a value
|
-- get the delta t of a value
|
||||||
---@param key string value key
|
---@param key string value key
|
||||||
---@return number
|
---@return number
|
||||||
local _get_dt = function (key)
|
local function _get_dt(key)
|
||||||
if self.deltas[key] then
|
if self.deltas[key] then
|
||||||
return self.deltas[key].dt
|
return self.deltas[key].dt
|
||||||
else
|
else
|
||||||
@@ -117,7 +117,7 @@ unit.new = function (for_reactor, num_boilers, num_turbines)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- update all delta computations
|
-- update all delta computations
|
||||||
local _dt__compute_all = function ()
|
local function _dt__compute_all()
|
||||||
if self.plc_s ~= nil then
|
if self.plc_s ~= nil then
|
||||||
local plc_db = self.plc_s.get_db()
|
local plc_db = self.plc_s.get_db()
|
||||||
|
|
||||||
@@ -151,7 +151,7 @@ unit.new = function (for_reactor, num_boilers, num_turbines)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- update the annunciator
|
-- update the annunciator
|
||||||
local _update_annunciator = function ()
|
local function _update_annunciator()
|
||||||
-- update deltas
|
-- update deltas
|
||||||
_dt__compute_all()
|
_dt__compute_all()
|
||||||
|
|
||||||
@@ -312,7 +312,7 @@ unit.new = function (for_reactor, num_boilers, num_turbines)
|
|||||||
|
|
||||||
-- unlink disconnected units
|
-- unlink disconnected units
|
||||||
---@param sessions table
|
---@param sessions table
|
||||||
local _unlink_disconnected_units = function (sessions)
|
local function _unlink_disconnected_units(sessions)
|
||||||
util.filter_table(sessions, function (u) return u.is_connected() end)
|
util.filter_table(sessions, function (u) return u.is_connected() end)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -320,7 +320,7 @@ unit.new = function (for_reactor, num_boilers, num_turbines)
|
|||||||
|
|
||||||
-- link the PLC
|
-- link the PLC
|
||||||
---@param plc_session plc_session_struct
|
---@param plc_session plc_session_struct
|
||||||
public.link_plc_session = function (plc_session)
|
function public.link_plc_session(plc_session)
|
||||||
self.plc_s = plc_session
|
self.plc_s = plc_session
|
||||||
|
|
||||||
-- reset deltas
|
-- reset deltas
|
||||||
@@ -333,7 +333,7 @@ unit.new = function (for_reactor, num_boilers, num_turbines)
|
|||||||
|
|
||||||
-- link a turbine RTU session
|
-- link a turbine RTU session
|
||||||
---@param turbine unit_session
|
---@param turbine unit_session
|
||||||
public.add_turbine = function (turbine)
|
function public.add_turbine(turbine)
|
||||||
if #self.turbines < self.num_turbines and turbine.get_device_idx() <= self.num_turbines then
|
if #self.turbines < self.num_turbines and turbine.get_device_idx() <= self.num_turbines then
|
||||||
table.insert(self.turbines, turbine)
|
table.insert(self.turbines, turbine)
|
||||||
|
|
||||||
@@ -349,7 +349,7 @@ unit.new = function (for_reactor, num_boilers, num_turbines)
|
|||||||
|
|
||||||
-- link a boiler RTU session
|
-- link a boiler RTU session
|
||||||
---@param boiler unit_session
|
---@param boiler unit_session
|
||||||
public.add_boiler = function (boiler)
|
function public.add_boiler(boiler)
|
||||||
if #self.boilers < self.num_boilers and boiler.get_device_idx() <= self.num_boilers then
|
if #self.boilers < self.num_boilers and boiler.get_device_idx() <= self.num_boilers then
|
||||||
table.insert(self.boilers, boiler)
|
table.insert(self.boilers, boiler)
|
||||||
|
|
||||||
@@ -366,7 +366,7 @@ unit.new = function (for_reactor, num_boilers, num_turbines)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- link a redstone RTU capability
|
-- link a redstone RTU capability
|
||||||
public.add_redstone = function (field, accessor)
|
function public.add_redstone(field, accessor)
|
||||||
-- ensure field exists
|
-- ensure field exists
|
||||||
if self.redstone[field] == nil then
|
if self.redstone[field] == nil then
|
||||||
self.redstone[field] = {}
|
self.redstone[field] = {}
|
||||||
@@ -377,7 +377,7 @@ unit.new = function (for_reactor, num_boilers, num_turbines)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- update (iterate) this unit
|
-- update (iterate) this unit
|
||||||
public.update = function ()
|
function public.update()
|
||||||
-- 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
|
||||||
self.plc_s = nil
|
self.plc_s = nil
|
||||||
@@ -392,7 +392,7 @@ unit.new = function (for_reactor, num_boilers, num_turbines)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get build properties of all machines
|
-- get build properties of all machines
|
||||||
public.get_build = function ()
|
function public.get_build()
|
||||||
local build = {}
|
local build = {}
|
||||||
|
|
||||||
if self.plc_s ~= nil then
|
if self.plc_s ~= nil then
|
||||||
@@ -413,7 +413,7 @@ unit.new = function (for_reactor, num_boilers, num_turbines)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get reactor status
|
-- get reactor status
|
||||||
public.get_reactor_status = function ()
|
function public.get_reactor_status()
|
||||||
local status = {}
|
local status = {}
|
||||||
|
|
||||||
if self.plc_s ~= nil then
|
if self.plc_s ~= nil then
|
||||||
@@ -427,7 +427,7 @@ unit.new = function (for_reactor, num_boilers, num_turbines)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get RTU statuses
|
-- get RTU statuses
|
||||||
public.get_rtu_statuses = function ()
|
function public.get_rtu_statuses()
|
||||||
local status = {}
|
local status = {}
|
||||||
|
|
||||||
-- status of boilers (including tanks)
|
-- status of boilers (including tanks)
|
||||||
@@ -452,7 +452,7 @@ unit.new = function (for_reactor, num_boilers, num_turbines)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get the annunciator status
|
-- get the annunciator status
|
||||||
public.get_annunciator = function () return self.db.annunciator end
|
function public.get_annunciator() return self.db.annunciator end
|
||||||
|
|
||||||
return public
|
return public
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user