#157 fixed bug with RTU remount messages

This commit is contained in:
Mikayla Fischler 2023-02-12 13:06:44 -05:00
parent 42ff61a8a1
commit 4d40d08a7a
8 changed files with 49 additions and 16 deletions

View File

@ -25,7 +25,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.10.2"
local RTU_VERSION = "beta-v0.10.3"
local rtu_t = types.rtu_t
@ -222,11 +222,13 @@ 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
modbus_io = modbus.new(rs_rtu, false),
@ -237,6 +239,8 @@ local function main()
table.insert(units, unit)
log.debug(util.c("init> initialized RTU unit #", #units, ": redstone_io (redstone) [1] for reactor ", io_reactor))
unit.uid = #units
end
end
@ -267,9 +271,10 @@ local function main()
local device = ppm.get_periph(name)
local type = nil
local rtu_iface = nil ---@type rtu_device
local rtu_iface = nil ---@type rtu_device
local rtu_type = ""
local formed = nil ---@type boolean|nil
local is_multiblock = false
local formed = nil ---@type boolean|nil
if device == nil then
local message = util.c("configure> '", name, "' not found, using placeholder")
@ -286,6 +291,7 @@ local function main()
-- boiler multiblock
rtu_type = rtu_t.boiler_valve
rtu_iface = boilerv_rtu.new(device)
is_multiblock = true
formed = device.isFormed()
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
@ -297,6 +303,7 @@ local function main()
-- turbine multiblock
rtu_type = rtu_t.turbine_valve
rtu_iface = turbinev_rtu.new(device)
is_multiblock = true
formed = device.isFormed()
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
@ -308,6 +315,7 @@ local function main()
-- induction matrix multiblock
rtu_type = rtu_t.induction_matrix
rtu_iface = imatrix_rtu.new(device)
is_multiblock = true
formed = device.isFormed()
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
@ -319,6 +327,7 @@ local function main()
-- SPS multiblock
rtu_type = rtu_t.sps
rtu_iface = sps_rtu.new(device)
is_multiblock = true
formed = device.isFormed()
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
@ -347,15 +356,17 @@ 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,
formed = formed,
rtu = rtu_iface, ---@type rtu_device|rtu_rs_device
is_multiblock = is_multiblock,
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
pkt_queue = mqueue.new(), ---@type mqueue|nil
thread = nil
}
@ -373,6 +384,8 @@ local function main()
end
log.debug(util.c("configure> initialized RTU unit #", #units, ": ", name, " (", rtu_type, ") [", index, "] for ", for_message))
rtu_unit.uid = #units
end
-- we made it through all that trusting-user-to-write-a-config-file chaos

View File

@ -157,16 +157,20 @@ function threads.thread__main(smem)
if unit.type == rtu_t.boiler_valve then
unit.rtu = boilerv_rtu.new(device)
unit.formed = true
-- 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
unit.rtu = turbinev_rtu.new(device)
unit.formed = true
-- 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
unit.rtu = imatrix_rtu.new(device)
unit.formed = true
-- 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
unit.rtu = sps_rtu.new(device)
unit.formed = true
-- 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
unit.rtu = sna_rtu.new(device)
elseif unit.type == rtu_t.env_detector then
@ -175,6 +179,10 @@ function threads.thread__main(smem)
log.error(util.c("failed to identify reconnected RTU unit type (", unit.name, ")"), true)
end
if unit.is_multiblock and (unit.formed == false) then
log.info(util.c("assuming ", unit.name, " is not formed due to PPM faults while initializing"))
end
unit.modbus_io = modbus.new(unit.rtu, true)
println_ts("reconnected the " .. unit.type .. " on interface " .. unit.name)
@ -183,7 +191,7 @@ function threads.thread__main(smem)
if resend_advert then
rtu_comms.send_advertisement(units)
else
rtu_comms.send_remounted(unit.index)
rtu_comms.send_remounted(unit.uid)
end
end
end
@ -342,9 +350,13 @@ function threads.thread__unit_comms(smem, unit)
end
-- 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 unit.is_multiblock and (util.time_ms() - last_f_check > 250) then
local is_formed = unit.device.isFormed()
last_f_check = util.time_ms()
if unit.formed == nil then unit.formed = is_formed end
if (not unit.formed) and is_formed then
-- newly re-formed
local iface = ppm.get_iface(unit.device)
@ -384,13 +396,13 @@ function threads.thread__unit_comms(smem, unit)
log.error("illegal remount of non-multiblock RTU attempted for " .. short_name, true)
end
rtu_comms.send_remounted(unit.index)
rtu_comms.send_remounted(unit.uid)
else
-- fully lost the peripheral now :(
log.error(util.c(unit.name, " lost (failed reconnect)"))
end
log.info("reconnected the " .. unit.type .. " on interface " .. unit.name)
log.info(util.c("reconnected the ", unit.type, " on interface ", unit.name))
else
log.error("failed to get interface of previously connected RTU unit " .. detail_name, true)
end

View File

@ -265,7 +265,7 @@ function rtu.new_session(id, in_queue, out_queue, advertisement, facility)
_handle_advertisement()
elseif pkt.type == SCADA_MGMT_TYPES.RTU_DEV_REMOUNT then
if pkt.length == 1 then
local unit_id = pkt[1]
local unit_id = pkt.data[1]
if self.units[unit_id] ~= nil then
local unit = self.units[unit_id] ---@type unit_session
unit.invalidate_cache()

View File

@ -137,6 +137,8 @@ function boilerv.new(session_id, unit_id, advert, out_queue)
-- load in data if correct length
if m_pkt.length == 1 then
self.db.formed = m_pkt.data[1]
if not self.db.formed then self.has_build = false end
else
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
end

View File

@ -124,6 +124,8 @@ function imatrix.new(session_id, unit_id, advert, out_queue)
-- load in data if correct length
if m_pkt.length == 1 then
self.db.formed = m_pkt.data[1]
if not self.db.formed then self.has_build = false end
else
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
end

View File

@ -129,6 +129,8 @@ function sps.new(session_id, unit_id, advert, out_queue)
-- load in data if correct length
if m_pkt.length == 1 then
self.db.formed = m_pkt.data[1]
if not self.db.formed then self.has_build = false end
else
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
end

View File

@ -166,6 +166,8 @@ function turbinev.new(session_id, unit_id, advert, out_queue)
-- load in data if correct length
if m_pkt.length == 1 then
self.db.formed = m_pkt.data[1]
if not self.db.formed then self.has_build = false end
else
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
end

View File

@ -14,7 +14,7 @@ local svsessions = require("supervisor.session.svsessions")
local config = require("supervisor.config")
local supervisor = require("supervisor.supervisor")
local SUPERVISOR_VERSION = "beta-v0.11.0"
local SUPERVISOR_VERSION = "beta-v0.11.1"
local print = util.print
local println = util.println