optimizations and cleanup for pull request

This commit is contained in:
Mikayla Fischler 2023-07-30 00:13:26 -04:00
parent 3f01ce7ec5
commit 724d13510d
10 changed files with 56 additions and 84 deletions

View File

@ -76,30 +76,4 @@ function sounder.continue()
return success
end
--#region Test Functions
-- function sounder.test_1() add(1) play() end -- play tone T_340Hz_Int_2Hz
-- function sounder.test_2() add(2) play() end -- play tone T_544Hz_440Hz_Alt
-- function sounder.test_3() add(3) play() end -- play tone T_660Hz_Int_125ms
-- function sounder.test_4() add(4) play() end -- play tone T_745Hz_Int_1Hz
-- function sounder.test_5() add(5) play() end -- play tone T_800Hz_Int
-- function sounder.test_6() add(6) play() end -- play tone T_800Hz_1000Hz_Alt
-- function sounder.test_7() add(7) play() end -- play tone T_1000Hz_Int
-- function sounder.test_8() add(8) play() end -- play tone T_1800Hz_Int_4Hz
-- function sounder.test_breach(active) test_alarms[ALARM.ContainmentBreach] = active end ---@param active boolean
-- function sounder.test_rad(active) test_alarms[ALARM.ContainmentRadiation] = active end ---@param active boolean
-- function sounder.test_lost(active) test_alarms[ALARM.ReactorLost] = active end ---@param active boolean
-- function sounder.test_crit(active) test_alarms[ALARM.CriticalDamage] = active end ---@param active boolean
-- function sounder.test_dmg(active) test_alarms[ALARM.ReactorDamage] = active end ---@param active boolean
-- function sounder.test_overtemp(active) test_alarms[ALARM.ReactorOverTemp] = active end ---@param active boolean
-- function sounder.test_hightemp(active) test_alarms[ALARM.ReactorHighTemp] = active end ---@param active boolean
-- function sounder.test_wasteleak(active) test_alarms[ALARM.ReactorWasteLeak] = active end ---@param active boolean
-- function sounder.test_highwaste(active) test_alarms[ALARM.ReactorHighWaste] = active end ---@param active boolean
-- function sounder.test_rps(active) test_alarms[ALARM.RPSTransient] = active end ---@param active boolean
-- function sounder.test_rcs(active) test_alarms[ALARM.RCSTransient] = active end ---@param active boolean
-- function sounder.test_turbinet(active) test_alarms[ALARM.TurbineTrip] = active end ---@param active boolean
--#endregion
return sounder

View File

@ -1,4 +1,4 @@
-- Button Graphics Element
-- App Button Graphics Element
local tcd = require("scada-common.tcd")
@ -40,7 +40,7 @@ local function app_button(args)
e.window.setCursorPos(math.floor((e.frame.w - string.len(args.title)) / 2) + 1, 4)
e.window.write(args.title)
-- draw the button
-- draw the app button
local function draw()
local fgd = args.app_fg_bg.fgd
local bkg = args.app_fg_bg.bkg
@ -75,7 +75,7 @@ local function app_button(args)
e.window.write(args.text)
end
-- draw the button as pressed (if active_fg_bg set)
-- draw the app button as pressed (if active_fg_bg set)
local function show_pressed()
if e.enabled and args.active_fg_bg ~= nil then
e.value = true
@ -85,7 +85,7 @@ local function app_button(args)
end
end
-- draw the button as unpressed (if active_fg_bg set)
-- draw the app button as unpressed (if active_fg_bg set)
local function show_unpressed()
if e.enabled and args.active_fg_bg ~= nil then
e.value = false
@ -115,7 +115,7 @@ local function app_button(args)
end
end
-- set the value (true simulates pressing the button)
-- set the value (true simulates pressing the app button)
---@param val boolean new value
function e.set_value(val)
if val then e.handle_mouse(core.events.mouse_generic(core.events.CLICK_TYPE.UP, 1, 1)) end

View File

@ -1,5 +1,5 @@
--
-- I/O Control for Pocket Integration with Supervisor & Coordinator
-- I/O Control for Pocket Integration with Supervisor & Coordinator
--
local psil = require("scada-common.psil")

View File

