mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
#31 PPM cannot assume that we will get a fault on failure, apparently sometimes we will only get a nil return so the system can no longer check ACCESS_OK, now each device has its own fault tracking
This commit is contained in:
parent
416255f41a
commit
86b0d155fa
@ -131,7 +131,8 @@ function iss_init(reactor)
|
||||
log._warning("ISS: reactor SCRAM")
|
||||
self.tripped = true
|
||||
self.trip_cause = status
|
||||
if self.reactor.scram() == ppm.ACCESS_FAULT then
|
||||
self.reactor.scram()
|
||||
if self.reactor.__p_is_faulted() then
|
||||
log._error("ISS: failed reactor SCRAM")
|
||||
end
|
||||
end
|
||||
@ -420,12 +421,14 @@ function comms_init(id, modem, local_port, server_port, reactor, iss)
|
||||
-- disable the reactor
|
||||
self.scrammed = true
|
||||
plc_state.scram = true
|
||||
_send_ack(packet.type, self.reactor.scram() == ppm.ACCESS_OK)
|
||||
self.reactor.scram()
|
||||
_send_ack(packet.type, self.reactor.__p_is_ok())
|
||||
elseif packet.type == RPLC_TYPES.MEK_ENABLE then
|
||||
-- enable the reactor
|
||||
self.scrammed = false
|
||||
plc_state.scram = false
|
||||
_send_ack(packet.type, self.reactor.activate() == ppm.ACCESS_OK)
|
||||
self.reactor.activate()
|
||||
_send_ack(packet.type, self.reactor.__p_is_ok())
|
||||
elseif packet.type == RPLC_TYPES.MEK_BURN_RATE then
|
||||
-- set the burn rate
|
||||
local success = false
|
||||
@ -441,11 +444,12 @@ function comms_init(id, modem, local_port, server_port, reactor, iss)
|
||||
-- if we know our max burn rate, update current burn rate if in range
|
||||
if max_burn_rate ~= ppm.ACCESS_FAULT then
|
||||
if burn_rate > 0 and burn_rate <= max_burn_rate then
|
||||
success = self.reactor.setBurnRate(burn_rate)
|
||||
self.reactor.setBurnRate(burn_rate)
|
||||
success = self.reactor.__p_is_ok()
|
||||
end
|
||||
end
|
||||
|
||||
_send_ack(packet.type, success == ppm.ACCESS_OK)
|
||||
_send_ack(packet.type, success)
|
||||
elseif packet.type == RPLC_TYPES.ISS_CLEAR then
|
||||
-- clear the ISS status
|
||||
iss.reset()
|
||||
|
@ -10,7 +10,7 @@ os.loadAPI("scada-common/comms.lua")
|
||||
os.loadAPI("config.lua")
|
||||
os.loadAPI("plc.lua")
|
||||
|
||||
local R_PLC_VERSION = "alpha-v0.2.5"
|
||||
local R_PLC_VERSION = "alpha-v0.2.6"
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
@ -281,7 +281,8 @@ while true do
|
||||
log._warning("terminate requested, exiting...")
|
||||
if plc_state.init_ok then
|
||||
plc_state.scram = true
|
||||
if reactor.scram() ~= ppm.ACCESS_FAULT then
|
||||
reactor.scram()
|
||||
if reactor.__p_is_ok() then
|
||||
println_ts("reactor disabled")
|
||||
else
|
||||
-- send an alarm: plc_comms.send_alarm(ALARMS.PLC_LOST_CONTROL) ?
|
||||
|
@ -17,7 +17,7 @@ os.loadAPI("dev/boiler_rtu.lua")
|
||||
os.loadAPI("dev/imatrix_rtu.lua")
|
||||
os.loadAPI("dev/turbine_rtu.lua")
|
||||
|
||||
local RTU_VERSION = "alpha-v0.2.3"
|
||||
local RTU_VERSION = "alpha-v0.2.4"
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
|
@ -4,14 +4,13 @@
|
||||
-- Protected Peripheral Manager
|
||||
--
|
||||
|
||||
ACCESS_OK = true
|
||||
ACCESS_FAULT = nil
|
||||
|
||||
----------------------------
|
||||
-- PRIVATE DATA/FUNCTIONS --
|
||||
----------------------------
|
||||
|
||||
local self = {
|
||||
local _ppm_sys = {
|
||||
mounts = {},
|
||||
auto_cf = false,
|
||||
faulted = false,
|
||||
@ -20,38 +19,66 @@ local self = {
|
||||
}
|
||||
|
||||
-- wrap peripheral calls with lua protected call
|
||||
-- ex. reason: we don't want a disconnect to crash the program before a SCRAM
|
||||
local peri_init = function (device)
|
||||
for key, func in pairs(device) do
|
||||
device[key] = function (...)
|
||||
-- we don't want a disconnect to crash a program
|
||||
-- also provides peripheral-specific fault checks (auto-clear fault defaults to true)
|
||||
local peri_init = function (iface)
|
||||
local self = {
|
||||
faulted = false,
|
||||
auto_cf = true,
|
||||
type = peripheral.getType(iface),
|
||||
device = peripheral.wrap(iface)
|
||||
}
|
||||
|
||||
-- initialization process (re-map)
|
||||
|
||||
for key, func in pairs(self.device) do
|
||||
self.device[key] = function (...)
|
||||
local status, result = pcall(func, ...)
|
||||
|
||||
if status then
|
||||
-- auto fault clear
|
||||
if self.auto_cf then self.faulted = false end
|
||||
|
||||
-- assume nil is only for functions with no return, so return status
|
||||
if result == nil then
|
||||
return ACCESS_OK
|
||||
else
|
||||
return result
|
||||
end
|
||||
if _ppm_sys.auto_cf then _ppm_sys.faulted = false end
|
||||
return result
|
||||
else
|
||||
-- function failed
|
||||
self.faulted = true
|
||||
_ppm_sys.faulted = true
|
||||
|
||||
if not mute then
|
||||
if not _ppm_sys.mute then
|
||||
log._error("PPM: protected " .. key .. "() -> " .. result)
|
||||
end
|
||||
|
||||
if result == "Terminated" then
|
||||
self.terminate = true
|
||||
_ppm_sys.terminate = true
|
||||
end
|
||||
|
||||
return ACCESS_FAULT
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- fault management functions
|
||||
|
||||
local clear_fault = function () self.faulted = false end
|
||||
local is_faulted = function () return self.faulted end
|
||||
local is_ok = function () return not self.faulted end
|
||||
|
||||
local enable_afc = function () self.auto_cf = true end
|
||||
local disable_afc = function () self.auto_cf = false end
|
||||
|
||||
-- append to device functions
|
||||
|
||||
self.device.__p_clear_fault = clear_fault
|
||||
self.device.__p_is_faulted = is_faulted
|
||||
self.device.__p_is_ok = is_ok
|
||||
self.device.__p_enable_afc = enable_afc
|
||||
self.device.__p_disable_afc = disable_afc
|
||||
|
||||
return {
|
||||
type = self.type,
|
||||
dev = self.device
|
||||
}
|
||||
end
|
||||
|
||||
----------------------
|
||||
@ -62,41 +89,41 @@ end
|
||||
|
||||
-- silence error prints
|
||||
function disable_reporting()
|
||||
self.mute = true
|
||||
_ppm_sys.mute = true
|
||||
end
|
||||
|
||||
-- allow error prints
|
||||
function enable_reporting()
|
||||
self.mute = false
|
||||
_ppm_sys.mute = false
|
||||
end
|
||||
|
||||
-- FAULT MEMORY --
|
||||
|
||||
-- enable automatically clearing fault flag
|
||||
function enable_afc()
|
||||
self.auto_cf = true
|
||||
_ppm_sys.auto_cf = true
|
||||
end
|
||||
|
||||
-- disable automatically clearing fault flag
|
||||
function disable_afc()
|
||||
self.auto_cf = false
|
||||
_ppm_sys.auto_cf = false
|
||||
end
|
||||
|
||||
-- check fault flag
|
||||
function is_faulted()
|
||||
return self.faulted
|
||||
return _ppm_sys.faulted
|
||||
end
|
||||
|
||||
-- clear fault flag
|
||||
function clear_fault()
|
||||
self.faulted = false
|
||||
_ppm_sys.faulted = false
|
||||
end
|
||||
|
||||
-- TERMINATION --
|
||||
|
||||
-- if a caught error was a termination request
|
||||
function should_terminate()
|
||||
return self.terminate
|
||||
return _ppm_sys.terminate
|
||||
end
|
||||
|
||||
-- MOUNTING --
|
||||
@ -105,18 +132,12 @@ end
|
||||
function mount_all()
|
||||
local ifaces = peripheral.getNames()
|
||||
|
||||
self.mounts = {}
|
||||
_ppm_sys.mounts = {}
|
||||
|
||||
for i = 1, #ifaces do
|
||||
local pm_dev = peripheral.wrap(ifaces[i])
|
||||
peri_init(pm_dev)
|
||||
_ppm_sys.mounts[ifaces[i]] = peri_init(ifaces[i])
|
||||
|
||||
self.mounts[ifaces[i]] = {
|
||||
type = peripheral.getType(ifaces[i]),
|
||||
dev = pm_dev
|
||||
}
|
||||
|
||||
log._info("PPM: found a " .. self.mounts[ifaces[i]].type .. " (" .. ifaces[i] .. ")")
|
||||
log._info("PPM: found a " .. _ppm_sys.mounts[ifaces[i]].type .. " (" .. ifaces[i] .. ")")
|
||||
end
|
||||
|
||||
if #ifaces == 0 then
|
||||
@ -128,31 +149,27 @@ end
|
||||
function mount(iface)
|
||||
local ifaces = peripheral.getNames()
|
||||
local pm_dev = nil
|
||||
local type = nil
|
||||
local pm_type = nil
|
||||
|
||||
for i = 1, #ifaces do
|
||||
if iface == ifaces[i] then
|
||||
log._info("PPM: mount(" .. iface .. ") -> found a " .. peripheral.getType(iface))
|
||||
|
||||
type = peripheral.getType(iface)
|
||||
pm_dev = peripheral.wrap(iface)
|
||||
peri_init(pm_dev)
|
||||
_ppm_sys.mounts[iface] = peri_init(iface)
|
||||
|
||||
self.mounts[iface] = {
|
||||
type = peripheral.getType(iface),
|
||||
dev = pm_dev
|
||||
}
|
||||
pm_type = _ppm_sys.mounts[iface].type
|
||||
pm_dev = _ppm_sys.mounts[iface].dev
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return type, pm_dev
|
||||
return pm_type, pm_dev
|
||||
end
|
||||
|
||||
-- handle peripheral_detach event
|
||||
function handle_unmount(iface)
|
||||
-- what got disconnected?
|
||||
local lost_dev = self.mounts[iface]
|
||||
local lost_dev = _ppm_sys.mounts[iface]
|
||||
|
||||
if lost_dev then
|
||||
local type = lost_dev.type
|
||||
@ -173,20 +190,20 @@ end
|
||||
|
||||
-- list mounted peripherals
|
||||
function list_mounts()
|
||||
return self.mounts
|
||||
return _ppm_sys.mounts
|
||||
end
|
||||
|
||||
-- get a mounted peripheral by side/interface
|
||||
function get_periph(iface)
|
||||
if self.mounts[iface] then
|
||||
return self.mounts[iface].dev
|
||||
if _ppm_sys.mounts[iface] then
|
||||
return _ppm_sys.mounts[iface].dev
|
||||
else return nil end
|
||||
end
|
||||
|
||||
-- get a mounted peripheral type by side/interface
|
||||
function get_type(iface)
|
||||
if self.mounts[iface] then
|
||||
return self.mounts[iface].type
|
||||
if _ppm_sys.mounts[iface] then
|
||||
return _ppm_sys.mounts[iface].type
|
||||
else return nil end
|
||||
end
|
||||
|
||||
@ -194,7 +211,7 @@ end
|
||||
function get_all_devices(name)
|
||||
local devices = {}
|
||||
|
||||
for side, data in pairs(self.mounts) do
|
||||
for side, data in pairs(_ppm_sys.mounts) do
|
||||
if data.type == name then
|
||||
table.insert(devices, data.dev)
|
||||
end
|
||||
@ -207,7 +224,7 @@ end
|
||||
function get_device(name)
|
||||
local device = nil
|
||||
|
||||
for side, data in pairs(self.mounts) do
|
||||
for side, data in pairs(_ppm_sys.mounts) do
|
||||
if data.type == name then
|
||||
device = data.dev
|
||||
break
|
||||
@ -228,7 +245,7 @@ end
|
||||
function get_wireless_modem()
|
||||
local w_modem = nil
|
||||
|
||||
for side, device in pairs(self.mounts) do
|
||||
for side, device in pairs(_ppm_sys.mounts) do
|
||||
if device.type == "modem" and device.dev.isWireless() then
|
||||
w_modem = device.dev
|
||||
break
|
||||
|
@ -330,7 +330,7 @@ function new_session(id, for_reactor, in_queue, out_queue)
|
||||
-- handle queue --
|
||||
------------------
|
||||
|
||||
if ~self.in_q.empty() then
|
||||
if not self.in_q.empty() then
|
||||
-- get a new message to process
|
||||
local message = self.in_q.pop()
|
||||
|
||||
|
@ -17,7 +17,7 @@ os.loadAPI("session/plc.lua")
|
||||
os.loadAPI("session/coordinator.lua")
|
||||
os.loadAPI("session/svsessions.lua")
|
||||
|
||||
local SUPERVISOR_VERSION = "alpha-v0.1.2"
|
||||
local SUPERVISOR_VERSION = "alpha-v0.1.3"
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
|
Loading…
Reference in New Issue
Block a user