mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
#106 fixes to reactor isFormed support
This commit is contained in:
parent
57bac57e3f
commit
004c960e4d
@ -230,16 +230,21 @@ function plc.rps_init(reactor, is_formed)
|
|||||||
local was_tripped = self.tripped
|
local was_tripped = self.tripped
|
||||||
local first_trip = false
|
local first_trip = false
|
||||||
|
|
||||||
-- update state
|
if self.formed then
|
||||||
parallel.waitForAll(
|
-- update state
|
||||||
_is_formed,
|
parallel.waitForAll(
|
||||||
_damage_critical,
|
_is_formed,
|
||||||
_high_temp,
|
_damage_critical,
|
||||||
_no_coolant,
|
_high_temp,
|
||||||
_excess_waste,
|
_no_coolant,
|
||||||
_excess_heated_coolant,
|
_excess_waste,
|
||||||
_insufficient_fuel
|
_excess_heated_coolant,
|
||||||
)
|
_insufficient_fuel
|
||||||
|
)
|
||||||
|
else
|
||||||
|
-- check to see if its now formed
|
||||||
|
_is_formed()
|
||||||
|
end
|
||||||
|
|
||||||
-- check system states in order of severity
|
-- check system states in order of severity
|
||||||
if self.tripped then
|
if self.tripped then
|
||||||
@ -284,7 +289,11 @@ function plc.rps_init(reactor, is_formed)
|
|||||||
self.tripped = true
|
self.tripped = true
|
||||||
self.trip_cause = status
|
self.trip_cause = status
|
||||||
|
|
||||||
public.scram()
|
if self.formed then
|
||||||
|
public.scram()
|
||||||
|
else
|
||||||
|
log.warning("RPS: skipping SCRAM due to not being formed")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return self.tripped, status, first_trip
|
return self.tripped, status, first_trip
|
||||||
@ -322,19 +331,16 @@ end
|
|||||||
---@param conn_watchdog watchdog
|
---@param conn_watchdog watchdog
|
||||||
function plc.comms(id, version, modem, local_port, server_port, reactor, rps, conn_watchdog)
|
function plc.comms(id, version, modem, local_port, server_port, reactor, rps, conn_watchdog)
|
||||||
local self = {
|
local self = {
|
||||||
id = id,
|
|
||||||
version = version,
|
|
||||||
seq_num = 0,
|
seq_num = 0,
|
||||||
r_seq_num = nil,
|
r_seq_num = nil,
|
||||||
modem = modem,
|
modem = modem,
|
||||||
s_port = server_port,
|
s_port = server_port,
|
||||||
l_port = local_port,
|
l_port = local_port,
|
||||||
reactor = reactor,
|
reactor = reactor,
|
||||||
rps = rps,
|
|
||||||
conn_watchdog = conn_watchdog,
|
|
||||||
scrammed = false,
|
scrammed = false,
|
||||||
linked = false,
|
linked = false,
|
||||||
status_cache = nil,
|
status_cache = nil,
|
||||||
|
resend_build = false,
|
||||||
max_burn_rate = nil
|
max_burn_rate = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,7 +364,7 @@ function plc.comms(id, version, modem, local_port, server_port, reactor, rps, co
|
|||||||
local s_pkt = comms.scada_packet()
|
local s_pkt = comms.scada_packet()
|
||||||
local r_pkt = comms.rplc_packet()
|
local r_pkt = comms.rplc_packet()
|
||||||
|
|
||||||
r_pkt.make(self.id, msg_type, msg)
|
r_pkt.make(id, msg_type, msg)
|
||||||
s_pkt.make(self.seq_num, PROTOCOLS.RPLC, r_pkt.raw_sendable())
|
s_pkt.make(self.seq_num, PROTOCOLS.RPLC, r_pkt.raw_sendable())
|
||||||
|
|
||||||
self.modem.transmit(self.s_port, self.l_port, s_pkt.raw_sendable())
|
self.modem.transmit(self.s_port, self.l_port, s_pkt.raw_sendable())
|
||||||
@ -514,6 +520,7 @@ function plc.comms(id, version, modem, local_port, server_port, reactor, rps, co
|
|||||||
|
|
||||||
if not self.reactor.__p_is_faulted() then
|
if not self.reactor.__p_is_faulted() then
|
||||||
_send(RPLC_TYPES.MEK_STRUCT, mek_data)
|
_send(RPLC_TYPES.MEK_STRUCT, mek_data)
|
||||||
|
self.resend_build = false
|
||||||
else
|
else
|
||||||
log.error("failed to send structure: PPM fault")
|
log.error("failed to send structure: PPM fault")
|
||||||
end
|
end
|
||||||
@ -535,6 +542,7 @@ function plc.comms(id, version, modem, local_port, server_port, reactor, rps, co
|
|||||||
function public.reconnect_reactor(reactor)
|
function public.reconnect_reactor(reactor)
|
||||||
self.reactor = reactor
|
self.reactor = reactor
|
||||||
self.status_cache = nil
|
self.status_cache = nil
|
||||||
|
self.resend_build = true
|
||||||
end
|
end
|
||||||
|
|
||||||
-- unlink from the server
|
-- unlink from the server
|
||||||
@ -546,30 +554,27 @@ function plc.comms(id, version, modem, local_port, server_port, reactor, rps, co
|
|||||||
|
|
||||||
-- close the connection to the server
|
-- close the connection to the server
|
||||||
function public.close()
|
function public.close()
|
||||||
self.conn_watchdog.cancel()
|
conn_watchdog.cancel()
|
||||||
public.unlink()
|
public.unlink()
|
||||||
_send_mgmt(SCADA_MGMT_TYPES.CLOSE, {})
|
_send_mgmt(SCADA_MGMT_TYPES.CLOSE, {})
|
||||||
end
|
end
|
||||||
|
|
||||||
-- attempt to establish link with supervisor
|
-- attempt to establish link with supervisor
|
||||||
function public.send_link_req()
|
function public.send_link_req()
|
||||||
_send(RPLC_TYPES.LINK_REQ, { self.id, self.version })
|
_send(RPLC_TYPES.LINK_REQ, { id, version })
|
||||||
end
|
end
|
||||||
|
|
||||||
-- send live status information
|
-- send live status information
|
||||||
---@param no_reactor boolean PLC lost reactor connection
|
---@param no_reactor boolean PLC lost reactor connection
|
||||||
---@param formed boolean reactor formed
|
---@param formed boolean reactor formed (from PLC state)
|
||||||
function public.send_status(no_reactor, formed)
|
function public.send_status(no_reactor, formed)
|
||||||
if self.linked then
|
if self.linked then
|
||||||
local mek_data = nil ---@type table
|
local mek_data = nil ---@type table
|
||||||
local heating_rate = nil ---@type number
|
local heating_rate = 0.0 ---@type number
|
||||||
|
|
||||||
if (not no_reactor) and formed then
|
if (not no_reactor) and rps.is_formed() then
|
||||||
if _update_status_cache() then
|
if _update_status_cache() then
|
||||||
mek_data = self.status_cache
|
mek_data = self.status_cache
|
||||||
log.debug("sent updated status")
|
|
||||||
else
|
|
||||||
log.debug("sent cached status")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
heating_rate = self.reactor.getHeatingRate()
|
heating_rate = self.reactor.getHeatingRate()
|
||||||
@ -586,6 +591,10 @@ function plc.comms(id, version, modem, local_port, server_port, reactor, rps, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
_send(RPLC_TYPES.STATUS, sys_status)
|
_send(RPLC_TYPES.STATUS, sys_status)
|
||||||
|
|
||||||
|
if self.resend_build then
|
||||||
|
_send_struct()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -661,7 +670,7 @@ function plc.comms(id, version, modem, local_port, server_port, reactor, rps, co
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- feed the watchdog first so it doesn't uhh...eat our packets :)
|
-- feed the watchdog first so it doesn't uhh...eat our packets :)
|
||||||
self.conn_watchdog.feed()
|
conn_watchdog.feed()
|
||||||
|
|
||||||
local protocol = packet.scada_frame.protocol()
|
local protocol = packet.scada_frame.protocol()
|
||||||
|
|
||||||
@ -739,11 +748,11 @@ function plc.comms(id, version, modem, local_port, server_port, reactor, rps, co
|
|||||||
elseif packet.type == RPLC_TYPES.RPS_ENABLE then
|
elseif packet.type == RPLC_TYPES.RPS_ENABLE then
|
||||||
-- enable the reactor
|
-- enable the reactor
|
||||||
self.scrammed = false
|
self.scrammed = false
|
||||||
_send_ack(packet.type, self.rps.activate())
|
_send_ack(packet.type, rps.activate())
|
||||||
elseif packet.type == RPLC_TYPES.RPS_SCRAM then
|
elseif packet.type == RPLC_TYPES.RPS_SCRAM then
|
||||||
-- disable the reactor
|
-- disable the reactor
|
||||||
self.scrammed = true
|
self.scrammed = true
|
||||||
self.rps.trip_manual()
|
rps.trip_manual()
|
||||||
_send_ack(packet.type, true)
|
_send_ack(packet.type, true)
|
||||||
elseif packet.type == RPLC_TYPES.RPS_RESET then
|
elseif packet.type == RPLC_TYPES.RPS_RESET then
|
||||||
-- reset the RPS status
|
-- reset the RPS status
|
||||||
@ -809,7 +818,7 @@ function plc.comms(id, version, modem, local_port, server_port, reactor, rps, co
|
|||||||
end
|
end
|
||||||
elseif packet.type == SCADA_MGMT_TYPES.CLOSE then
|
elseif packet.type == SCADA_MGMT_TYPES.CLOSE then
|
||||||
-- handle session close
|
-- handle session close
|
||||||
self.conn_watchdog.cancel()
|
conn_watchdog.cancel()
|
||||||
public.unlink()
|
public.unlink()
|
||||||
println_ts("server connection closed by remote host")
|
println_ts("server connection closed by remote host")
|
||||||
log.warning("server connection closed by remote host")
|
log.warning("server connection closed by remote host")
|
||||||
|
@ -13,7 +13,7 @@ local config = require("reactor-plc.config")
|
|||||||
local plc = require("reactor-plc.plc")
|
local plc = require("reactor-plc.plc")
|
||||||
local threads = require("reactor-plc.threads")
|
local threads = require("reactor-plc.threads")
|
||||||
|
|
||||||
local R_PLC_VERSION = "beta-v0.9.0"
|
local R_PLC_VERSION = "beta-v0.9.1"
|
||||||
|
|
||||||
local print = util.print
|
local print = util.print
|
||||||
local println = util.println
|
local println = util.println
|
||||||
|
@ -84,6 +84,7 @@ function threads.thread__main(smem, init)
|
|||||||
-- push a connect event and unmount it from the PPM
|
-- push a connect event and unmount it from the PPM
|
||||||
local iface = ppm.get_iface(plc_dev.reactor)
|
local iface = ppm.get_iface(plc_dev.reactor)
|
||||||
if iface then
|
if iface then
|
||||||
|
log.info("unmounting and remounting unformed reactor")
|
||||||
ppm.unmount(plc_dev.reactor)
|
ppm.unmount(plc_dev.reactor)
|
||||||
|
|
||||||
local type, device = ppm.mount(iface)
|
local type, device = ppm.mount(iface)
|
||||||
@ -91,27 +92,32 @@ function threads.thread__main(smem, init)
|
|||||||
if type ~= "fissionReactorLogicAdapter" and device ~= nil then
|
if type ~= "fissionReactorLogicAdapter" and device ~= nil then
|
||||||
-- reconnect reactor
|
-- reconnect reactor
|
||||||
plc_dev.reactor = device
|
plc_dev.reactor = device
|
||||||
|
|
||||||
smem.q.mq_rps.push_command(MQ__RPS_CMD.SCRAM)
|
|
||||||
|
|
||||||
println_ts("reactor reconnected as formed.")
|
|
||||||
log.info("reactor reconnected as formed")
|
|
||||||
|
|
||||||
plc_state.reactor_formed = device.isFormed()
|
plc_state.reactor_formed = device.isFormed()
|
||||||
|
|
||||||
rps.reconnect_reactor(plc_dev.reactor)
|
if plc_state.reactor_formed then
|
||||||
if networked then
|
println_ts("reactor reconnected as formed.")
|
||||||
plc_comms.reconnect_reactor(plc_dev.reactor)
|
log.info("reactor reconnected as formed")
|
||||||
|
|
||||||
|
-- SCRAM newly connected reactor
|
||||||
|
smem.q.mq_rps.push_command(MQ__RPS_CMD.SCRAM)
|
||||||
|
else
|
||||||
|
println_ts("reactor reconnected but still not formed.")
|
||||||
|
log.info("reactor reconnected but still not formed")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- determine if we are still in a degraded state
|
-- determine if we are still in a degraded state
|
||||||
if not networked or not plc_state.no_modem then
|
if not networked or not plc_state.no_modem then
|
||||||
plc_state.degraded = false
|
plc_state.degraded = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
rps.reconnect_reactor(plc_dev.reactor)
|
||||||
|
if networked then
|
||||||
|
plc_comms.reconnect_reactor(plc_dev.reactor)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
-- fully lost the reactor now :(
|
-- fully lost the reactor now :(
|
||||||
println_ts("reactor lost (failed reconnect)!")
|
println_ts("reactor lost (failed reconnect)!")
|
||||||
log.error("reactor lost (failed reconnect!")
|
log.error("reactor lost (failed reconnect)")
|
||||||
|
|
||||||
plc_state.no_reactor = true
|
plc_state.no_reactor = true
|
||||||
plc_state.degraded = true
|
plc_state.degraded = true
|
||||||
@ -141,7 +147,7 @@ function threads.thread__main(smem, init)
|
|||||||
if type ~= nil and device ~= nil then
|
if type ~= nil and device ~= nil then
|
||||||
if type == "fissionReactorLogicAdapter" then
|
if type == "fissionReactorLogicAdapter" then
|
||||||
println_ts("reactor disconnected!")
|
println_ts("reactor disconnected!")
|
||||||
log.error("reactor disconnected!")
|
log.error("reactor logic adapter disconnected")
|
||||||
|
|
||||||
plc_state.no_reactor = true
|
plc_state.no_reactor = true
|
||||||
plc_state.degraded = true
|
plc_state.degraded = true
|
||||||
@ -149,7 +155,7 @@ function threads.thread__main(smem, init)
|
|||||||
-- we only care if this is our wireless modem
|
-- we only care if this is our wireless modem
|
||||||
if device == plc_dev.modem then
|
if device == plc_dev.modem then
|
||||||
println_ts("comms modem disconnected!")
|
println_ts("comms modem disconnected!")
|
||||||
log.error("comms modem disconnected!")
|
log.error("comms modem disconnected")
|
||||||
|
|
||||||
plc_state.no_modem = true
|
plc_state.no_modem = true
|
||||||
|
|
||||||
@ -173,25 +179,27 @@ function threads.thread__main(smem, init)
|
|||||||
-- reconnected reactor
|
-- reconnected reactor
|
||||||
plc_dev.reactor = device
|
plc_dev.reactor = device
|
||||||
|
|
||||||
smem.q.mq_rps.push_command(MQ__RPS_CMD.SCRAM)
|
|
||||||
|
|
||||||
println_ts("reactor reconnected.")
|
println_ts("reactor reconnected.")
|
||||||
log.info("reactor reconnected")
|
log.info("reactor reconnected")
|
||||||
|
|
||||||
plc_state.no_reactor = false
|
plc_state.no_reactor = false
|
||||||
plc_state.reactor_formed = device.isFormed()
|
plc_state.reactor_formed = device.isFormed()
|
||||||
|
|
||||||
|
-- determine if we are still in a degraded state
|
||||||
|
if (not networked or not plc_state.no_modem) and plc_state.reactor_formed then
|
||||||
|
plc_state.degraded = false
|
||||||
|
end
|
||||||
|
|
||||||
if plc_state.init_ok then
|
if plc_state.init_ok then
|
||||||
|
if plc_state.reactor_formed then
|
||||||
|
smem.q.mq_rps.push_command(MQ__RPS_CMD.SCRAM)
|
||||||
|
end
|
||||||
|
|
||||||
rps.reconnect_reactor(plc_dev.reactor)
|
rps.reconnect_reactor(plc_dev.reactor)
|
||||||
if networked then
|
if networked then
|
||||||
plc_comms.reconnect_reactor(plc_dev.reactor)
|
plc_comms.reconnect_reactor(plc_dev.reactor)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- determine if we are still in a degraded state
|
|
||||||
if (not networked or not plc_state.no_modem) and plc_state.reactor_formed then
|
|
||||||
plc_state.degraded = false
|
|
||||||
end
|
|
||||||
elseif networked and type == "modem" then
|
elseif networked and type == "modem" then
|
||||||
if device.isWireless() then
|
if device.isWireless() then
|
||||||
-- reconnected modem
|
-- reconnected modem
|
||||||
@ -302,7 +310,7 @@ function threads.thread__rps(smem)
|
|||||||
-- if we tried to SCRAM but failed, keep trying
|
-- if we tried to SCRAM but failed, keep trying
|
||||||
-- in that case, SCRAM won't be called until it reconnects (this is the expected use of this check)
|
-- in that case, SCRAM won't be called until it reconnects (this is the expected use of this check)
|
||||||
---@diagnostic disable-next-line: need-check-nil
|
---@diagnostic disable-next-line: need-check-nil
|
||||||
if not plc_state.no_reactor and rps.is_tripped() and reactor.getStatus() then
|
if (not plc_state.no_reactor) and rps.is_formed() and rps.is_tripped() and reactor.getStatus() then
|
||||||
rps.scram()
|
rps.scram()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -115,35 +115,35 @@ local function peri_init(iface)
|
|||||||
|
|
||||||
-- add default index function to catch undefined indicies
|
-- add default index function to catch undefined indicies
|
||||||
|
|
||||||
local mt = {}
|
local mt = {
|
||||||
|
__index = function (_, key)
|
||||||
function mt.__index(_, key)
|
-- this will continuously be counting calls here as faults
|
||||||
-- this will continuously be counting calls here as faults
|
-- unlike other functions, faults here can't be cleared as it is just not defined
|
||||||
-- unlike other functions, faults here can't be cleared as it is just not defined
|
if self.fault_counts[key] == nil then
|
||||||
if self.fault_counts[key] == nil then
|
self.fault_counts[key] = 0
|
||||||
self.fault_counts[key] = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
-- function failed
|
|
||||||
self.faulted = true
|
|
||||||
self.last_fault = UNDEFINED_FIELD
|
|
||||||
|
|
||||||
_ppm_sys.faulted = true
|
|
||||||
_ppm_sys.last_fault = UNDEFINED_FIELD
|
|
||||||
|
|
||||||
if not _ppm_sys.mute and (self.fault_counts[key] % REPORT_FREQUENCY == 0) then
|
|
||||||
local count_str = ""
|
|
||||||
if self.fault_counts[key] > 0 then
|
|
||||||
count_str = " [" .. self.fault_counts[key] .. " total calls]"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
log.error(util.c("PPM: caught undefined function ", key, "()", count_str))
|
-- function failed
|
||||||
|
self.faulted = true
|
||||||
|
self.last_fault = UNDEFINED_FIELD
|
||||||
|
|
||||||
|
_ppm_sys.faulted = true
|
||||||
|
_ppm_sys.last_fault = UNDEFINED_FIELD
|
||||||
|
|
||||||
|
if not _ppm_sys.mute and (self.fault_counts[key] % REPORT_FREQUENCY == 0) then
|
||||||
|
local count_str = ""
|
||||||
|
if self.fault_counts[key] > 0 then
|
||||||
|
count_str = " [" .. self.fault_counts[key] .. " total calls]"
|
||||||
|
end
|
||||||
|
|
||||||
|
log.error(util.c("PPM: caught undefined function ", key, "()", count_str))
|
||||||
|
end
|
||||||
|
|
||||||
|
self.fault_counts[key] = self.fault_counts[key] + 1
|
||||||
|
|
||||||
|
return (function () return ACCESS_FAULT end)
|
||||||
end
|
end
|
||||||
|
}
|
||||||
self.fault_counts[key] = self.fault_counts[key] + 1
|
|
||||||
|
|
||||||
return ACCESS_FAULT
|
|
||||||
end
|
|
||||||
|
|
||||||
setmetatable(self.device, mt)
|
setmetatable(self.device, mt)
|
||||||
|
|
||||||
|
@ -105,7 +105,8 @@ types.rps_status_t = {
|
|||||||
no_fuel = "no_fuel",
|
no_fuel = "no_fuel",
|
||||||
fault = "fault",
|
fault = "fault",
|
||||||
timeout = "timeout",
|
timeout = "timeout",
|
||||||
manual = "manual"
|
manual = "manual",
|
||||||
|
sys_fail = "sys_fail"
|
||||||
}
|
}
|
||||||
|
|
||||||
-- turbine steam dumping modes
|
-- turbine steam dumping modes
|
||||||
|
Loading…
x
Reference in New Issue
Block a user