mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
#123 RTU startup without devices, fixed repeat RTU advert handling, added PPM virtual devices, fixed log out of space detection, updated RTU type conversion functions in comms
This commit is contained in:
parent
f940c136bf
commit
1a01bec7e4
@ -16,7 +16,7 @@ local config = require("coordinator.config")
|
||||
local coordinator = require("coordinator.coordinator")
|
||||
local renderer = require("coordinator.renderer")
|
||||
|
||||
local COORDINATOR_VERSION = "alpha-v0.6.9"
|
||||
local COORDINATOR_VERSION = "alpha-v0.6.10"
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
|
@ -13,7 +13,7 @@ local config = require("reactor-plc.config")
|
||||
local plc = require("reactor-plc.plc")
|
||||
local threads = require("reactor-plc.threads")
|
||||
|
||||
local R_PLC_VERSION = "beta-v0.9.4"
|
||||
local R_PLC_VERSION = "beta-v0.9.5"
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
|
172
rtu/startup.lua
172
rtu/startup.lua
@ -24,7 +24,7 @@ local sna_rtu = require("rtu.dev.sna_rtu")
|
||||
local sps_rtu = require("rtu.dev.sps_rtu")
|
||||
local turbinev_rtu = require("rtu.dev.turbinev_rtu")
|
||||
|
||||
local RTU_VERSION = "beta-v0.9.1"
|
||||
local RTU_VERSION = "beta-v0.9.2"
|
||||
|
||||
local rtu_t = types.rtu_t
|
||||
|
||||
@ -257,98 +257,104 @@ local function configure()
|
||||
|
||||
local device = ppm.get_periph(name)
|
||||
|
||||
local type = nil
|
||||
local rtu_iface = nil ---@type rtu_device
|
||||
local rtu_type = ""
|
||||
local formed = nil ---@type boolean|nil
|
||||
|
||||
if device == nil then
|
||||
local message = util.c("configure> '", name, "' not found")
|
||||
local message = util.c("configure> '", name, "' not found, using placeholder")
|
||||
println(message)
|
||||
log.fatal(message)
|
||||
return false
|
||||
log.warning(message)
|
||||
|
||||
-- mount a virtual (placeholder) device
|
||||
type, device = ppm.mount_virtual()
|
||||
else
|
||||
local type = ppm.get_type(name)
|
||||
local rtu_iface = nil ---@type rtu_device
|
||||
local rtu_type = ""
|
||||
local formed = nil ---@type boolean|nil
|
||||
type = ppm.get_type(name)
|
||||
end
|
||||
|
||||
if type == "boilerValve" then
|
||||
-- boiler multiblock
|
||||
rtu_type = rtu_t.boiler_valve
|
||||
rtu_iface = boilerv_rtu.new(device)
|
||||
formed = device.isFormed()
|
||||
if type == "boilerValve" then
|
||||
-- boiler multiblock
|
||||
rtu_type = rtu_t.boiler_valve
|
||||
rtu_iface = boilerv_rtu.new(device)
|
||||
formed = device.isFormed()
|
||||
|
||||
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
||||
println_ts(util.c("configure> failed to check if '", name, "' is formed"))
|
||||
log.fatal(util.c("configure> failed to check if '", name, "' is a formed boiler multiblock"))
|
||||
return false
|
||||
end
|
||||
elseif type == "turbineValve" then
|
||||
-- turbine multiblock
|
||||
rtu_type = rtu_t.turbine_valve
|
||||
rtu_iface = turbinev_rtu.new(device)
|
||||
formed = device.isFormed()
|
||||
|
||||
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
||||
println_ts(util.c("configure> failed to check if '", name, "' is formed"))
|
||||
log.fatal(util.c("configure> failed to check if '", name, "' is a formed turbine multiblock"))
|
||||
return false
|
||||
end
|
||||
elseif type == "inductionPort" then
|
||||
-- induction matrix multiblock
|
||||
rtu_type = rtu_t.induction_matrix
|
||||
rtu_iface = imatrix_rtu.new(device)
|
||||
formed = device.isFormed()
|
||||
|
||||
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
||||
println_ts(util.c("configure> failed to check if '", name, "' is formed"))
|
||||
log.fatal(util.c("configure> failed to check if '", name, "' is a formed induction matrix multiblock"))
|
||||
return false
|
||||
end
|
||||
elseif type == "spsPort" then
|
||||
-- SPS multiblock
|
||||
rtu_type = rtu_t.sps
|
||||
rtu_iface = sps_rtu.new(device)
|
||||
formed = device.isFormed()
|
||||
|
||||
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
||||
println_ts(util.c("configure> failed to check if '", name, "' is formed"))
|
||||
log.fatal(util.c("configure> failed to check if '", name, "' is a formed SPS multiblock"))
|
||||
return false
|
||||
end
|
||||
elseif type == "solarNeutronActivator" then
|
||||
-- SNA
|
||||
rtu_type = rtu_t.sna
|
||||
rtu_iface = sna_rtu.new(device)
|
||||
elseif type == "environmentDetector" then
|
||||
-- advanced peripherals environment detector
|
||||
rtu_type = rtu_t.env_detector
|
||||
rtu_iface = envd_rtu.new(device)
|
||||
else
|
||||
local message = util.c("configure> device '", name, "' is not a known type (", type, ")")
|
||||
println_ts(message)
|
||||
log.fatal(message)
|
||||
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
||||
println_ts(util.c("configure> failed to check if '", name, "' is formed"))
|
||||
log.fatal(util.c("configure> failed to check if '", name, "' is a formed boiler multiblock"))
|
||||
return false
|
||||
end
|
||||
elseif type == "turbineValve" then
|
||||
-- turbine multiblock
|
||||
rtu_type = rtu_t.turbine_valve
|
||||
rtu_iface = turbinev_rtu.new(device)
|
||||
formed = device.isFormed()
|
||||
|
||||
if rtu_iface ~= nil then
|
||||
---@class rtu_unit_registry_entry
|
||||
local rtu_unit = {
|
||||
name = name,
|
||||
type = rtu_type,
|
||||
index = index,
|
||||
reactor = for_reactor,
|
||||
device = device,
|
||||
formed = formed,
|
||||
rtu = rtu_iface, ---@type rtu_device|rtu_rs_device
|
||||
modbus_io = modbus.new(rtu_iface, true),
|
||||
pkt_queue = mqueue.new(), ---@type mqueue|nil
|
||||
thread = nil
|
||||
}
|
||||
|
||||
rtu_unit.thread = threads.thread__unit_comms(__shared_memory, rtu_unit)
|
||||
|
||||
table.insert(units, rtu_unit)
|
||||
|
||||
log.debug(util.c("configure> initialized RTU unit #", #units, ": ", name, " (", rtu_type, ") [", index, "] for reactor ", for_reactor))
|
||||
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
||||
println_ts(util.c("configure> failed to check if '", name, "' is formed"))
|
||||
log.fatal(util.c("configure> failed to check if '", name, "' is a formed turbine multiblock"))
|
||||
return false
|
||||
end
|
||||
elseif type == "inductionPort" then
|
||||
-- induction matrix multiblock
|
||||
rtu_type = rtu_t.induction_matrix
|
||||
rtu_iface = imatrix_rtu.new(device)
|
||||
formed = device.isFormed()
|
||||
|
||||
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
||||
println_ts(util.c("configure> failed to check if '", name, "' is formed"))
|
||||
log.fatal(util.c("configure> failed to check if '", name, "' is a formed induction matrix multiblock"))
|
||||
return false
|
||||
end
|
||||
elseif type == "spsPort" then
|
||||
-- SPS multiblock
|
||||
rtu_type = rtu_t.sps
|
||||
rtu_iface = sps_rtu.new(device)
|
||||
formed = device.isFormed()
|
||||
|
||||
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
||||
println_ts(util.c("configure> failed to check if '", name, "' is formed"))
|
||||
log.fatal(util.c("configure> failed to check if '", name, "' is a formed SPS multiblock"))
|
||||
return false
|
||||
end
|
||||
elseif type == "solarNeutronActivator" then
|
||||
-- SNA
|
||||
rtu_type = rtu_t.sna
|
||||
rtu_iface = sna_rtu.new(device)
|
||||
elseif type == "environmentDetector" then
|
||||
-- advanced peripherals environment detector
|
||||
rtu_type = rtu_t.env_detector
|
||||
rtu_iface = envd_rtu.new(device)
|
||||
elseif type == ppm.VIRTUAL_DEVICE_TYPE then
|
||||
-- placeholder device
|
||||
rtu_type = "virtual"
|
||||
rtu_iface = rtu.init_unit().interface()
|
||||
else
|
||||
local message = util.c("configure> device '", name, "' is not a known type (", type, ")")
|
||||
println_ts(message)
|
||||
log.fatal(message)
|
||||
return false
|
||||
end
|
||||
|
||||
---@class rtu_unit_registry_entry
|
||||
local rtu_unit = {
|
||||
name = name,
|
||||
type = rtu_type,
|
||||
index = index,
|
||||
reactor = for_reactor,
|
||||
device = device,
|
||||
formed = formed,
|
||||
rtu = rtu_iface, ---@type rtu_device|rtu_rs_device
|
||||
modbus_io = modbus.new(rtu_iface, true),
|
||||
pkt_queue = mqueue.new(), ---@type mqueue|nil
|
||||
thread = nil
|
||||
}
|
||||
|
||||
rtu_unit.thread = threads.thread__unit_comms(__shared_memory, rtu_unit)
|
||||
|
||||
table.insert(units, rtu_unit)
|
||||
|
||||
log.debug(util.c("configure> initialized RTU unit #", #units, ": ", name, " (", rtu_type, ") [", index, "] for reactor ", for_reactor))
|
||||
end
|
||||
|
||||
-- we made it through all that trusting-user-to-write-a-config-file chaos
|
||||
|
@ -122,9 +122,37 @@ function threads.thread__main(smem)
|
||||
-- find disconnected device to reconnect
|
||||
-- note: cannot check isFormed as that would yield this coroutine and consume events
|
||||
if unit.name == param1 then
|
||||
local resend_advert = false
|
||||
|
||||
-- found, re-link
|
||||
unit.device = device
|
||||
|
||||
if unit.type == "virtual" then
|
||||
resend_advert = true
|
||||
if type == "boilerValve" then
|
||||
-- boiler multiblock
|
||||
unit.type = rtu_t.boiler_valve
|
||||
elseif type == "turbineValve" then
|
||||
-- turbine multiblock
|
||||
unit.type = rtu_t.turbine_valve
|
||||
elseif type == "inductionPort" then
|
||||
-- induction matrix multiblock
|
||||
unit.type = rtu_t.induction_matrix
|
||||
elseif type == "spsPort" then
|
||||
-- SPS multiblock
|
||||
unit.type = rtu_t.sps
|
||||
elseif type == "solarNeutronActivator" then
|
||||
-- SNA
|
||||
unit.type = rtu_t.sna
|
||||
elseif type == "environmentDetector" then
|
||||
-- advanced peripherals environment detector
|
||||
unit.type = rtu_t.env_detector
|
||||
else
|
||||
resend_advert = false
|
||||
log.error(util.c("virtual device '", unit.name, "' cannot init to an unknown type (", type, ")"))
|
||||
end
|
||||
end
|
||||
|
||||
if unit.type == rtu_t.boiler_valve then
|
||||
unit.rtu = boilerv_rtu.new(device)
|
||||
unit.formed = true
|
||||
@ -142,14 +170,19 @@ function threads.thread__main(smem)
|
||||
elseif unit.type == rtu_t.env_detector then
|
||||
unit.rtu = envd_rtu.new(device)
|
||||
else
|
||||
log.error(util.c("unreachable case occured trying to identify reconnected RTU unit type (", unit.name, ")"), true)
|
||||
log.error(util.c("failed to identify reconnected RTU unit type (", unit.name, ")"), true)
|
||||
end
|
||||
|
||||
unit.modbus_io = modbus.new(unit.rtu, true)
|
||||
|
||||
rtu_comms.send_remounted(unit.index)
|
||||
|
||||
println_ts("reconnected the " .. unit.type .. " on interface " .. unit.name)
|
||||
log.info("reconnected the " .. unit.type .. " on interface " .. unit.name)
|
||||
|
||||
if resend_advert then
|
||||
rtu_comms.send_advertisement(units)
|
||||
else
|
||||
rtu_comms.send_remounted(unit.index)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -274,7 +307,6 @@ function threads.thread__unit_comms(smem, unit)
|
||||
|
||||
local last_update = util.time()
|
||||
|
||||
local check_formed = type(unit.formed) == "boolean"
|
||||
local last_f_check = 0
|
||||
|
||||
local detail_name = util.c(unit.type, " (", unit.name, ") [", unit.index, "] for reactor ", unit.reactor)
|
||||
@ -308,8 +340,8 @@ function threads.thread__unit_comms(smem, unit)
|
||||
end
|
||||
|
||||
|
||||
-- check if multiblocks is still formed
|
||||
if check_formed and (util.time() - last_f_check > 1000) then
|
||||
-- check if multiblock is still formed if this is a multiblock
|
||||
if (type(unit.formed) == "boolean") and (util.time() - last_f_check > 1000) then
|
||||
if (not unit.formed) and unit.device.isFormed() then
|
||||
-- newly re-formed
|
||||
local iface = ppm.get_iface(unit.device)
|
||||
|
@ -642,6 +642,12 @@ function comms.rtu_t_to_unit_type(type)
|
||||
return RTU_UNIT_TYPES.TURBINE_VALVE
|
||||
elseif type == rtu_t.induction_matrix then
|
||||
return RTU_UNIT_TYPES.IMATRIX
|
||||
elseif type == rtu_t.sps then
|
||||
return RTU_UNIT_TYPES.SPS
|
||||
elseif type == rtu_t.sna then
|
||||
return RTU_UNIT_TYPES.SNA
|
||||
elseif type == rtu_t.env_detector then
|
||||
return RTU_UNIT_TYPES.ENV_DETECTOR
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -659,6 +665,12 @@ function comms.advert_type_to_rtu_t(utype)
|
||||
return rtu_t.turbine_valve
|
||||
elseif utype == RTU_UNIT_TYPES.IMATRIX then
|
||||
return rtu_t.induction_matrix
|
||||
elseif utype == RTU_UNIT_TYPES.SPS then
|
||||
return rtu_t.sps
|
||||
elseif utype == RTU_UNIT_TYPES.SNA then
|
||||
return rtu_t.sna
|
||||
elseif utype == RTU_UNIT_TYPES.ENV_DETECTOR then
|
||||
return rtu_t.env_detector
|
||||
end
|
||||
|
||||
return nil
|
||||
|
@ -58,6 +58,7 @@ end
|
||||
-- private log write function
|
||||
---@param msg string
|
||||
local function _log(msg)
|
||||
local out_of_space = false
|
||||
local time_stamp = os.date("[%c] ")
|
||||
local stamped = time_stamp .. util.strval(msg)
|
||||
|
||||
@ -69,15 +70,17 @@ local function _log(msg)
|
||||
|
||||
-- if we don't have space, we need to create a new log file
|
||||
|
||||
if not status then
|
||||
if result == "Out of space" then
|
||||
if (not status) and (result ~= nil) then
|
||||
out_of_space = string.find(result, "Out of space") ~= nil
|
||||
|
||||
if out_of_space then
|
||||
-- will delete log file
|
||||
elseif result ~= nil then
|
||||
else
|
||||
util.println("unknown error writing to logfile: " .. result)
|
||||
end
|
||||
end
|
||||
|
||||
if (result == "Out of space") or (free_space(_log_sys.path) < 100) then
|
||||
if out_of_space or (free_space(_log_sys.path) < 100) then
|
||||
-- delete the old log file and open a new one
|
||||
_log_sys.file.close()
|
||||
fs.delete(_log_sys.path)
|
||||
|
@ -12,8 +12,11 @@ local ACCESS_FAULT = nil ---@type nil
|
||||
|
||||
local UNDEFINED_FIELD = "undefined field"
|
||||
|
||||
local VIRTUAL_DEVICE_TYPE = "ppm_vdev"
|
||||
|
||||
ppm.ACCESS_FAULT = ACCESS_FAULT
|
||||
ppm.UNDEFINED_FIELD = UNDEFINED_FIELD
|
||||
ppm.VIRTUAL_DEVICE_TYPE = VIRTUAL_DEVICE_TYPE
|
||||
|
||||
----------------------------
|
||||
-- PRIVATE DATA/FUNCTIONS --
|
||||
@ -23,6 +26,7 @@ local REPORT_FREQUENCY = 20 -- log every 20 faults per function
|
||||
|
||||
local _ppm_sys = {
|
||||
mounts = {},
|
||||
next_vid = 0,
|
||||
auto_cf = false,
|
||||
faulted = false,
|
||||
last_fault = "",
|
||||
@ -42,10 +46,15 @@ local function peri_init(iface)
|
||||
last_fault = "",
|
||||
fault_counts = {},
|
||||
auto_cf = true,
|
||||
type = peripheral.getType(iface),
|
||||
device = peripheral.wrap(iface)
|
||||
type = VIRTUAL_DEVICE_TYPE,
|
||||
device = {}
|
||||
}
|
||||
|
||||
if iface ~= "__virtual__" then
|
||||
self.type = peripheral.getType(iface)
|
||||
self.device = peripheral.wrap(iface)
|
||||
end
|
||||
|
||||
-- initialization process (re-map)
|
||||
|
||||
for key, func in pairs(self.device) do
|
||||
@ -245,6 +254,19 @@ function ppm.mount(iface)
|
||||
return pm_type, pm_dev
|
||||
end
|
||||
|
||||
-- mount a virtual, placeholder device (specifically designed for RTU startup with missing devices)
|
||||
---@return string type, table device
|
||||
function ppm.mount_virtual()
|
||||
local iface = "ppm_vdev_" .. _ppm_sys.next_vid
|
||||
|
||||
_ppm_sys.mounts[iface] = peri_init("__virtual__")
|
||||
_ppm_sys.next_vid = _ppm_sys.next_vid + 1
|
||||
|
||||
log.info(util.c("PPM: mount_virtual() -> allocated new virtual device ", iface))
|
||||
|
||||
return _ppm_sys.mounts[iface].type, _ppm_sys.mounts[iface].dev
|
||||
end
|
||||
|
||||
-- manually unmount a peripheral from the PPM
|
||||
---@param device table device table
|
||||
function ppm.unmount(device)
|
||||
|
@ -89,8 +89,12 @@ function rtu.new_session(id, in_queue, out_queue, advertisement, facility_units)
|
||||
|
||||
-- parse the recorded advertisement and create unit sub-sessions
|
||||
local function _handle_advertisement()
|
||||
self.units = {}
|
||||
self.rs_io_q = {}
|
||||
_reset_config()
|
||||
|
||||
for i = 1, #self.f_units do
|
||||
local unit = self.f_units[i] ---@type reactor_unit
|
||||
unit.purge_rtu_devices(self.id)
|
||||
end
|
||||
|
||||
for i = 1, #self.advert do
|
||||
local unit = nil ---@type unit_session|nil
|
||||
@ -130,6 +134,7 @@ function rtu.new_session(id, in_queue, out_queue, advertisement, facility_units)
|
||||
|
||||
if u_type == false then
|
||||
-- validation fail
|
||||
log.debug(log_header .. "advertisement unit validation failure")
|
||||
else
|
||||
local target_unit = self.f_units[unit_advert.reactor] ---@type reactor_unit
|
||||
|
||||
@ -285,8 +290,13 @@ function rtu.new_session(id, in_queue, out_queue, advertisement, facility_units)
|
||||
_close()
|
||||
elseif pkt.type == SCADA_MGMT_TYPES.RTU_ADVERT then
|
||||
-- RTU unit advertisement
|
||||
-- handle advertisement; this will re-create all unit sub-sessions
|
||||
log.debug(log_header .. "received updated advertisement")
|
||||
|
||||
-- copy advertisement and remove version tag
|
||||
self.advert = pkt.data
|
||||
table.remove(self.advert, 1)
|
||||
|
||||
-- handle advertisement; this will re-create all unit sub-sessions
|
||||
_handle_advertisement()
|
||||
elseif pkt.type == SCADA_MGMT_TYPES.RTU_DEV_REMOUNT then
|
||||
if pkt.length == 1 then
|
||||
|
@ -46,7 +46,7 @@ function boilerv.new(session_id, unit_id, advert, out_queue)
|
||||
local log_tag = "session.rtu(" .. session_id .. ").boilerv(" .. advert.index .. "): "
|
||||
|
||||
local self = {
|
||||
session = unit_session.new(unit_id, advert, out_queue, log_tag, TXN_TAGS),
|
||||
session = unit_session.new(session_id, unit_id, advert, out_queue, log_tag, TXN_TAGS),
|
||||
has_build = false,
|
||||
periodics = {
|
||||
next_formed_req = 0,
|
||||
|
@ -37,7 +37,7 @@ function envd.new(session_id, unit_id, advert, out_queue)
|
||||
local log_tag = "session.rtu(" .. session_id .. ").envd(" .. advert.index .. "): "
|
||||
|
||||
local self = {
|
||||
session = unit_session.new(unit_id, advert, out_queue, log_tag, TXN_TAGS),
|
||||
session = unit_session.new(session_id, unit_id, advert, out_queue, log_tag, TXN_TAGS),
|
||||
periodics = {
|
||||
next_rad_req = 0
|
||||
},
|
||||
|
@ -46,7 +46,7 @@ function imatrix.new(session_id, unit_id, advert, out_queue)
|
||||
local log_tag = "session.rtu(" .. session_id .. ").imatrix(" .. advert.index .. "): "
|
||||
|
||||
local self = {
|
||||
session = unit_session.new(unit_id, advert, out_queue, log_tag, TXN_TAGS),
|
||||
session = unit_session.new(session_id, unit_id, advert, out_queue, log_tag, TXN_TAGS),
|
||||
has_build = false,
|
||||
periodics = {
|
||||
next_formed_req = 0,
|
||||
|
@ -61,7 +61,7 @@ function redstone.new(session_id, unit_id, advert, out_queue)
|
||||
local log_tag = "session.rtu(" .. session_id .. ").redstone(" .. unit_id .. "): "
|
||||
|
||||
local self = {
|
||||
session = unit_session.new(unit_id, advert, out_queue, log_tag, TXN_TAGS),
|
||||
session = unit_session.new(session_id, unit_id, advert, out_queue, log_tag, TXN_TAGS),
|
||||
in_q = mqueue.new(),
|
||||
has_di = false,
|
||||
has_ai = false,
|
||||
|
@ -43,7 +43,7 @@ function sna.new(session_id, unit_id, advert, out_queue)
|
||||
local log_tag = "session.rtu(" .. session_id .. ").sna(" .. advert.index .. "): "
|
||||
|
||||
local self = {
|
||||
session = unit_session.new(unit_id, advert, out_queue, log_tag, TXN_TAGS),
|
||||
session = unit_session.new(session_id, unit_id, advert, out_queue, log_tag, TXN_TAGS),
|
||||
has_build = false,
|
||||
periodics = {
|
||||
next_build_req = 0,
|
||||
|
@ -46,7 +46,7 @@ function sps.new(session_id, unit_id, advert, out_queue)
|
||||
local log_tag = "session.rtu(" .. session_id .. ").sps(" .. advert.index .. "): "
|
||||
|
||||
local self = {
|
||||
session = unit_session.new(unit_id, advert, out_queue, log_tag, TXN_TAGS),
|
||||
session = unit_session.new(session_id, unit_id, advert, out_queue, log_tag, TXN_TAGS),
|
||||
has_build = false,
|
||||
periodics = {
|
||||
next_formed_req = 0,
|
||||
|
@ -66,7 +66,7 @@ function turbinev.new(session_id, unit_id, advert, out_queue)
|
||||
local log_tag = "session.rtu(" .. session_id .. ").turbinev(" .. advert.index .. "): "
|
||||
|
||||
local self = {
|
||||
session = unit_session.new(unit_id, advert, out_queue, log_tag, TXN_TAGS),
|
||||
session = unit_session.new(session_id, unit_id, advert, out_queue, log_tag, TXN_TAGS),
|
||||
in_q = mqueue.new(),
|
||||
has_build = false,
|
||||
periodics = {
|
||||
|
@ -22,12 +22,13 @@ unit_session.RTU_US_CMDS = RTU_US_CMDS
|
||||
unit_session.RTU_US_DATA = RTU_US_DATA
|
||||
|
||||
-- create a new unit session runner
|
||||
---@param session_id integer RTU session ID
|
||||
---@param unit_id integer MODBUS unit ID
|
||||
---@param advert rtu_advertisement RTU advertisement for this unit
|
||||
---@param out_queue mqueue send queue
|
||||
---@param log_tag string logging tag
|
||||
---@param txn_tags table transaction log tags
|
||||
function unit_session.new(unit_id, advert, out_queue, log_tag, txn_tags)
|
||||
function unit_session.new(session_id, unit_id, advert, out_queue, log_tag, txn_tags)
|
||||
local self = {
|
||||
log_tag = log_tag,
|
||||
txn_tags = txn_tags,
|
||||
@ -132,6 +133,8 @@ function unit_session.new(unit_id, advert, out_queue, log_tag, txn_tags)
|
||||
|
||||
-- PUBLIC FUNCTIONS --
|
||||
|
||||
-- get the unit ID
|
||||
function public.get_session_id() return session_id end
|
||||
-- get the unit ID
|
||||
function public.get_unit_id() return self.unit_id end
|
||||
-- get the device index
|
||||
|
@ -401,6 +401,14 @@ function unit.new(for_reactor, num_boilers, num_turbines)
|
||||
table.insert(self.redstone[field], accessor)
|
||||
end
|
||||
|
||||
-- purge devices associated with the given RTU session ID
|
||||
---@param session integer RTU session ID
|
||||
function public.purge_rtu_devices(session)
|
||||
util.filter_table(self.turbines, function (s) return s.get_session_id() ~= session end)
|
||||
util.filter_table(self.boilers, function (s) return s.get_session_id() ~= session end)
|
||||
util.filter_table(self.redstone, function (s) return s.get_session_id() ~= session end)
|
||||
end
|
||||
|
||||
-- UPDATE SESSION --
|
||||
|
||||
-- update (iterate) this unit
|
||||
|
@ -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.7.3"
|
||||
local SUPERVISOR_VERSION = "beta-v0.7.4"
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
|
Loading…
Reference in New Issue
Block a user