#157 fixed bug with RTU remount messages
This commit is contained in:
parent
42ff61a8a1
commit
4d40d08a7a
@ -25,7 +25,7 @@ local sna_rtu = require("rtu.dev.sna_rtu")
|
|||||||
local sps_rtu = require("rtu.dev.sps_rtu")
|
local sps_rtu = require("rtu.dev.sps_rtu")
|
||||||
local turbinev_rtu = require("rtu.dev.turbinev_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
|
local rtu_t = types.rtu_t
|
||||||
|
|
||||||
@ -222,11 +222,13 @@ local function main()
|
|||||||
|
|
||||||
---@class rtu_unit_registry_entry
|
---@class rtu_unit_registry_entry
|
||||||
local unit = {
|
local unit = {
|
||||||
|
uid = 0,
|
||||||
name = "redstone_io",
|
name = "redstone_io",
|
||||||
type = rtu_t.redstone,
|
type = rtu_t.redstone,
|
||||||
index = entry_idx,
|
index = entry_idx,
|
||||||
reactor = io_reactor,
|
reactor = io_reactor,
|
||||||
device = capabilities, -- use device field for redstone ports
|
device = capabilities, -- use device field for redstone ports
|
||||||
|
is_multiblock = false,
|
||||||
formed = nil, ---@type boolean|nil
|
formed = nil, ---@type boolean|nil
|
||||||
rtu = rs_rtu, ---@type rtu_device|rtu_rs_device
|
rtu = rs_rtu, ---@type rtu_device|rtu_rs_device
|
||||||
modbus_io = modbus.new(rs_rtu, false),
|
modbus_io = modbus.new(rs_rtu, false),
|
||||||
@ -237,6 +239,8 @@ local function main()
|
|||||||
table.insert(units, unit)
|
table.insert(units, unit)
|
||||||
|
|
||||||
log.debug(util.c("init> initialized RTU unit #", #units, ": redstone_io (redstone) [1] for reactor ", io_reactor))
|
log.debug(util.c("init> initialized RTU unit #", #units, ": redstone_io (redstone) [1] for reactor ", io_reactor))
|
||||||
|
|
||||||
|
unit.uid = #units
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -269,6 +273,7 @@ local function main()
|
|||||||
local type = nil
|
local type = nil
|
||||||
local rtu_iface = nil ---@type rtu_device
|
local rtu_iface = nil ---@type rtu_device
|
||||||
local rtu_type = ""
|
local rtu_type = ""
|
||||||
|
local is_multiblock = false
|
||||||
local formed = nil ---@type boolean|nil
|
local formed = nil ---@type boolean|nil
|
||||||
|
|
||||||
if device == nil then
|
if device == nil then
|
||||||
@ -286,6 +291,7 @@ local function main()
|
|||||||
-- boiler multiblock
|
-- boiler multiblock
|
||||||
rtu_type = rtu_t.boiler_valve
|
rtu_type = rtu_t.boiler_valve
|
||||||
rtu_iface = boilerv_rtu.new(device)
|
rtu_iface = boilerv_rtu.new(device)
|
||||||
|
is_multiblock = true
|
||||||
formed = device.isFormed()
|
formed = device.isFormed()
|
||||||
|
|
||||||
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
||||||
@ -297,6 +303,7 @@ local function main()
|
|||||||
-- turbine multiblock
|
-- turbine multiblock
|
||||||
rtu_type = rtu_t.turbine_valve
|
rtu_type = rtu_t.turbine_valve
|
||||||
rtu_iface = turbinev_rtu.new(device)
|
rtu_iface = turbinev_rtu.new(device)
|
||||||
|
is_multiblock = true
|
||||||
formed = device.isFormed()
|
formed = device.isFormed()
|
||||||
|
|
||||||
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
||||||
@ -308,6 +315,7 @@ local function main()
|
|||||||
-- induction matrix multiblock
|
-- induction matrix multiblock
|
||||||
rtu_type = rtu_t.induction_matrix
|
rtu_type = rtu_t.induction_matrix
|
||||||
rtu_iface = imatrix_rtu.new(device)
|
rtu_iface = imatrix_rtu.new(device)
|
||||||
|
is_multiblock = true
|
||||||
formed = device.isFormed()
|
formed = device.isFormed()
|
||||||
|
|
||||||
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
||||||
@ -319,6 +327,7 @@ local function main()
|
|||||||
-- SPS multiblock
|
-- SPS multiblock
|
||||||
rtu_type = rtu_t.sps
|
rtu_type = rtu_t.sps
|
||||||
rtu_iface = sps_rtu.new(device)
|
rtu_iface = sps_rtu.new(device)
|
||||||
|
is_multiblock = true
|
||||||
formed = device.isFormed()
|
formed = device.isFormed()
|
||||||
|
|
||||||
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
||||||
@ -347,12 +356,14 @@ local function main()
|
|||||||
|
|
||||||
---@class rtu_unit_registry_entry
|
---@class rtu_unit_registry_entry
|
||||||
local rtu_unit = {
|
local rtu_unit = {
|
||||||
|
uid = 0,
|
||||||
name = name,
|
name = name,
|
||||||
type = rtu_type,
|
type = rtu_type,
|
||||||
index = index,
|
index = index,
|
||||||
reactor = for_reactor,
|
reactor = for_reactor,
|
||||||
device = device,
|
device = device,
|
||||||
formed = formed,
|
is_multiblock = is_multiblock,
|
||||||
|
formed = formed, ---@type boolean|nil
|
||||||
rtu = rtu_iface, ---@type rtu_device|rtu_rs_device
|
rtu = rtu_iface, ---@type rtu_device|rtu_rs_device
|
||||||
modbus_io = modbus.new(rtu_iface, true),
|
modbus_io = modbus.new(rtu_iface, true),
|
||||||
pkt_queue = mqueue.new(), ---@type mqueue|nil
|
pkt_queue = mqueue.new(), ---@type mqueue|nil
|
||||||
@ -373,6 +384,8 @@ local function main()
|
|||||||
end
|
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, " (", rtu_type, ") [", index, "] for ", for_message))
|
||||||
|
|
||||||
|
rtu_unit.uid = #units
|
||||||
end
|
end
|
||||||
|
|
||||||
-- we made it through all that trusting-user-to-write-a-config-file chaos
|
-- we made it through all that trusting-user-to-write-a-config-file chaos
|
||||||
|
|||||||
@ -157,16 +157,20 @@ function threads.thread__main(smem)
|
|||||||
|
|
||||||
if unit.type == rtu_t.boiler_valve then
|
if unit.type == rtu_t.boiler_valve then
|
||||||
unit.rtu = boilerv_rtu.new(device)
|
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
|
elseif unit.type == rtu_t.turbine_valve then
|
||||||
unit.rtu = turbinev_rtu.new(device)
|
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
|
elseif unit.type == rtu_t.induction_matrix then
|
||||||
unit.rtu = imatrix_rtu.new(device)
|
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
|
elseif unit.type == rtu_t.sps then
|
||||||
unit.rtu = sps_rtu.new(device)
|
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
|
elseif unit.type == rtu_t.sna then
|
||||||
unit.rtu = sna_rtu.new(device)
|
unit.rtu = sna_rtu.new(device)
|
||||||
elseif unit.type == rtu_t.env_detector then
|
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)
|
log.error(util.c("failed to identify reconnected RTU unit type (", unit.name, ")"), true)
|
||||||
end
|
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)
|
unit.modbus_io = modbus.new(unit.rtu, true)
|
||||||
|
|
||||||
println_ts("reconnected the " .. unit.type .. " on interface " .. unit.name)
|
println_ts("reconnected the " .. unit.type .. " on interface " .. unit.name)
|
||||||
@ -183,7 +191,7 @@ function threads.thread__main(smem)
|
|||||||
if resend_advert then
|
if resend_advert then
|
||||||
rtu_comms.send_advertisement(units)
|
rtu_comms.send_advertisement(units)
|
||||||
else
|
else
|
||||||
rtu_comms.send_remounted(unit.index)
|
rtu_comms.send_remounted(unit.uid)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -342,9 +350,13 @@ function threads.thread__unit_comms(smem, unit)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- check if multiblock is still formed if this is a multiblock
|
-- 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()
|
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
|
if (not unit.formed) and is_formed then
|
||||||
-- newly re-formed
|
-- newly re-formed
|
||||||
local iface = ppm.get_iface(unit.device)
|
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)
|
log.error("illegal remount of non-multiblock RTU attempted for " .. short_name, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
rtu_comms.send_remounted(unit.index)
|
rtu_comms.send_remounted(unit.uid)
|
||||||
else
|
else
|
||||||
-- fully lost the peripheral now :(
|
-- fully lost the peripheral now :(
|
||||||
log.error(util.c(unit.name, " lost (failed reconnect)"))
|
log.error(util.c(unit.name, " lost (failed reconnect)"))
|
||||||
end
|
end
|
||||||
|
|
||||||
log.info("reconnected the " .. unit.type .. " on interface " .. unit.name)
|
log.info(util.c("reconnected the ", unit.type, " on interface ", unit.name))
|
||||||
else
|
else
|
||||||
log.error("failed to get interface of previously connected RTU unit " .. detail_name, true)
|
log.error("failed to get interface of previously connected RTU unit " .. detail_name, true)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -265,7 +265,7 @@ function rtu.new_session(id, in_queue, out_queue, advertisement, facility)
|
|||||||
_handle_advertisement()
|
_handle_advertisement()
|
||||||
elseif pkt.type == SCADA_MGMT_TYPES.RTU_DEV_REMOUNT then
|
elseif pkt.type == SCADA_MGMT_TYPES.RTU_DEV_REMOUNT then
|
||||||
if pkt.length == 1 then
|
if pkt.length == 1 then
|
||||||
local unit_id = pkt[1]
|
local unit_id = pkt.data[1]
|
||||||
if self.units[unit_id] ~= nil then
|
if self.units[unit_id] ~= nil then
|
||||||
local unit = self.units[unit_id] ---@type unit_session
|
local unit = self.units[unit_id] ---@type unit_session
|
||||||
unit.invalidate_cache()
|
unit.invalidate_cache()
|
||||||
|
|||||||
@ -137,6 +137,8 @@ function boilerv.new(session_id, unit_id, advert, out_queue)
|
|||||||
-- load in data if correct length
|
-- load in data if correct length
|
||||||
if m_pkt.length == 1 then
|
if m_pkt.length == 1 then
|
||||||
self.db.formed = m_pkt.data[1]
|
self.db.formed = m_pkt.data[1]
|
||||||
|
|
||||||
|
if not self.db.formed then self.has_build = false end
|
||||||
else
|
else
|
||||||
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
|
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
|
||||||
end
|
end
|
||||||
|
|||||||
@ -124,6 +124,8 @@ function imatrix.new(session_id, unit_id, advert, out_queue)
|
|||||||
-- load in data if correct length
|
-- load in data if correct length
|
||||||
if m_pkt.length == 1 then
|
if m_pkt.length == 1 then
|
||||||
self.db.formed = m_pkt.data[1]
|
self.db.formed = m_pkt.data[1]
|
||||||
|
|
||||||
|
if not self.db.formed then self.has_build = false end
|
||||||
else
|
else
|
||||||
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
|
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
|
||||||
end
|
end
|
||||||
|
|||||||
@ -129,6 +129,8 @@ function sps.new(session_id, unit_id, advert, out_queue)
|
|||||||
-- load in data if correct length
|
-- load in data if correct length
|
||||||
if m_pkt.length == 1 then
|
if m_pkt.length == 1 then
|
||||||
self.db.formed = m_pkt.data[1]
|
self.db.formed = m_pkt.data[1]
|
||||||
|
|
||||||
|
if not self.db.formed then self.has_build = false end
|
||||||
else
|
else
|
||||||
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
|
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
|
||||||
end
|
end
|
||||||
|
|||||||
@ -166,6 +166,8 @@ function turbinev.new(session_id, unit_id, advert, out_queue)
|
|||||||
-- load in data if correct length
|
-- load in data if correct length
|
||||||
if m_pkt.length == 1 then
|
if m_pkt.length == 1 then
|
||||||
self.db.formed = m_pkt.data[1]
|
self.db.formed = m_pkt.data[1]
|
||||||
|
|
||||||
|
if not self.db.formed then self.has_build = false end
|
||||||
else
|
else
|
||||||
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
|
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
|
||||||
end
|
end
|
||||||
|
|||||||
@ -14,7 +14,7 @@ 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.11.0"
|
local SUPERVISOR_VERSION = "beta-v0.11.1"
|
||||||
|
|
||||||
local print = util.print
|
local print = util.print
|
||||||
local println = util.println
|
local println = util.println
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user