@ -155,18 +155,18 @@ function pocket.comms(version, nic, pkt_channel, svr_channel, crd_channel, range
end
end
-- supervisor test alarm tones by tone
---@param id tone_id|0 tone ID, or 0 to stop all
---@param state boolean tone state
function public.diag__set_alarm_tone(id, state)
if self.sv.linked then _send_sv(SCADA_MGMT_TYPE.DIAG_TONE_SET, { id, state }) end
end
-- supervisor get active alarm tones
function public.diag__get_alarm_tones()
if self.sv.linked then _send_sv(SCADA_MGMT_TYPE.DIAG_TONE_GET, {}) end
end
-- supervisor test alarm tones by tone
---@param id TONE|0 tone ID, or 0 to stop all
---@param state boolean tone state
function public.diag__set_alarm_tone(id, state)
if self.sv.linked then _send_sv(SCADA_MGMT_TYPE.DIAG_TONE_SET, { id, state }) end
end
-- supervisor test alarm tones by alarm
---@param id ALARM|0 alarm ID, 0 to stop all
---@param state boolean alarm state

View File

@ -1,5 +1,3 @@
-- local style = require("pocket.ui.style")
local iocontrol = require("pocket.iocontrol")
local core = require("graphics.core")

View File

@ -467,7 +467,7 @@ function rtu.comms(version, nic, rtu_channel, svr_channel, range, conn_watchdog)
local s = sounders[i] ---@type rtu_speaker_sounder
-- set tone states
for id = 1, #states do s.stream.set_active(id, states[id]) end
for id = 1, #states do s.stream.set_active(id, states[id] == true) end
end
end
else

View File

@ -14,8 +14,8 @@ local _05s_SAMPLES = 24000 -- half a second worth of samples
---@class audio
local audio = {}
---@enum tone_id
local TONES = {
---@enum TONE
local TONE = {
T_340Hz_Int_2Hz = 1,
T_544Hz_440Hz_Alt = 2,
T_660Hz_Int_125ms = 3,
@ -26,7 +26,7 @@ local TONES = {
T_1800Hz_Int_4Hz = 8
}
audio.TONES = TONES
audio.TONE = TONE
local tone_data = {
{ {}, {}, {}, {} }, -- 340Hz @ 2Hz Intermittent
@ -251,7 +251,7 @@ function audio.new_stream()
local public = {}
-- add a tone to the output buffer
---@param index tone_id tone ID
---@param index TONE tone ID
---@param active boolean active state
function public.set_active(index, active)
if self.tone_active[index] ~= nil then
@ -261,7 +261,7 @@ function audio.new_stream()
end
-- check if a tone is active
---@param index tone_id tone index
---@param index TONE tone index
function public.is_active(index)
if self.tone_active[index] then return self.tone_active[index] end
return false

View File

@ -9,7 +9,7 @@ local unit = require("supervisor.unit")
local rsctl = require("supervisor.session.rsctl")
local TONES = audio.TONES
local TONE = audio.TONE
local ALARM = types.ALARM
local PRIO = types.ALARM_PRIORITY
@ -783,13 +783,8 @@ function facility.new(num_reactors, cooling_conf)
local alarms = { false, false, false, false, false, false, false, false, false, false, false, false }
for i = 1, #self.tone_states do
-- reset tone states before re-evaluting
self.tone_states[i] = false
-- clear testing tones if we aren't using them
if (not allow_test) and (not self.test_tone_reset) then self.test_tone_states[i] = false end
end
-- reset tone states before re-evaluting
for i = 1, #self.tone_states do self.tone_states[i] = false end
if allow_test then
alarms = self.test_alarm_states
@ -799,64 +794,58 @@ function facility.new(num_reactors, cooling_conf)
local u = self.units[i] ---@type reactor_unit
for id, alarm in pairs(u.get_alarms()) do
alarms[id] = alarms[id] or (alarm == ALARM_STATE.TRIPPED)
-- clear testing alarms if we aren't using them
if not self.test_tone_reset then self.test_alarm_states[id] = false end
end
end
self.test_tone_reset = true
end
-- flag that tones were reset to notify diagnostic accessor
if not allow_test then
self.test_tone_set = false
self.test_tone_reset = true
if not self.test_tone_reset then
-- clear testing alarms if we aren't using them
for i = 1, #self.test_alarm_states do self.test_alarm_states[i] = false end
end
end
-- Evaluate Alarms --
-- containment breach is worst case CRITICAL alarm, this takes priority
if alarms[ALARM.ContainmentBreach] then
self.tone_states[TONES.T_1800Hz_Int_4Hz] = true
self.tone_states[TONE.T_1800Hz_Int_4Hz] = true
else
-- critical damage is highest priority CRITICAL level alarm
if alarms[ALARM.CriticalDamage] then
self.tone_states[TONES.T_660Hz_Int_125ms] = true
self.tone_states[TONE.T_660Hz_Int_125ms] = true
else
-- EMERGENCY level alarms + URGENT over temp
if alarms[ALARM.ReactorDamage] or alarms[ALARM.ReactorOverTemp] or alarms[ALARM.ReactorWasteLeak] then
self.tone_states[TONES.T_544Hz_440Hz_Alt] = true
self.tone_states[TONE.T_544Hz_440Hz_Alt] = true
-- URGENT level turbine trip
elseif alarms[ALARM.TurbineTrip] then
self.tone_states[TONES.T_745Hz_Int_1Hz] = true
self.tone_states[TONE.T_745Hz_Int_1Hz] = true
-- URGENT level reactor lost
elseif alarms[ALARM.ReactorLost] then
self.tone_states[TONES.T_340Hz_Int_2Hz] = true
self.tone_states[TONE.T_340Hz_Int_2Hz] = true
-- TIMELY level alarms
elseif alarms[ALARM.ReactorHighTemp] or alarms[ALARM.ReactorHighWaste] or alarms[ALARM.RCSTransient] then
self.tone_states[TONES.T_800Hz_Int] = true
self.tone_states[TONE.T_800Hz_Int] = true
end
end
-- check RPS transient URGENT level alarm
if alarms[ALARM.RPSTransient] then
self.tone_states[TONES.T_1000Hz_Int] = true
self.tone_states[TONE.T_1000Hz_Int] = true
-- disable really painful audio combination
self.tone_states[TONES.T_340Hz_Int_2Hz] = false
self.tone_states[TONE.T_340Hz_Int_2Hz] = false
end
end
-- radiation is a big concern, always play this CRITICAL level alarm if active
if alarms[ALARM.ContainmentRadiation] then
self.tone_states[TONES.T_800Hz_1000Hz_Alt] = true
self.tone_states[TONE.T_800Hz_1000Hz_Alt] = true
-- we are going to disable the RPS trip alarm audio due to conflict, and if it was enabled
-- then we can re-enable the reactor lost alarm audio since it doesn't painfully combine with this one
if self.tone_states[TONES.T_1000Hz_Int] and alarms[ALARM.ReactorLost] then self.tone_states[TONES.T_340Hz_Int_2Hz] = true end
if self.tone_states[TONE.T_1000Hz_Int] and alarms[ALARM.ReactorLost] then self.tone_states[TONE.T_340Hz_Int_2Hz] = true end
-- it sounds *really* bad if this is in conjunction with these other tones, so disable them
self.tone_states[TONES.T_745Hz_Int_1Hz] = false
self.tone_states[TONES.T_800Hz_Int] = false
self.tone_states[TONES.T_1000Hz_Int] = false
self.tone_states[TONE.T_745Hz_Int_1Hz] = false
self.tone_states[TONE.T_800Hz_Int] = false
self.tone_states[TONE.T_1000Hz_Int] = false
end
-- add to tone states if testing is active
@ -864,6 +853,17 @@ function facility.new(num_reactors, cooling_conf)
for i = 1, #self.tone_states do
self.tone_states[i] = self.tone_states[i] or self.test_tone_states[i]
end
self.test_tone_reset = false
else
if not self.test_tone_reset then
-- clear testing tones if we aren't using them
for i = 1, #self.test_tone_states do self.test_tone_states[i] = false end
end
-- flag that tones were reset
self.test_tone_set = false
self.test_tone_reset = true
end
end
@ -1009,7 +1009,7 @@ function facility.new(num_reactors, cooling_conf)
-- DIAGNOSTIC TESTING --
-- attempt to set a test tone state
---@param id tone_id|0 tone ID or 0 to disable all
---@param id TONE|0 tone ID or 0 to disable all
---@param state boolean state
---@return boolean allow_testing, table test_tone_states
function public.diag_set_test_tone(id, state)

View File

@ -142,7 +142,7 @@ function pocket.new_session(id, s_addr, in_queue, out_queue, timeout, facility,
if type(pkt.data[1]) == "number" and type(pkt.data[2]) == "boolean" then
valid = true
-- try to set tone states, then send back if testing is allowed
-- try to set tone states, then send back if testing is allowed
local allow_testing, test_tone_states = facility.diag_set_test_tone(pkt.data[1], pkt.data[2])
_send_mgmt(SCADA_MGMT_TYPE.DIAG_TONE_SET, { allow_testing, test_tone_states })
else
@ -165,7 +165,7 @@ function pocket.new_session(id, s_addr, in_queue, out_queue, timeout, facility,
if type(pkt.data[1]) == "number" and type(pkt.data[2]) == "boolean" then
valid = true
-- try to set alarm states, then send back if testing is allowed
-- try to set alarm states, then send back if testing is allowed
local allow_testing, test_alarm_states = facility.diag_set_test_alarm(pkt.data[1], pkt.data[2])
_send_mgmt(SCADA_MGMT_TYPE.DIAG_ALARM_SET, { allow_testing, test_alarm_states })
else

View File

@ -725,14 +725,14 @@ function unit.new(reactor_id, num_boilers, num_turbines)
-- can't be disconnected
if self.plc_i == nil then return false end
-- reactor must be stopped and RPS can't be tripped
if self.plc_i.get_status().status or self.plc_i.get_db().rps_tripped then return false end
-- alarms must be inactive and not tripping
for _, alarm in pairs(self.alarms) do
if not (alarm.state == AISTATE.INACTIVE or alarm.state == AISTATE.RING_BACK) then return false end
end
-- reactor must be stopped and RPS can't be tripped
if self.plc_i.get_status().status or self.plc_i.get_db().rps_tripped then return false end
return true
end