mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
#176 generator trip detection on supervisor
This commit is contained in:
parent
8b1e7cb933
commit
0f735d049e
@ -14,7 +14,7 @@ local svsessions = require("supervisor.session.svsessions")
|
||||
local config = require("supervisor.config")
|
||||
local supervisor = require("supervisor.supervisor")
|
||||
|
||||
local SUPERVISOR_VERSION = "v0.14.0"
|
||||
local SUPERVISOR_VERSION = "v0.14.1"
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
|
@ -154,7 +154,8 @@ function unit.new(reactor_id, num_boilers, num_turbines)
|
||||
ReactorHighWaste = { state = AISTATE.INACTIVE, trip_time = 0, hold_time = 2, id = ALARM.ReactorHighWaste, tier = PRIO.URGENT },
|
||||
-- RPS trip occured
|
||||
RPSTransient = { state = AISTATE.INACTIVE, trip_time = 0, hold_time = 2, id = ALARM.RPSTransient, tier = PRIO.TIMELY },
|
||||
-- BoilRateMismatch, CoolantFeedMismatch, SteamFeedMismatch, MaxWaterReturnFeed
|
||||
-- CoolantLevelLow, WaterLevelLow, TurbineOverSpeed, MaxWaterReturnFeed, RCPTrip, RCSFlowLow, BoilRateMismatch, CoolantFeedMismatch,
|
||||
-- SteamFeedMismatch, MaxWaterReturnFeed, RCS hardware fault
|
||||
RCSTransient = { state = AISTATE.INACTIVE, trip_time = 0, hold_time = 5, id = ALARM.RCSTransient, tier = PRIO.TIMELY },
|
||||
-- "It's just a routine turbin' trip!" -Bill Gibson, "The China Syndrome"
|
||||
TurbineTrip = { state = AISTATE.INACTIVE, trip_time = 0, hold_time = 2, id = ALARM.TurbineTrip, tier = PRIO.URGENT }
|
||||
@ -195,6 +196,7 @@ function unit.new(reactor_id, num_boilers, num_turbines)
|
||||
TurbineOnline = {},
|
||||
SteamDumpOpen = {},
|
||||
TurbineOverSpeed = {},
|
||||
GeneratorTrip = {},
|
||||
TurbineTrip = {}
|
||||
},
|
||||
---@class alarms
|
||||
@ -238,6 +240,7 @@ function unit.new(reactor_id, num_boilers, num_turbines)
|
||||
table.insert(self.db.annunciator.TurbineOnline, false)
|
||||
table.insert(self.db.annunciator.SteamDumpOpen, TRI_FAIL.OK)
|
||||
table.insert(self.db.annunciator.TurbineOverSpeed, false)
|
||||
table.insert(self.db.annunciator.GeneratorTrip, false)
|
||||
table.insert(self.db.annunciator.TurbineTrip, false)
|
||||
end
|
||||
|
||||
@ -312,7 +315,6 @@ function unit.new(reactor_id, num_boilers, num_turbines)
|
||||
local last_update_s = db.tanks.last_update / 1000.0
|
||||
|
||||
_compute_dt(DT_KEYS.TurbineSteam .. turbine.get_device_idx(), db.tanks.steam.amount, last_update_s)
|
||||
---@todo unused currently?
|
||||
_compute_dt(DT_KEYS.TurbinePower .. turbine.get_device_idx(), db.tanks.energy, last_update_s)
|
||||
end
|
||||
end
|
||||
|
@ -316,12 +316,13 @@ function logic.update_annunciator(self)
|
||||
self.db.annunciator.SteamFeedMismatch = sfmismatch
|
||||
self.db.annunciator.MaxWaterReturnFeed = max_water_return_rate == total_flow_rate and total_flow_rate ~= 0
|
||||
|
||||
-- check if steam dumps are open
|
||||
-- turbine safety checks
|
||||
for i = 1, #self.turbines do
|
||||
local turbine = self.turbines[i] ---@type unit_session
|
||||
local db = turbine.get_db() ---@type turbinev_session_db
|
||||
local idx = turbine.get_device_idx()
|
||||
|
||||
-- check if steam dumps are open
|
||||
if db.state.dumping_mode == DUMPING_MODE.IDLE then
|
||||
self.db.annunciator.SteamDumpOpen[idx] = TRI_FAIL.OK
|
||||
elseif db.state.dumping_mode == DUMPING_MODE.DUMPING_EXCESS then
|
||||
@ -329,29 +330,28 @@ function logic.update_annunciator(self)
|
||||
else
|
||||
self.db.annunciator.SteamDumpOpen[idx] = TRI_FAIL.FULL
|
||||
end
|
||||
end
|
||||
|
||||
-- check if turbines are at max speed but not keeping up
|
||||
for i = 1, #self.turbines do
|
||||
local turbine = self.turbines[i] ---@type unit_session
|
||||
local db = turbine.get_db() ---@type turbinev_session_db
|
||||
local idx = turbine.get_device_idx()
|
||||
|
||||
-- check if turbines are at max speed but not keeping up
|
||||
self.db.annunciator.TurbineOverSpeed[idx] = (db.state.flow_rate == db.build.max_flow_rate) and (_get_dt(DT_KEYS.TurbineSteam .. idx) > 0.0)
|
||||
end
|
||||
|
||||
--[[
|
||||
Turbine Trip
|
||||
a turbine trip is when the turbine stops, which means we are no longer receiving water and lose the ability to cool.
|
||||
this can be identified by these conditions:
|
||||
- the current flow rate is 0 mB/t and it should not be
|
||||
- can initially catch this by detecting a 0 flow rate with a non-zero input rate, but eventually the steam will fill up
|
||||
- can later identified by presence of steam in tank with a 0 flow rate
|
||||
]]--
|
||||
for i = 1, #self.turbines do
|
||||
local turbine = self.turbines[i] ---@type unit_session
|
||||
local db = turbine.get_db() ---@type turbinev_session_db
|
||||
--[[
|
||||
Generator Trip
|
||||
a generator trip is when a generator suddenly and unexpectedly loses it's external load
|
||||
oftentimes this is when a power plant is disconnected from the grid for one reason or another
|
||||
in this case we just:
|
||||
- check if internal power storage of turbine is increasing
|
||||
that means there is no external load and there will be a turbine trip soon if this is not resolved
|
||||
]]--
|
||||
self.db.annunciator.GeneratorTrip[idx] = _get_dt(DT_KEYS.TurbinePower .. idx) > 0.0
|
||||
|
||||
--[[
|
||||
Turbine Trip
|
||||
a turbine trip is when the turbine stops, which means we are no longer receiving water and lose the ability to cool.
|
||||
this can be identified by these conditions:
|
||||
- the current flow rate is 0 mB/t and it should not be
|
||||
- can initially catch this by detecting a 0 flow rate with a non-zero input rate, but eventually the steam will fill up
|
||||
- can later identified by presence of steam in tank with a 0 flow rate
|
||||
]]--
|
||||
local has_steam = db.state.steam_input_rate > 0 or db.tanks.steam_fill > 0.01
|
||||
self.db.annunciator.TurbineTrip[turbine.get_device_idx()] = has_steam and db.state.flow_rate == 0
|
||||
end
|
||||
@ -506,10 +506,12 @@ function logic.update_alarms(self)
|
||||
-- RCS Transient
|
||||
local any_low = annunc.CoolantLevelLow
|
||||
local any_over = false
|
||||
local gen_trip = false
|
||||
for i = 1, #annunc.WaterLevelLow do any_low = any_low or annunc.WaterLevelLow[i] end
|
||||
for i = 1, #annunc.TurbineOverSpeed do any_over = any_over or annunc.TurbineOverSpeed[i] end
|
||||
for i = 1, #annunc.GeneratorTrip do gen_trip = gen_trip or annunc.GeneratorTrip[i] end
|
||||
|
||||
local rcs_trans = any_low or any_over or annunc.RCPTrip or annunc.MaxWaterReturnFeed
|
||||
local rcs_trans = any_low or any_over or gen_trip or annunc.RCPTrip or annunc.MaxWaterReturnFeed
|
||||
|
||||
-- only care about RCS flow low early with boilers
|
||||
if self.num_boilers > 0 then rcs_trans = rcs_trans or annunc.RCSFlowLow end
|
||||
|
Loading…
Reference in New Issue
Block a user