#118 refactored RTU unit types
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
local comms = require("scada-common.comms")
|
||||
local ppm = require("scada-common.ppm")
|
||||
local log = require("scada-common.log")
|
||||
local types = require("scada-common.types")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local modbus = require("rtu.modbus")
|
||||
@@ -11,7 +12,7 @@ local PROTOCOL = comms.PROTOCOL
|
||||
local DEVICE_TYPE = comms.DEVICE_TYPE
|
||||
local ESTABLISH_ACK = comms.ESTABLISH_ACK
|
||||
local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE
|
||||
local RTU_UNIT_TYPE = comms.RTU_UNIT_TYPE
|
||||
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
@@ -223,12 +224,11 @@ function rtu.comms(version, modem, local_port, server_port, range, conn_watchdog
|
||||
local advertisement = {}
|
||||
|
||||
for i = 1, #units do
|
||||
local unit = units[i] --@type rtu_unit_registry_entry
|
||||
local type = comms.rtu_t_to_unit_type(unit.type)
|
||||
local unit = units[i] ---@type rtu_unit_registry_entry
|
||||
|
||||
if type ~= nil then
|
||||
local advert = {
|
||||
type,
|
||||
unit.type,
|
||||
unit.index,
|
||||
unit.reactor
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ local turbinev_rtu = require("rtu.dev.turbinev_rtu")
|
||||
|
||||
local RTU_VERSION = "beta-v0.11.2"
|
||||
|
||||
local rtu_t = types.rtu_t
|
||||
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
@@ -151,7 +151,7 @@ local function main()
|
||||
-- check for duplicate entries
|
||||
for i = 1, #units do
|
||||
local unit = units[i] ---@type rtu_unit_registry_entry
|
||||
if unit.reactor == io_reactor and unit.type == rtu_t.redstone then
|
||||
if unit.reactor == io_reactor and unit.type == RTU_UNIT_TYPE.REDSTONE then
|
||||
-- duplicate entry
|
||||
local message = util.c("configure> skipping definition block #", entry_idx, " for reactor ", io_reactor,
|
||||
" with already defined redstone I/O")
|
||||
@@ -224,23 +224,28 @@ local function main()
|
||||
|
||||
---@class rtu_unit_registry_entry
|
||||
local unit = {
|
||||
uid = 0,
|
||||
name = "redstone_io",
|
||||
type = rtu_t.redstone,
|
||||
index = entry_idx,
|
||||
reactor = io_reactor,
|
||||
device = capabilities, -- use device field for redstone ports
|
||||
is_multiblock = false,
|
||||
formed = nil, ---@type boolean|nil
|
||||
rtu = rs_rtu, ---@type rtu_device|rtu_rs_device
|
||||
uid = 0, ---@type integer
|
||||
name = "redstone_io", ---@type string
|
||||
type = RTU_UNIT_TYPE.REDSTONE, ---@type RTU_UNIT_TYPE
|
||||
index = entry_idx, ---@type integer
|
||||
reactor = io_reactor, ---@type integer
|
||||
device = capabilities, ---@type table use device field for redstone ports
|
||||
is_multiblock = false, ---@type boolean
|
||||
formed = nil, ---@type boolean|nil
|
||||
rtu = rs_rtu, ---@type rtu_device|rtu_rs_device
|
||||
modbus_io = modbus.new(rs_rtu, false),
|
||||
pkt_queue = nil, ---@type mqueue|nil
|
||||
thread = nil
|
||||
pkt_queue = nil, ---@type mqueue|nil
|
||||
thread = nil ---@type parallel_thread|nil
|
||||
}
|
||||
|
||||
table.insert(units, unit)
|
||||
|
||||
log.debug(util.c("init> initialized RTU unit #", #units, ": redstone_io (redstone) [1] for reactor ", io_reactor))
|
||||
local for_message = "facility"
|
||||
if io_reactor > 0 then
|
||||
for_message = util.c("reactor ", io_reactor)
|
||||
end
|
||||
|
||||
log.debug(util.c("configure> initialized RTU unit #", #units, ": redstone_io (redstone) [1] for ", for_message))
|
||||
|
||||
unit.uid = #units
|
||||
end
|
||||
@@ -274,7 +279,7 @@ local function main()
|
||||
|
||||
local type = nil
|
||||
local rtu_iface = nil ---@type rtu_device
|
||||
local rtu_type = ""
|
||||
local rtu_type = nil ---@type RTU_UNIT_TYPE
|
||||
local is_multiblock = false
|
||||
local formed = nil ---@type boolean|nil
|
||||
|
||||
@@ -291,7 +296,7 @@ local function main()
|
||||
|
||||
if type == "boilerValve" then
|
||||
-- boiler multiblock
|
||||
rtu_type = rtu_t.boiler_valve
|
||||
rtu_type = RTU_UNIT_TYPE.BOILER_VALVE
|
||||
rtu_iface = boilerv_rtu.new(device)
|
||||
is_multiblock = true
|
||||
formed = device.isFormed()
|
||||
@@ -303,7 +308,7 @@ local function main()
|
||||
end
|
||||
elseif type == "turbineValve" then
|
||||
-- turbine multiblock
|
||||
rtu_type = rtu_t.turbine_valve
|
||||
rtu_type = RTU_UNIT_TYPE.TURBINE_VALVE
|
||||
rtu_iface = turbinev_rtu.new(device)
|
||||
is_multiblock = true
|
||||
formed = device.isFormed()
|
||||
@@ -315,7 +320,7 @@ local function main()
|
||||
end
|
||||
elseif type == "inductionPort" then
|
||||
-- induction matrix multiblock
|
||||
rtu_type = rtu_t.induction_matrix
|
||||
rtu_type = RTU_UNIT_TYPE.IMATRIX
|
||||
rtu_iface = imatrix_rtu.new(device)
|
||||
is_multiblock = true
|
||||
formed = device.isFormed()
|
||||
@@ -327,7 +332,7 @@ local function main()
|
||||
end
|
||||
elseif type == "spsPort" then
|
||||
-- SPS multiblock
|
||||
rtu_type = rtu_t.sps
|
||||
rtu_type = RTU_UNIT_TYPE.SPS
|
||||
rtu_iface = sps_rtu.new(device)
|
||||
is_multiblock = true
|
||||
formed = device.isFormed()
|
||||
@@ -339,15 +344,15 @@ local function main()
|
||||
end
|
||||
elseif type == "solarNeutronActivator" then
|
||||
-- SNA
|
||||
rtu_type = rtu_t.sna
|
||||
rtu_type = RTU_UNIT_TYPE.SNA
|
||||
rtu_iface = sna_rtu.new(device)
|
||||
elseif type == "environmentDetector" then
|
||||
-- advanced peripherals environment detector
|
||||
rtu_type = rtu_t.env_detector
|
||||
rtu_type = RTU_UNIT_TYPE.ENV_DETECTOR
|
||||
rtu_iface = envd_rtu.new(device)
|
||||
elseif type == ppm.VIRTUAL_DEVICE_TYPE then
|
||||
-- placeholder device
|
||||
rtu_type = "virtual"
|
||||
rtu_type = RTU_UNIT_TYPE.VIRTUAL
|
||||
rtu_iface = rtu.init_unit().interface()
|
||||
else
|
||||
local message = util.c("configure> device '", name, "' is not a known type (", type, ")")
|
||||
@@ -358,18 +363,18 @@ local function main()
|
||||
|
||||
---@class rtu_unit_registry_entry
|
||||
local rtu_unit = {
|
||||
uid = 0,
|
||||
name = name,
|
||||
type = rtu_type,
|
||||
index = index,
|
||||
reactor = for_reactor,
|
||||
device = device,
|
||||
is_multiblock = is_multiblock,
|
||||
uid = 0, ---@type integer
|
||||
name = name, ---@type string
|
||||
type = rtu_type, ---@type RTU_UNIT_TYPE
|
||||
index = index, ---@type integer
|
||||
reactor = for_reactor, ---@type integer
|
||||
device = device, ---@type table
|
||||
is_multiblock = is_multiblock, ---@type boolean
|
||||
formed = formed, ---@type boolean|nil
|
||||
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
|
||||
thread = nil ---@type parallel_thread|nil
|
||||
}
|
||||
|
||||
rtu_unit.thread = threads.thread__unit_comms(__shared_memory, rtu_unit)
|
||||
@@ -385,7 +390,7 @@ local function main()
|
||||
for_message = util.c("reactor ", for_reactor)
|
||||
end
|
||||
|
||||
log.debug(util.c("configure> initialized RTU unit #", #units, ": ", name, " (", rtu_type, ") [", index, "] for ", for_message))
|
||||
log.debug(util.c("configure> initialized RTU unit #", #units, ": ", name, " (", types.rtu_type_to_string(rtu_type), ") [", index, "] for ", for_message))
|
||||
|
||||
rtu_unit.uid = #units
|
||||
end
|
||||
|
||||
@@ -15,7 +15,7 @@ local modbus = require("rtu.modbus")
|
||||
|
||||
local threads = {}
|
||||
|
||||
local rtu_t = types.rtu_t
|
||||
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
@@ -28,7 +28,8 @@ local COMMS_SLEEP = 100 -- (100ms, 2 ticks)
|
||||
-- main thread
|
||||
---@param smem rtu_shared_memory
|
||||
function threads.thread__main(smem)
|
||||
local public = {} ---@class thread
|
||||
---@class parallel_thread
|
||||
local public = {}
|
||||
|
||||
-- execute thread
|
||||
function public.exec()
|
||||
@@ -93,8 +94,9 @@ function threads.thread__main(smem)
|
||||
-- we are going to let the PPM prevent crashes
|
||||
-- return fault flags/codes to MODBUS queries
|
||||
local unit = units[i]
|
||||
println_ts(util.c("lost the ", unit.type, " on interface ", unit.name))
|
||||
log.warning(util.c("lost the ", unit.type, " unit peripheral on interface ", unit.name))
|
||||
local type_name = types.rtu_type_to_string(unit.type)
|
||||
println_ts(util.c("lost the ", type_name, " on interface ", unit.name))
|
||||
log.warning(util.c("lost the ", type_name, " unit peripheral on interface ", unit.name))
|
||||
break
|
||||
end
|
||||
end
|
||||
@@ -129,51 +131,51 @@ function threads.thread__main(smem)
|
||||
-- found, re-link
|
||||
unit.device = device
|
||||
|
||||
if unit.type == "virtual" then
|
||||
if unit.type == RTU_UNIT_TYPE.VIRTUAL then
|
||||
resend_advert = true
|
||||
if type == "boilerValve" then
|
||||
-- boiler multiblock
|
||||
unit.type = rtu_t.boiler_valve
|
||||
unit.type = RTU_UNIT_TYPE.BOILER_VALVE
|
||||
elseif type == "turbineValve" then
|
||||
-- turbine multiblock
|
||||
unit.type = rtu_t.turbine_valve
|
||||
unit.type = RTU_UNIT_TYPE.TURBINE_VALVE
|
||||
elseif type == "inductionPort" then
|
||||
-- induction matrix multiblock
|
||||
unit.type = rtu_t.induction_matrix
|
||||
unit.type = RTU_UNIT_TYPE.IMATRIX
|
||||
elseif type == "spsPort" then
|
||||
-- SPS multiblock
|
||||
unit.type = rtu_t.sps
|
||||
unit.type = RTU_UNIT_TYPE.SPS
|
||||
elseif type == "solarNeutronActivator" then
|
||||
-- SNA
|
||||
unit.type = rtu_t.sna
|
||||
unit.type = RTU_UNIT_TYPE.SNA
|
||||
elseif type == "environmentDetector" then
|
||||
-- advanced peripherals environment detector
|
||||
unit.type = rtu_t.env_detector
|
||||
unit.type = RTU_UNIT_TYPE.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
|
||||
if unit.type == RTU_UNIT_TYPE.BOILER_VALVE then
|
||||
unit.rtu = boilerv_rtu.new(device)
|
||||
-- if not formed, indexing the multiblock functions would have resulted in a PPM fault
|
||||
unit.formed = util.trinary(device.__p_is_faulted(), false, nil)
|
||||
elseif unit.type == rtu_t.turbine_valve then
|
||||
elseif unit.type == RTU_UNIT_TYPE.TURBINE_VALVE then
|
||||
unit.rtu = turbinev_rtu.new(device)
|
||||
-- if not formed, indexing the multiblock functions would have resulted in a PPM fault
|
||||
unit.formed = util.trinary(device.__p_is_faulted(), false, nil)
|
||||
elseif unit.type == rtu_t.induction_matrix then
|
||||
elseif unit.type == RTU_UNIT_TYPE.IMATRIX then
|
||||
unit.rtu = imatrix_rtu.new(device)
|
||||
-- if not formed, indexing the multiblock functions would have resulted in a PPM fault
|
||||
unit.formed = util.trinary(device.__p_is_faulted(), false, nil)
|
||||
elseif unit.type == rtu_t.sps then
|
||||
elseif unit.type == RTU_UNIT_TYPE.SPS then
|
||||
unit.rtu = sps_rtu.new(device)
|
||||
-- if not formed, indexing the multiblock functions would have resulted in a PPM fault
|
||||
unit.formed = util.trinary(device.__p_is_faulted(), false, nil)
|
||||
elseif unit.type == rtu_t.sna then
|
||||
elseif unit.type == RTU_UNIT_TYPE.SNA then
|
||||
unit.rtu = sna_rtu.new(device)
|
||||
elseif unit.type == rtu_t.env_detector then
|
||||
elseif unit.type == RTU_UNIT_TYPE.ENV_DETECTOR then
|
||||
unit.rtu = envd_rtu.new(device)
|
||||
else
|
||||
log.error(util.c("failed to identify reconnected RTU unit type (", unit.name, ")"), true)
|
||||
@@ -185,8 +187,10 @@ function threads.thread__main(smem)
|
||||
|
||||
unit.modbus_io = modbus.new(unit.rtu, true)
|
||||
|
||||
println_ts("reconnected the " .. unit.type .. " on interface " .. unit.name)
|
||||
log.info("reconnected the " .. unit.type .. " on interface " .. unit.name)
|
||||
local type_name = types.rtu_type_to_string(unit.type)
|
||||
local message = util.c("reconnected the ", type_name, " on interface ", unit.name)
|
||||
println_ts(message)
|
||||
log.info(message)
|
||||
|
||||
if resend_advert then
|
||||
rtu_comms.send_advertisement(units)
|
||||
@@ -231,7 +235,8 @@ end
|
||||
-- communications handler thread
|
||||
---@param smem rtu_shared_memory
|
||||
function threads.thread__comms(smem)
|
||||
local public = {} ---@class thread
|
||||
---@class parallel_thread
|
||||
local public = {}
|
||||
|
||||
-- execute thread
|
||||
function public.exec()
|
||||
@@ -304,11 +309,12 @@ end
|
||||
---@param smem rtu_shared_memory
|
||||
---@param unit rtu_unit_registry_entry
|
||||
function threads.thread__unit_comms(smem, unit)
|
||||
local public = {} ---@class thread
|
||||
---@class parallel_thread
|
||||
local public = {}
|
||||
|
||||
-- execute thread
|
||||
function public.exec()
|
||||
log.debug("rtu unit thread start -> " .. unit.type .. "(" .. unit.name .. ")")
|
||||
log.debug(util.c("rtu unit thread start -> ", types.rtu_type_to_string(unit.type), "(", unit.name, ")"))
|
||||
|
||||
-- load in from shared memory
|
||||
local rtu_state = smem.rtu_state
|
||||
@@ -319,8 +325,8 @@ function threads.thread__unit_comms(smem, unit)
|
||||
|
||||
local last_f_check = 0
|
||||
|
||||
local detail_name = util.c(unit.type, " (", unit.name, ") [", unit.index, "] for reactor ", unit.reactor)
|
||||
local short_name = util.c(unit.type, " (", unit.name, ")")
|
||||
local detail_name = util.c(types.rtu_type_to_string(unit.type), " (", unit.name, ") [", unit.index, "] for reactor ", unit.reactor)
|
||||
local short_name = util.c(types.rtu_type_to_string(unit.type), " (", unit.name, ")")
|
||||
|
||||
if packet_queue == nil then
|
||||
log.error("rtu unit thread created without a message queue, exiting...", true)
|
||||
@@ -368,25 +374,25 @@ function threads.thread__unit_comms(smem, unit)
|
||||
local type, device = ppm.mount(iface)
|
||||
|
||||
if device ~= nil then
|
||||
if type == "boilerValve" and unit.type == rtu_t.boiler_valve then
|
||||
if type == "boilerValve" and unit.type == RTU_UNIT_TYPE.BOILER_VALVE then
|
||||
-- boiler multiblock
|
||||
unit.device = device
|
||||
unit.rtu = boilerv_rtu.new(device)
|
||||
unit.formed = device.isFormed()
|
||||
unit.modbus_io = modbus.new(unit.rtu, true)
|
||||
elseif type == "turbineValve" and unit.type == rtu_t.turbine_valve then
|
||||
elseif type == "turbineValve" and unit.type == RTU_UNIT_TYPE.TURBINE_VALVE then
|
||||
-- turbine multiblock
|
||||
unit.device = device
|
||||
unit.rtu = turbinev_rtu.new(device)
|
||||
unit.formed = device.isFormed()
|
||||
unit.modbus_io = modbus.new(unit.rtu, true)
|
||||
elseif type == "inductionPort" and unit.type == rtu_t.induction_matrix then
|
||||
elseif type == "inductionPort" and unit.type == RTU_UNIT_TYPE.IMATRIX then
|
||||
-- induction matrix multiblock
|
||||
unit.device = device
|
||||
unit.rtu = imatrix_rtu.new(device)
|
||||
unit.formed = device.isFormed()
|
||||
unit.modbus_io = modbus.new(unit.rtu, true)
|
||||
elseif type == "spsPort" and unit.type == rtu_t.sps then
|
||||
elseif type == "spsPort" and unit.type == RTU_UNIT_TYPE.SPS then
|
||||
-- SPS multiblock
|
||||
unit.device = device
|
||||
unit.rtu = sps_rtu.new(device)
|
||||
@@ -433,7 +439,7 @@ function threads.thread__unit_comms(smem, unit)
|
||||
end
|
||||
|
||||
if not rtu_state.shutdown then
|
||||
log.info(util.c("rtu unit thread ", unit.type, "(", unit.name, " restarting in 5 seconds..."))
|
||||
log.info(util.c("rtu unit thread ", types.rtu_type_to_string(unit.type), "(", unit.name, " restarting in 5 seconds..."))
|
||||
util.psleep(5)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user