2022-06-16 15:24:35 +00:00
--
-- Main SCADA Coordinator GUI
--
2023-01-15 18:11:46 +00:00
local util = require ( " scada-common.util " )
2022-09-07 02:38:27 +00:00
local iocontrol = require ( " coordinator.iocontrol " )
2022-12-04 18:59:10 +00:00
local sounder = require ( " coordinator.sounder " )
2022-07-10 20:15:30 +00:00
2022-09-05 20:04:32 +00:00
local style = require ( " coordinator.ui.style " )
2022-06-16 15:24:35 +00:00
2023-01-15 18:11:46 +00:00
local imatrix = require ( " coordinator.ui.components.imatrix " )
local process_ctl = require ( " coordinator.ui.components.processctl " )
2022-06-16 15:24:35 +00:00
local unit_overview = require ( " coordinator.ui.components.unit_overview " )
2022-09-05 20:04:32 +00:00
local core = require ( " graphics.core " )
2022-12-04 18:59:10 +00:00
local ColorMap = require ( " graphics.elements.colormap " )
2022-09-05 20:04:32 +00:00
local DisplayBox = require ( " graphics.elements.displaybox " )
2023-01-15 18:11:46 +00:00
local Div = require ( " graphics.elements.div " )
2022-09-05 20:04:32 +00:00
local TextBox = require ( " graphics.elements.textbox " )
2022-12-04 18:59:10 +00:00
local PushButton = require ( " graphics.elements.controls.push_button " )
local SwitchButton = require ( " graphics.elements.controls.switch_button " )
2022-12-06 16:40:13 +00:00
local DataIndicator = require ( " graphics.elements.indicators.data " )
2022-06-16 15:24:35 +00:00
local TEXT_ALIGN = core.graphics . TEXT_ALIGN
2022-12-04 18:59:10 +00:00
local cpair = core.graphics . cpair
2022-09-07 02:38:27 +00:00
-- create new main view
2023-02-23 04:09:47 +00:00
---@nodiscard
2022-09-07 02:38:27 +00:00
---@param monitor table main viewscreen
2022-06-16 15:24:35 +00:00
local function init ( monitor )
2022-12-06 16:40:13 +00:00
local facility = iocontrol.get_db ( ) . facility
local units = iocontrol.get_db ( ) . units
2022-06-16 15:24:35 +00:00
local main = DisplayBox { window = monitor , fg_bg = style.root }
-- window header message
2022-12-06 16:40:13 +00:00
local header = TextBox { parent = main , y = 1 , text = " Nuclear Generation Facility SCADA Coordinator " , alignment = TEXT_ALIGN.CENTER , height = 1 , fg_bg = style.header }
local ping = DataIndicator { parent = main , x = 1 , y = 1 , label = " SVTT " , format = " %d " , value = 0 , unit = " ms " , lu_colors = cpair ( colors.lightGray , colors.white ) , width = 12 , fg_bg = style.header }
-- max length example: "01:23:45 AM - Wednesday, September 28 2022"
local datetime = TextBox { parent = main , x = ( header.width ( ) - 42 ) , y = 1 , text = " " , alignment = TEXT_ALIGN.RIGHT , width = 42 , height = 1 , fg_bg = style.header }
2022-06-16 15:24:35 +00:00
2022-12-06 16:40:13 +00:00
facility.ps . subscribe ( " sv_ping " , ping.update )
facility.ps . subscribe ( " date_time " , datetime.set_value )
2022-07-10 20:15:30 +00:00
2022-07-14 17:47:39 +00:00
local uo_1 , uo_2 , uo_3 , uo_4 ---@type graphics_element
2022-12-05 21:17:09 +00:00
local cnc_y_start = 3
2023-02-03 03:58:51 +00:00
local row_1_height = 0
2022-12-05 21:17:09 +00:00
2022-06-16 15:24:35 +00:00
-- unit overviews
2022-12-06 16:40:13 +00:00
if facility.num_units >= 1 then
uo_1 = unit_overview ( main , 2 , 3 , units [ 1 ] )
2023-02-03 03:58:51 +00:00
row_1_height = uo_1.height ( )
2022-12-05 21:17:09 +00:00
end
2022-12-06 16:40:13 +00:00
if facility.num_units >= 2 then
uo_2 = unit_overview ( main , 84 , 3 , units [ 2 ] )
2023-02-03 03:58:51 +00:00
row_1_height = math.max ( row_1_height , uo_2.height ( ) )
2022-12-05 21:17:09 +00:00
end
2022-07-14 17:47:39 +00:00
2023-02-03 03:58:51 +00:00
cnc_y_start = cnc_y_start + row_1_height + 1
2022-12-06 16:40:13 +00:00
if facility.num_units >= 3 then
2022-07-14 17:47:39 +00:00
-- base offset 3, spacing 1, max height of units 1 and 2
2023-02-03 03:58:51 +00:00
local row_2_offset = cnc_y_start
2022-07-14 17:47:39 +00:00
2022-12-06 16:40:13 +00:00
uo_3 = unit_overview ( main , 2 , row_2_offset , units [ 3 ] )
2023-02-03 03:58:51 +00:00
cnc_y_start = row_2_offset + uo_3.height ( ) + 1
2022-12-05 21:17:09 +00:00
2022-12-06 16:40:13 +00:00
if facility.num_units == 4 then
uo_4 = unit_overview ( main , 84 , row_2_offset , units [ 4 ] )
2023-02-03 03:58:51 +00:00
cnc_y_start = math.max ( cnc_y_start , row_2_offset + uo_4.height ( ) + 1 )
2022-12-05 21:17:09 +00:00
end
2022-07-14 17:47:39 +00:00
end
2023-02-23 04:09:47 +00:00
-- command & control
2022-06-16 15:24:35 +00:00
2023-02-05 17:15:41 +00:00
cnc_y_start = cnc_y_start
2022-12-05 21:17:09 +00:00
2023-02-05 17:15:41 +00:00
-- induction matrix and process control interfaces are 24 tall + space needed for divider
local cnc_bottom_align_start = main.height ( ) - 26
2022-12-10 20:44:11 +00:00
2023-02-05 17:15:41 +00:00
assert ( cnc_bottom_align_start >= cnc_y_start , " main display not of sufficient vertical resolution (add an additional row of monitors) " )
TextBox { parent = main , y = cnc_bottom_align_start , text = util.strrep ( " \x8c " , header.width ( ) ) , alignment = TEXT_ALIGN.CENTER , height = 1 , fg_bg = cpair ( colors.lightGray , colors.gray ) }
cnc_bottom_align_start = cnc_bottom_align_start + 2
2023-02-23 04:09:47 +00:00
local _ = process_ctl ( main , 2 , cnc_bottom_align_start )
2023-01-15 18:11:46 +00:00
2022-12-04 18:59:10 +00:00
-- testing
---@fixme remove test code
2023-02-05 07:07:54 +00:00
-- ColorMap{parent=main,x=98,y=(main.height()-1)}
2023-02-04 18:47:00 +00:00
2023-02-05 17:15:41 +00:00
local audio = Div { parent = main , width = 23 , height = 23 , x = 107 , y = cnc_bottom_align_start }
2023-02-04 18:47:00 +00:00
PushButton { parent = audio , x = 16 , y = 1 , text = " TEST 1 " , min_width = 8 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_1 }
PushButton { parent = audio , x = 16 , text = " TEST 2 " , min_width = 8 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_2 }
PushButton { parent = audio , x = 16 , text = " TEST 3 " , min_width = 8 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_3 }
PushButton { parent = audio , x = 16 , text = " TEST 4 " , min_width = 8 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_4 }
PushButton { parent = audio , x = 16 , text = " TEST 5 " , min_width = 8 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_5 }
PushButton { parent = audio , x = 16 , text = " TEST 6 " , min_width = 8 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_6 }
PushButton { parent = audio , x = 16 , text = " TEST 7 " , min_width = 8 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_7 }
PushButton { parent = audio , x = 16 , text = " TEST 8 " , min_width = 8 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_8 }
PushButton { parent = audio , x = 16 , text = " STOP " , min_width = 8 , fg_bg = cpair ( colors.black , colors.red ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.stop }
PushButton { parent = audio , x = 16 , text = " PSCALE " , min_width = 8 , fg_bg = cpair ( colors.black , colors.blue ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_power_scale }
SwitchButton { parent = audio , x = 1 , y = 12 , text = " CONTAINMENT BREACH " , min_width = 23 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_breach }
SwitchButton { parent = audio , x = 1 , text = " CONTAINMENT RADIATION " , min_width = 23 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_rad }
SwitchButton { parent = audio , x = 1 , text = " REACTOR LOST " , min_width = 23 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_lost }
SwitchButton { parent = audio , x = 1 , text = " CRITICAL DAMAGE " , min_width = 23 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_crit }
SwitchButton { parent = audio , x = 1 , text = " REACTOR DAMAGE " , min_width = 23 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_dmg }
SwitchButton { parent = audio , x = 1 , text = " REACTOR OVER TEMP " , min_width = 23 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_overtemp }
SwitchButton { parent = audio , x = 1 , text = " REACTOR HIGH TEMP " , min_width = 23 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_hightemp }
SwitchButton { parent = audio , x = 1 , text = " REACTOR WASTE LEAK " , min_width = 23 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_wasteleak }
SwitchButton { parent = audio , x = 1 , text = " REACTOR WASTE HIGH " , min_width = 23 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_highwaste }
SwitchButton { parent = audio , x = 1 , text = " RPS TRANSIENT " , min_width = 23 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_rps }
SwitchButton { parent = audio , x = 1 , text = " RCS TRANSIENT " , min_width = 23 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_rcs }
SwitchButton { parent = audio , x = 1 , text = " TURBINE TRIP " , min_width = 23 , fg_bg = cpair ( colors.black , colors.yellow ) , active_fg_bg = cpair ( colors.white , colors.gray ) , callback = sounder.test_turbinet }
2022-12-04 18:59:10 +00:00
2023-02-23 04:09:47 +00:00
local _ = imatrix ( main , 131 , cnc_bottom_align_start , facility.induction_data_tbl [ 1 ] , facility.induction_ps_tbl [ 1 ] )
2022-12-10 20:44:11 +00:00
2022-06-16 15:24:35 +00:00
return main
end
return init