#118 safety/constants common file
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
local const = require("scada-common.constants")
|
||||
local log = require("scada-common.log")
|
||||
local rsio = require("scada-common.rsio")
|
||||
local types = require("scada-common.types")
|
||||
@@ -16,15 +17,9 @@ local IO = rsio.IO
|
||||
-- 2856 FE per blade per 1 mB, 285.6 FE per blade per 0.1 mB (minimum)
|
||||
local POWER_PER_BLADE = util.joules_to_fe(7140)
|
||||
|
||||
local FLOW_STABILITY_DELAY_S = unit.FLOW_STABILITY_DELAY_MS / 1000
|
||||
local FLOW_STABILITY_DELAY_S = const.FLOW_STABILITY_DELAY_MS / 1000
|
||||
|
||||
-- background radiation 0.0000001 Sv/h (99.99 nSv/h)
|
||||
-- "green tint" radiation 0.00001 Sv/h (10 uSv/h)
|
||||
-- damaging radiation 0.00006 Sv/h (60 uSv/h)
|
||||
local RADIATION_ALARM_LEVEL = 0.00001
|
||||
|
||||
local HIGH_CHARGE = 1.0
|
||||
local RE_ENABLE_CHARGE = 0.95
|
||||
local ALARM_LIMS = const.ALARM_LIMITS
|
||||
|
||||
local AUTO_SCRAM = {
|
||||
NONE = 0,
|
||||
@@ -563,10 +558,10 @@ function facility.new(num_reactors, cooling_conf)
|
||||
|
||||
-- check matrix fill too high
|
||||
local was_fill = astatus.matrix_fill
|
||||
astatus.matrix_fill = (db.tanks.energy_fill >= HIGH_CHARGE) or (astatus.matrix_fill and db.tanks.energy_fill > RE_ENABLE_CHARGE)
|
||||
astatus.matrix_fill = (db.tanks.energy_fill >= ALARM_LIMS.CHARGE_HIGH) or (astatus.matrix_fill and db.tanks.energy_fill > ALARM_LIMS.CHARGE_RE_ENABLE)
|
||||
|
||||
if was_fill and not astatus.matrix_fill then
|
||||
log.info("FAC: charge state of induction matrix entered acceptable range <= " .. (RE_ENABLE_CHARGE * 100) .. "%")
|
||||
log.info("FAC: charge state of induction matrix entered acceptable range <= " .. (ALARM_LIMS.CHARGE_RE_ENABLE * 100) .. "%")
|
||||
end
|
||||
|
||||
-- check for critical unit alarms
|
||||
@@ -585,7 +580,7 @@ function facility.new(num_reactors, cooling_conf)
|
||||
local envd = self.envd[1] ---@type unit_session
|
||||
local e_db = envd.get_db() ---@type envd_session_db
|
||||
|
||||
astatus.radiation = e_db.radiation_raw > RADIATION_ALARM_LEVEL
|
||||
astatus.radiation = e_db.radiation_raw > ALARM_LIMS.FAC_HIGH_RAD
|
||||
else
|
||||
-- don't clear, if it is true then we lost it with high radiation, so just keep alarming
|
||||
-- operator can restart the system or hit the stop/reset button
|
||||
|
||||
@@ -12,8 +12,6 @@ local rsctl = require("supervisor.session.rsctl")
|
||||
local unit = {}
|
||||
|
||||
local WASTE_MODE = types.WASTE_MODE
|
||||
local DUMPING_MODE = types.DUMPING_MODE
|
||||
|
||||
local ALARM = types.ALARM
|
||||
local PRIO = types.ALARM_PRIORITY
|
||||
local ALARM_STATE = types.ALARM_STATE
|
||||
@@ -23,8 +21,6 @@ local PLC_S_CMDS = plc.PLC_S_CMDS
|
||||
|
||||
local IO = rsio.IO
|
||||
|
||||
local FLOW_STABILITY_DELAY_MS = 15000
|
||||
|
||||
local DT_KEYS = {
|
||||
ReactorBurnR = "RBR",
|
||||
ReactorTemp = "RTP",
|
||||
@@ -50,8 +46,6 @@ local AISTATE = {
|
||||
RING_BACK_TRIPPING = 6
|
||||
}
|
||||
|
||||
unit.FLOW_STABILITY_DELAY_MS = FLOW_STABILITY_DELAY_MS
|
||||
|
||||
---@class alarm_def
|
||||
---@field state ALARM_INT_STATE internal alarm state
|
||||
---@field trip_time integer time (ms) when first tripped
|
||||
@@ -73,7 +67,6 @@ function unit.new(reactor_id, num_boilers, num_turbines)
|
||||
num_boilers = num_boilers,
|
||||
num_turbines = num_turbines,
|
||||
types = { DT_KEYS = DT_KEYS, AISTATE = AISTATE },
|
||||
defs = { FLOW_STABILITY_DELAY_MS = FLOW_STABILITY_DELAY_MS },
|
||||
-- rtus
|
||||
redstone = {},
|
||||
boilers = {},
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
local const = require("scada-common.constants")
|
||||
local log = require("scada-common.log")
|
||||
local rsio = require("scada-common.rsio")
|
||||
local types = require("scada-common.types")
|
||||
@@ -5,11 +6,10 @@ local util = require("scada-common.util")
|
||||
|
||||
local plc = require("supervisor.session.plc")
|
||||
|
||||
local TRI_FAIL = types.TRI_FAIL
|
||||
local TRI_FAIL = types.TRI_FAIL
|
||||
local DUMPING_MODE = types.DUMPING_MODE
|
||||
|
||||
local PRIO = types.ALARM_PRIORITY
|
||||
local ALARM_STATE = types.ALARM_STATE
|
||||
local PRIO = types.ALARM_PRIORITY
|
||||
local ALARM_STATE = types.ALARM_STATE
|
||||
|
||||
local IO = rsio.IO
|
||||
|
||||
@@ -24,11 +24,10 @@ local AISTATE_NAMES = {
|
||||
"RING_BACK_TRIPPING"
|
||||
}
|
||||
|
||||
-- background radiation 0.0000001 Sv/h (99.99 nSv/h)
|
||||
-- "green tint" radiation 0.00001 Sv/h (10 uSv/h)
|
||||
-- damaging radiation 0.00006 Sv/h (60 uSv/h)
|
||||
local RADIATION_ALERT_LEVEL = 0.00001 -- 10 uSv/h
|
||||
local RADIATION_ALARM_LEVEL = 0.00005 -- 50 uSv/h, not yet damaging but this isn't good
|
||||
local FLOW_STABILITY_DELAY_MS = const.FLOW_STABILITY_DELAY_MS
|
||||
|
||||
local ANNUNC_LIMS = const.ANNUNCIATOR_LIMITS
|
||||
local ALARM_LIMS = const.ALARM_LIMITS
|
||||
|
||||
---@class unit_logic_extension
|
||||
local logic = {}
|
||||
@@ -111,12 +110,12 @@ function logic.update_annunciator(self)
|
||||
self.db.annunciator.ManualReactorSCRAM = plc_db.rps_trip_cause == types.RPS_TRIP_CAUSE.MANUAL
|
||||
self.db.annunciator.AutoReactorSCRAM = plc_db.rps_trip_cause == types.RPS_TRIP_CAUSE.AUTOMATIC
|
||||
self.db.annunciator.RCPTrip = plc_db.rps_tripped and (plc_db.rps_status.ex_hcool or plc_db.rps_status.no_cool)
|
||||
self.db.annunciator.RCSFlowLow = _get_dt(DT_KEYS.ReactorCCool) < -2.0
|
||||
self.db.annunciator.CoolantLevelLow = plc_db.mek_status.ccool_fill < 0.4
|
||||
self.db.annunciator.ReactorTempHigh = plc_db.mek_status.temp > 1000
|
||||
self.db.annunciator.ReactorHighDeltaT = _get_dt(DT_KEYS.ReactorTemp) > 100
|
||||
self.db.annunciator.FuelInputRateLow = _get_dt(DT_KEYS.ReactorFuel) < -1.0 or plc_db.mek_status.fuel_fill <= 0.01
|
||||
self.db.annunciator.WasteLineOcclusion = _get_dt(DT_KEYS.ReactorWaste) > 1.0 or plc_db.mek_status.waste_fill >= 0.85
|
||||
self.db.annunciator.RCSFlowLow = _get_dt(DT_KEYS.ReactorCCool) < ANNUNC_LIMS.RCSFlowLow
|
||||
self.db.annunciator.CoolantLevelLow = plc_db.mek_status.ccool_fill < ANNUNC_LIMS.CoolantLevelLow
|
||||
self.db.annunciator.ReactorTempHigh = plc_db.mek_status.temp > ANNUNC_LIMS.ReactorTempHigh
|
||||
self.db.annunciator.ReactorHighDeltaT = _get_dt(DT_KEYS.ReactorTemp) > ANNUNC_LIMS.ReactorHighDeltaT
|
||||
self.db.annunciator.FuelInputRateLow = _get_dt(DT_KEYS.ReactorFuel) < -1.0 or plc_db.mek_status.fuel_fill <= ANNUNC_LIMS.FuelLevelLow
|
||||
self.db.annunciator.WasteLineOcclusion = _get_dt(DT_KEYS.ReactorWaste) > 1.0 or plc_db.mek_status.waste_fill >= ANNUNC_LIMS.WasteLevelHigh
|
||||
|
||||
-- this warning applies when no coolant is buffered (which we can't easily determine without running)
|
||||
--[[
|
||||
@@ -150,7 +149,7 @@ function logic.update_annunciator(self)
|
||||
for i = 1, #self.envd do
|
||||
local envd = self.envd[i] ---@type unit_session
|
||||
self.db.annunciator.RadiationMonitor = util.trinary(envd.is_faulted(), 2, 3)
|
||||
self.db.annunciator.RadiationWarning = envd.get_db().radiation_raw > RADIATION_ALERT_LEVEL
|
||||
self.db.annunciator.RadiationWarning = envd.get_db().radiation_raw > ANNUNC_LIMS.RadiationWarning
|
||||
break
|
||||
end
|
||||
|
||||
@@ -299,7 +298,7 @@ function logic.update_annunciator(self)
|
||||
self.db.annunciator.BoilRateMismatch = math.abs(total_boil_rate - total_input_rate) > (0.04 * total_boil_rate)
|
||||
|
||||
-- check for steam feed mismatch and max return rate
|
||||
local sfmismatch = math.abs(total_flow_rate - total_input_rate) > 10
|
||||
local sfmismatch = math.abs(total_flow_rate - total_input_rate) > ANNUNC_LIMS.SteamFeedMismatch
|
||||
sfmismatch = sfmismatch or boiler_steam_dt_sum > 2.0 or boiler_water_dt_sum < -2.0
|
||||
self.db.annunciator.SteamFeedMismatch = sfmismatch
|
||||
self.db.annunciator.MaxWaterReturnFeed = max_water_return_rate == total_flow_rate and total_flow_rate ~= 0
|
||||
@@ -449,7 +448,7 @@ function logic.update_alarms(self)
|
||||
-- Containment Radiation
|
||||
local rad_alarm = false
|
||||
for i = 1, #self.envd do
|
||||
rad_alarm = self.envd[i].get_db().radiation_raw > RADIATION_ALARM_LEVEL
|
||||
rad_alarm = self.envd[i].get_db().radiation_raw > ALARM_LIMS.HIGH_RADIATION
|
||||
break
|
||||
end
|
||||
_update_alarm_state(self, rad_alarm, self.alarms.ContainmentRadiation)
|
||||
@@ -469,14 +468,14 @@ function logic.update_alarms(self)
|
||||
_update_alarm_state(self, (plc_cache.temp >= 1200) or rps_high_temp, self.alarms.ReactorOverTemp)
|
||||
|
||||
-- High Temperature
|
||||
_update_alarm_state(self, plc_cache.temp > 1150, self.alarms.ReactorHighTemp)
|
||||
_update_alarm_state(self, plc_cache.temp >= ALARM_LIMS.HIGH_TEMP, self.alarms.ReactorHighTemp)
|
||||
|
||||
-- Waste Leak
|
||||
_update_alarm_state(self, plc_cache.waste >= 0.99, self.alarms.ReactorWasteLeak)
|
||||
_update_alarm_state(self, plc_cache.waste >= 1.0, self.alarms.ReactorWasteLeak)
|
||||
|
||||
-- High Waste
|
||||
local rps_high_waste = plc_cache.rps_status.ex_waste and not self.last_rps_trips.ex_waste
|
||||
_update_alarm_state(self, (plc_cache.waste > 0.50) or rps_high_waste, self.alarms.ReactorHighWaste)
|
||||
_update_alarm_state(self, (plc_cache.waste > ALARM_LIMS.HIGH_WASTE) or rps_high_waste, self.alarms.ReactorHighWaste)
|
||||
|
||||
-- RPS Transient (excludes timeouts and manual trips)
|
||||
local rps_alarm = false
|
||||
@@ -501,7 +500,7 @@ function logic.update_alarms(self)
|
||||
-- annunciator indicators for these states may not indicate a real issue when:
|
||||
-- > flow is ramping up right after reactor start
|
||||
-- > flow is ramping down after reactor shutdown
|
||||
if ((util.time_ms() - self.last_rate_change_ms) > self.defs.FLOW_STABILITY_DELAY_MS) and plc_cache.active then
|
||||
if ((util.time_ms() - self.last_rate_change_ms) > FLOW_STABILITY_DELAY_MS) and plc_cache.active then
|
||||
rcs_trans = rcs_trans or annunc.BoilRateMismatch or annunc.CoolantFeedMismatch or annunc.SteamFeedMismatch
|
||||
end
|
||||
|
||||
@@ -621,7 +620,7 @@ function logic.update_status_text(self)
|
||||
self.status_text[2] = "insufficient fuel input rate"
|
||||
elseif self.db.annunciator.WasteLineOcclusion then
|
||||
self.status_text[2] = "insufficient waste output rate"
|
||||
elseif (util.time_ms() - self.last_rate_change_ms) <= self.defs.FLOW_STABILITY_DELAY_MS then
|
||||
elseif (util.time_ms() - self.last_rate_change_ms) <= FLOW_STABILITY_DELAY_MS then
|
||||
self.status_text[2] = "awaiting flow stability"
|
||||
else
|
||||
self.status_text[2] = "system nominal"
|
||||
|
||||
Reference in New Issue
Block a user