mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
#200 work in progress unit views and sidebar/app updates
This commit is contained in:
parent
3bfcb1d83c
commit
0c6c7bf9a5
@ -30,7 +30,7 @@ local function app_button(args)
|
|||||||
element.assert(type(args.app_fg_bg) == "table", "app_fg_bg is a required field")
|
element.assert(type(args.app_fg_bg) == "table", "app_fg_bg is a required field")
|
||||||
|
|
||||||
args.height = 4
|
args.height = 4
|
||||||
args.width = 5
|
args.width = 7
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
@ -46,7 +46,7 @@ local function app_button(args)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- draw icon
|
-- draw icon
|
||||||
e.w_set_cur(1, 1)
|
e.w_set_cur(2, 1)
|
||||||
e.w_set_fgd(fgd)
|
e.w_set_fgd(fgd)
|
||||||
e.w_set_bkg(bkg)
|
e.w_set_bkg(bkg)
|
||||||
e.w_write("\x9f\x83\x83\x83")
|
e.w_write("\x9f\x83\x83\x83")
|
||||||
@ -55,16 +55,16 @@ local function app_button(args)
|
|||||||
e.w_write("\x90")
|
e.w_write("\x90")
|
||||||
e.w_set_fgd(fgd)
|
e.w_set_fgd(fgd)
|
||||||
e.w_set_bkg(bkg)
|
e.w_set_bkg(bkg)
|
||||||
e.w_set_cur(1, 2)
|
e.w_set_cur(2, 2)
|
||||||
e.w_write("\x95 ")
|
e.w_write("\x95 ")
|
||||||
e.w_set_fgd(bkg)
|
e.w_set_fgd(bkg)
|
||||||
e.w_set_bkg(fgd)
|
e.w_set_bkg(fgd)
|
||||||
e.w_write("\x95")
|
e.w_write("\x95")
|
||||||
e.w_set_cur(1, 3)
|
e.w_set_cur(2, 3)
|
||||||
e.w_write("\x82\x8f\x8f\x8f\x81")
|
e.w_write("\x82\x8f\x8f\x8f\x81")
|
||||||
|
|
||||||
-- write the icon text
|
-- write the icon text
|
||||||
e.w_set_cur(3, 2)
|
e.w_set_cur(4, 2)
|
||||||
e.w_set_fgd(fgd)
|
e.w_set_fgd(fgd)
|
||||||
e.w_set_bkg(bkg)
|
e.w_set_bkg(bkg)
|
||||||
e.w_write(args.text)
|
e.w_write(args.text)
|
||||||
|
@ -8,13 +8,7 @@ local element = require("graphics.element")
|
|||||||
|
|
||||||
local MOUSE_CLICK = core.events.MOUSE_CLICK
|
local MOUSE_CLICK = core.events.MOUSE_CLICK
|
||||||
|
|
||||||
---@class sidebar_tab
|
|
||||||
---@field char string character identifier
|
|
||||||
---@field color cpair tab colors (fg/bg)
|
|
||||||
|
|
||||||
---@class sidebar_args
|
---@class sidebar_args
|
||||||
---@field tabs table sidebar tab options
|
|
||||||
---@field callback function function to call on tab change
|
|
||||||
---@field parent graphics_element
|
---@field parent graphics_element
|
||||||
---@field id? string element id
|
---@field id? string element id
|
||||||
---@field x? integer 1 if omitted
|
---@field x? integer 1 if omitted
|
||||||
@ -27,21 +21,16 @@ local MOUSE_CLICK = core.events.MOUSE_CLICK
|
|||||||
---@param args sidebar_args
|
---@param args sidebar_args
|
||||||
---@return graphics_element element, element_id id
|
---@return graphics_element element, element_id id
|
||||||
local function sidebar(args)
|
local function sidebar(args)
|
||||||
element.assert(type(args.tabs) == "table", "tabs is a required field")
|
|
||||||
element.assert(#args.tabs > 0, "at least one tab is required")
|
|
||||||
element.assert(type(args.callback) == "function", "callback is a required field")
|
|
||||||
|
|
||||||
args.width = 3
|
args.width = 3
|
||||||
|
|
||||||
-- create new graphics element base object
|
-- create new graphics element base object
|
||||||
local e = element.new(args)
|
local e = element.new(args)
|
||||||
|
|
||||||
element.assert(e.frame.h >= (#args.tabs * 3), "height insufficent to display all tabs")
|
|
||||||
|
|
||||||
-- default to 1st tab
|
-- default to 1st tab
|
||||||
e.value = 1
|
e.value = 1
|
||||||
|
|
||||||
local was_pressed = false
|
local was_pressed = false
|
||||||
|
local tabs = {}
|
||||||
|
|
||||||
-- show the button state
|
-- show the button state
|
||||||
---@param pressed? boolean if the currently selected tab should appear as actively pressed
|
---@param pressed? boolean if the currently selected tab should appear as actively pressed
|
||||||
@ -51,10 +40,18 @@ local function sidebar(args)
|
|||||||
was_pressed = pressed
|
was_pressed = pressed
|
||||||
pressed_idx = pressed_idx or e.value
|
pressed_idx = pressed_idx or e.value
|
||||||
|
|
||||||
for i = 1, #args.tabs do
|
-- clear
|
||||||
local tab = args.tabs[i] ---@type sidebar_tab
|
e.w_set_fgd(e.fg_bg.fgd)
|
||||||
|
e.w_set_bkg(e.fg_bg.bkg)
|
||||||
|
for y = 1, e.frame.h do
|
||||||
|
e.w_set_cur(1, y)
|
||||||
|
e.w_write(" ")
|
||||||
|
end
|
||||||
|
|
||||||
local y = ((i - 1) * 3) + 1
|
-- draw tabs
|
||||||
|
for i = 1, #tabs do
|
||||||
|
local tab = tabs[i] ---@type sidebar_tab
|
||||||
|
local y = tab.y_start
|
||||||
|
|
||||||
e.w_set_cur(1, y)
|
e.w_set_cur(1, y)
|
||||||
|
|
||||||
@ -66,38 +63,54 @@ local function sidebar(args)
|
|||||||
e.w_set_bkg(tab.color.bkg)
|
e.w_set_bkg(tab.color.bkg)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if tab.tall then
|
||||||
e.w_write(" ")
|
e.w_write(" ")
|
||||||
e.w_set_cur(1, y + 1)
|
e.w_set_cur(1, y + 1)
|
||||||
if e.value == i then
|
end
|
||||||
e.w_write(" " .. tab.char .. "\x10")
|
|
||||||
else e.w_write(" " .. tab.char .. " ") end
|
e.w_write(tab.label)
|
||||||
|
|
||||||
|
if tab.tall then
|
||||||
e.w_set_cur(1, y + 2)
|
e.w_set_cur(1, y + 2)
|
||||||
e.w_write(" ")
|
e.w_write(" ")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- determine which tab was pressed
|
||||||
|
---@param y integer y coordinate
|
||||||
|
local function find_tab(y)
|
||||||
|
for i = 1, #tabs do
|
||||||
|
local tab = tabs[i] ---@type sidebar_tab
|
||||||
|
|
||||||
|
if y >= tab.y_start and y <= tab.y_end then
|
||||||
|
return i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- handle mouse interaction
|
-- handle mouse interaction
|
||||||
---@param event mouse_interaction mouse event
|
---@param event mouse_interaction mouse event
|
||||||
function e.handle_mouse(event)
|
function e.handle_mouse(event)
|
||||||
-- determine what was pressed
|
-- determine what was pressed
|
||||||
if e.enabled then
|
if e.enabled then
|
||||||
local cur_idx = math.ceil(event.current.y / 3)
|
local cur_idx = find_tab(event.current.y)
|
||||||
local ini_idx = math.ceil(event.initial.y / 3)
|
local ini_idx = find_tab(event.initial.y)
|
||||||
|
|
||||||
if args.tabs[cur_idx] ~= nil then
|
if tabs[cur_idx] ~= nil then
|
||||||
if event.type == MOUSE_CLICK.TAP then
|
if event.type == MOUSE_CLICK.TAP then
|
||||||
e.value = cur_idx
|
e.value = cur_idx
|
||||||
draw(true)
|
draw(true)
|
||||||
-- show as unpressed in 0.25 seconds
|
-- show as unpressed in 0.25 seconds
|
||||||
tcd.dispatch(0.25, function () draw(false) end)
|
tcd.dispatch(0.25, function () draw(false) end)
|
||||||
args.callback(e.value)
|
tabs[cur_idx].callback()
|
||||||
elseif event.type == MOUSE_CLICK.DOWN then
|
elseif event.type == MOUSE_CLICK.DOWN then
|
||||||
draw(true, cur_idx)
|
draw(true, cur_idx)
|
||||||
elseif event.type == MOUSE_CLICK.UP then
|
elseif event.type == MOUSE_CLICK.UP then
|
||||||
if cur_idx == ini_idx and e.in_frame_bounds(event.current.x, event.current.y) then
|
if cur_idx == ini_idx and e.in_frame_bounds(event.current.x, event.current.y) then
|
||||||
e.value = cur_idx
|
e.value = cur_idx
|
||||||
draw(false)
|
draw(false)
|
||||||
args.callback(e.value)
|
tabs[cur_idx].callback()
|
||||||
else draw(false) end
|
else draw(false) end
|
||||||
end
|
end
|
||||||
elseif event.type == MOUSE_CLICK.UP then
|
elseif event.type == MOUSE_CLICK.UP then
|
||||||
@ -113,6 +126,35 @@ local function sidebar(args)
|
|||||||
draw(false)
|
draw(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- update the sidebar nav options
|
||||||
|
---@param items table sidebar entries
|
||||||
|
function e.on_update(items)
|
||||||
|
local next_y = 1
|
||||||
|
|
||||||
|
tabs = {}
|
||||||
|
|
||||||
|
for i = 1, #items do
|
||||||
|
local item = items[i]
|
||||||
|
local height = util.trinary(item.tall, 3, 1)
|
||||||
|
|
||||||
|
---@class sidebar_tab
|
||||||
|
local entry = {
|
||||||
|
y_start = next_y,
|
||||||
|
y_end = next_y + height - 1,
|
||||||
|
tall = item.tall,
|
||||||
|
label = item.label,
|
||||||
|
color = item.color,
|
||||||
|
callback = item.callback
|
||||||
|
}
|
||||||
|
|
||||||
|
next_y = next_y + height
|
||||||
|
|
||||||
|
tabs[i] = entry
|
||||||
|
end
|
||||||
|
|
||||||
|
draw()
|
||||||
|
end
|
||||||
|
|
||||||
-- element redraw
|
-- element redraw
|
||||||
e.redraw = draw
|
e.redraw = draw
|
||||||
|
|
||||||
|
@ -5,8 +5,10 @@
|
|||||||
local log = require("scada-common.log")
|
local log = require("scada-common.log")
|
||||||
local psil = require("scada-common.psil")
|
local psil = require("scada-common.psil")
|
||||||
local types = require("scada-common.types")
|
local types = require("scada-common.types")
|
||||||
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
local ALARM = types.ALARM
|
local ALARM = types.ALARM
|
||||||
|
local ALARM_STATE = types.ALARM_STATE
|
||||||
|
|
||||||
---@todo nominal trip time is ping (0ms to 10ms usually)
|
---@todo nominal trip time is ping (0ms to 10ms usually)
|
||||||
local WARN_TT = 40
|
local WARN_TT = 40
|
||||||
@ -72,6 +74,10 @@ function iocontrol.alloc_nav()
|
|||||||
self.pane = root_pane
|
self.pane = root_pane
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function io.nav.set_sidebar(sidebar)
|
||||||
|
self.sidebar = sidebar
|
||||||
|
end
|
||||||
|
|
||||||
-- register an app
|
-- register an app
|
||||||
---@param app_id POCKET_APP_ID app ID
|
---@param app_id POCKET_APP_ID app ID
|
||||||
---@param container graphics_element element that contains this app (usually a Div)
|
---@param container graphics_element element that contains this app (usually a Div)
|
||||||
@ -79,18 +85,37 @@ function iocontrol.alloc_nav()
|
|||||||
function io.nav.register_app(app_id, container, pane)
|
function io.nav.register_app(app_id, container, pane)
|
||||||
---@class pocket_app
|
---@class pocket_app
|
||||||
local app = {
|
local app = {
|
||||||
|
loaded = false,
|
||||||
|
load = nil,
|
||||||
root = { _p = nil, _c = {}, nav_to = function () end, tasks = {} }, ---@type nav_tree_page
|
root = { _p = nil, _c = {}, nav_to = function () end, tasks = {} }, ---@type nav_tree_page
|
||||||
cur_page = nil, ---@type nav_tree_page
|
cur_page = nil, ---@type nav_tree_page
|
||||||
pane = pane,
|
pane = pane,
|
||||||
paned_pages = {}
|
paned_pages = {},
|
||||||
|
sidebar_items = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.load = function () app.loaded = true end
|
||||||
|
|
||||||
-- delayed set of the pane if it wasn't ready at the start
|
-- delayed set of the pane if it wasn't ready at the start
|
||||||
---@param root_pane graphics_element multipane
|
---@param root_pane graphics_element multipane
|
||||||
function app.set_root_pane(root_pane)
|
function app.set_root_pane(root_pane)
|
||||||
app.pane = root_pane
|
app.pane = root_pane
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function app.set_sidebar(items)
|
||||||
|
app.sidebar_items = items
|
||||||
|
if self.sidebar then self.sidebar.update(items) end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- function to run on initial load into memory
|
||||||
|
---@param on_load function callback
|
||||||
|
function app.set_on_load(on_load)
|
||||||
|
app.load = function ()
|
||||||
|
on_load()
|
||||||
|
app.loaded = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- if a pane was provided, this will switch between numbered pages
|
-- if a pane was provided, this will switch between numbered pages
|
||||||
---@param idx integer page index
|
---@param idx integer page index
|
||||||
function app.switcher(idx)
|
function app.switcher(idx)
|
||||||
@ -160,9 +185,16 @@ function iocontrol.alloc_nav()
|
|||||||
-- open a given app
|
-- open a given app
|
||||||
---@param app_id POCKET_APP_ID
|
---@param app_id POCKET_APP_ID
|
||||||
function io.nav.open_app(app_id)
|
function io.nav.open_app(app_id)
|
||||||
if self.apps[app_id] then
|
local app = self.apps[app_id] ---@type pocket_app
|
||||||
|
if app then
|
||||||
|
if not app.loaded then app.load() end
|
||||||
|
|
||||||
self.cur_app = app_id
|
self.cur_app = app_id
|
||||||
self.pane.set_value(app_id)
|
self.pane.set_value(app_id)
|
||||||
|
|
||||||
|
if #app.sidebar_items > 0 then
|
||||||
|
self.sidebar.update(app.sidebar_items)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
log.debug("tried to open unknown app")
|
log.debug("tried to open unknown app")
|
||||||
end
|
end
|
||||||
@ -262,6 +294,16 @@ function iocontrol.init_fac(conf, temp_scale)
|
|||||||
auto_ramping = false,
|
auto_ramping = false,
|
||||||
auto_saturated = false,
|
auto_saturated = false,
|
||||||
|
|
||||||
|
auto_scram = false,
|
||||||
|
---@type ascram_status
|
||||||
|
ascram_status = {
|
||||||
|
matrix_dc = false,
|
||||||
|
matrix_fill = false,
|
||||||
|
crit_alarm = false,
|
||||||
|
radiation = false,
|
||||||
|
gen_fault = false
|
||||||
|
},
|
||||||
|
|
||||||
---@type WASTE_PRODUCT
|
---@type WASTE_PRODUCT
|
||||||
auto_current_waste_product = types.WASTE_PRODUCT.PLUTONIUM,
|
auto_current_waste_product = types.WASTE_PRODUCT.PLUTONIUM,
|
||||||
auto_pu_fallback_active = false,
|
auto_pu_fallback_active = false,
|
||||||
@ -282,6 +324,179 @@ function iocontrol.init_fac(conf, temp_scale)
|
|||||||
env_d_ps = psil.create(),
|
env_d_ps = psil.create(),
|
||||||
env_d_data = {}
|
env_d_data = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- create induction and SPS tables (currently only 1 of each is supported)
|
||||||
|
table.insert(io.facility.induction_ps_tbl, psil.create())
|
||||||
|
table.insert(io.facility.induction_data_tbl, {})
|
||||||
|
table.insert(io.facility.sps_ps_tbl, psil.create())
|
||||||
|
table.insert(io.facility.sps_data_tbl, {})
|
||||||
|
|
||||||
|
-- determine tank information
|
||||||
|
if io.facility.tank_mode == 0 then
|
||||||
|
io.facility.tank_defs = {}
|
||||||
|
-- on facility tank mode 0, setup tank defs to match unit tank option
|
||||||
|
for i = 1, conf.num_units do
|
||||||
|
io.facility.tank_defs[i] = util.trinary(conf.cooling.r_cool[i].TankConnection, 1, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
io.facility.tank_list = { table.unpack(io.facility.tank_defs) }
|
||||||
|
else
|
||||||
|
-- decode the layout of tanks from the connections definitions
|
||||||
|
local tank_mode = io.facility.tank_mode
|
||||||
|
local tank_defs = io.facility.tank_defs
|
||||||
|
local tank_list = { table.unpack(tank_defs) }
|
||||||
|
|
||||||
|
local function calc_fdef(start_idx, end_idx)
|
||||||
|
local first = 4
|
||||||
|
for i = start_idx, end_idx do
|
||||||
|
if io.facility.tank_defs[i] == 2 then
|
||||||
|
if i < first then first = i end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return first
|
||||||
|
end
|
||||||
|
|
||||||
|
if tank_mode == 1 then
|
||||||
|
-- (1) 1 total facility tank (A A A A)
|
||||||
|
local first_fdef = calc_fdef(1, #tank_defs)
|
||||||
|
for i = 1, #tank_defs do
|
||||||
|
if i > first_fdef and tank_defs[i] == 2 then
|
||||||
|
tank_list[i] = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif tank_mode == 2 then
|
||||||
|
-- (2) 2 total facility tanks (A A A B)
|
||||||
|
local first_fdef = calc_fdef(1, math.min(3, #tank_defs))
|
||||||
|
for i = 1, #tank_defs do
|
||||||
|
if (i ~= 4) and (i > first_fdef) and (tank_defs[i] == 2) then
|
||||||
|
tank_list[i] = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif tank_mode == 3 then
|
||||||
|
-- (3) 2 total facility tanks (A A B B)
|
||||||
|
for _, a in pairs({ 1, 3 }) do
|
||||||
|
local b = a + 1
|
||||||
|
if (tank_defs[a] == 2) and (tank_defs[b] == 2) then
|
||||||
|
tank_list[b] = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif tank_mode == 4 then
|
||||||
|
-- (4) 2 total facility tanks (A B B B)
|
||||||
|
local first_fdef = calc_fdef(2, #tank_defs)
|
||||||
|
for i = 1, #tank_defs do
|
||||||
|
if (i ~= 1) and (i > first_fdef) and (tank_defs[i] == 2) then
|
||||||
|
tank_list[i] = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif tank_mode == 5 then
|
||||||
|
-- (5) 3 total facility tanks (A A B C)
|
||||||
|
local first_fdef = calc_fdef(1, math.min(2, #tank_defs))
|
||||||
|
for i = 1, #tank_defs do
|
||||||
|
if (not (i == 3 or i == 4)) and (i > first_fdef) and (tank_defs[i] == 2) then
|
||||||
|
tank_list[i] = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif tank_mode == 6 then
|
||||||
|
-- (6) 3 total facility tanks (A B B C)
|
||||||
|
local first_fdef = calc_fdef(2, math.min(3, #tank_defs))
|
||||||
|
for i = 1, #tank_defs do
|
||||||
|
if (not (i == 1 or i == 4)) and (i > first_fdef) and (tank_defs[i] == 2) then
|
||||||
|
tank_list[i] = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif tank_mode == 7 then
|
||||||
|
-- (7) 3 total facility tanks (A B C C)
|
||||||
|
local first_fdef = calc_fdef(3, #tank_defs)
|
||||||
|
for i = 1, #tank_defs do
|
||||||
|
if (not (i == 1 or i == 2)) and (i > first_fdef) and (tank_defs[i] == 2) then
|
||||||
|
tank_list[i] = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
io.facility.tank_list = tank_list
|
||||||
|
end
|
||||||
|
|
||||||
|
-- create facility tank tables
|
||||||
|
for i = 1, #io.facility.tank_list do
|
||||||
|
if io.facility.tank_list[i] == 2 then
|
||||||
|
table.insert(io.facility.tank_ps_tbl, psil.create())
|
||||||
|
table.insert(io.facility.tank_data_tbl, {})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- create unit data structures
|
||||||
|
io.units = {}
|
||||||
|
for i = 1, conf.num_units do
|
||||||
|
---@class pioctl_unit
|
||||||
|
local entry = {
|
||||||
|
unit_id = i,
|
||||||
|
|
||||||
|
num_boilers = 0,
|
||||||
|
num_turbines = 0,
|
||||||
|
num_snas = 0,
|
||||||
|
has_tank = conf.cooling.r_cool[i].TankConnection,
|
||||||
|
|
||||||
|
control_state = false,
|
||||||
|
burn_rate_cmd = 0.0,
|
||||||
|
radiation = types.new_zero_radiation_reading(),
|
||||||
|
|
||||||
|
sna_peak_rate = 0.0,
|
||||||
|
sna_max_rate = 0.0,
|
||||||
|
sna_out_rate = 0.0,
|
||||||
|
|
||||||
|
waste_mode = types.WASTE_MODE.MANUAL_PLUTONIUM,
|
||||||
|
waste_product = types.WASTE_PRODUCT.PLUTONIUM,
|
||||||
|
|
||||||
|
-- auto control group
|
||||||
|
a_group = 0,
|
||||||
|
|
||||||
|
---@type alarms
|
||||||
|
alarms = { ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE },
|
||||||
|
|
||||||
|
annunciator = {}, ---@type annunciator
|
||||||
|
|
||||||
|
unit_ps = psil.create(),
|
||||||
|
reactor_data = {}, ---@type reactor_db
|
||||||
|
|
||||||
|
boiler_ps_tbl = {},
|
||||||
|
boiler_data_tbl = {},
|
||||||
|
|
||||||
|
turbine_ps_tbl = {},
|
||||||
|
turbine_data_tbl = {},
|
||||||
|
|
||||||
|
tank_ps_tbl = {},
|
||||||
|
tank_data_tbl = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
-- on other facility modes, overwrite unit TANK option with facility tank defs
|
||||||
|
if io.facility.tank_mode ~= 0 then
|
||||||
|
entry.has_tank = conf.cooling.fac_tank_defs[i] > 0
|
||||||
|
end
|
||||||
|
|
||||||
|
-- create boiler tables
|
||||||
|
for _ = 1, conf.cooling.r_cool[i].BoilerCount do
|
||||||
|
table.insert(entry.boiler_ps_tbl, psil.create())
|
||||||
|
table.insert(entry.boiler_data_tbl, {})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- create turbine tables
|
||||||
|
for _ = 1, conf.cooling.r_cool[i].TurbineCount do
|
||||||
|
table.insert(entry.turbine_ps_tbl, psil.create())
|
||||||
|
table.insert(entry.turbine_data_tbl, {})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- create tank tables
|
||||||
|
if io.facility.tank_defs[i] == 1 then
|
||||||
|
table.insert(entry.tank_ps_tbl, psil.create())
|
||||||
|
table.insert(entry.tank_data_tbl, {})
|
||||||
|
end
|
||||||
|
|
||||||
|
entry.num_boilers = #entry.boiler_data_tbl
|
||||||
|
entry.num_turbines = #entry.turbine_data_tbl
|
||||||
|
|
||||||
|
table.insert(io.units, entry)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- set network link state
|
-- set network link state
|
||||||
|
@ -19,6 +19,8 @@ local function create_pages(root)
|
|||||||
db.nav.register_app(iocontrol.APP_ID.DUMMY, main).new_page(nil, function () end)
|
db.nav.register_app(iocontrol.APP_ID.DUMMY, main).new_page(nil, function () end)
|
||||||
|
|
||||||
TextBox{parent=main,text="This app is not implemented yet.",x=1,y=2,alignment=core.ALIGN.CENTER}
|
TextBox{parent=main,text="This app is not implemented yet.",x=1,y=2,alignment=core.ALIGN.CENTER}
|
||||||
|
|
||||||
|
TextBox{parent=main,text=" pretend something cool is here \x03",x=1,y=10,alignment=core.ALIGN.CENTER,fg_bg=core.cpair(colors.gray,colors.black)}
|
||||||
end
|
end
|
||||||
|
|
||||||
return create_pages
|
return create_pages
|
||||||
|
@ -71,10 +71,6 @@ local function init(main)
|
|||||||
|
|
||||||
local page_div = Div{parent=main_pane,x=4,y=1}
|
local page_div = Div{parent=main_pane,x=4,y=1}
|
||||||
|
|
||||||
local sidebar_tabs = {
|
|
||||||
{ char = "#", color = cpair(colors.black, colors.green) }
|
|
||||||
}
|
|
||||||
|
|
||||||
home_page(page_div)
|
home_page(page_div)
|
||||||
unit_page(page_div)
|
unit_page(page_div)
|
||||||
|
|
||||||
@ -84,13 +80,13 @@ local function init(main)
|
|||||||
|
|
||||||
assert(#db.nav.get_containers() == iocontrol.APP_ID.NUM_APPS, "app IDs were not sequential or some apps weren't registered")
|
assert(#db.nav.get_containers() == iocontrol.APP_ID.NUM_APPS, "app IDs were not sequential or some apps weren't registered")
|
||||||
|
|
||||||
local page_pane = MultiPane{parent=page_div,x=1,y=1,panes=db.nav.get_containers()}
|
db.nav.set_pane(MultiPane{parent=page_div,x=1,y=1,panes=db.nav.get_containers()})
|
||||||
db.nav.set_pane(page_pane)
|
db.nav.set_sidebar(Sidebar{parent=main_pane,x=1,y=1,height=18,fg_bg=cpair(colors.white,colors.gray)})
|
||||||
|
|
||||||
Sidebar{parent=main_pane,x=1,y=1,tabs=sidebar_tabs,fg_bg=cpair(colors.white,colors.gray),callback=db.nav.open_app}
|
|
||||||
|
|
||||||
PushButton{parent=main_pane,x=1,y=19,text="\x1b",min_width=3,fg_bg=cpair(colors.white,colors.gray),active_fg_bg=cpair(colors.gray,colors.black),callback=db.nav.nav_up}
|
PushButton{parent=main_pane,x=1,y=19,text="\x1b",min_width=3,fg_bg=cpair(colors.white,colors.gray),active_fg_bg=cpair(colors.gray,colors.black),callback=db.nav.nav_up}
|
||||||
|
|
||||||
|
db.nav.open_app(iocontrol.APP_ID.ROOT)
|
||||||
|
|
||||||
--#endregion
|
--#endregion
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -39,21 +39,26 @@ local function new_view(root)
|
|||||||
|
|
||||||
local function open(id) db.nav.open_app(id) end
|
local function open(id) db.nav.open_app(id) end
|
||||||
|
|
||||||
|
app.set_sidebar({
|
||||||
|
{ label = " #\x10", tall = true, color = core.cpair(colors.black, colors.green), callback = function () open(APP_ID.ROOT) end }
|
||||||
|
})
|
||||||
|
|
||||||
local active_fg_bg = cpair(colors.white,colors.gray)
|
local active_fg_bg = cpair(colors.white,colors.gray)
|
||||||
|
|
||||||
App{parent=apps_1,x=3,y=2,text="U",title="Units",callback=function()open(APP_ID.UNITS)end,app_fg_bg=cpair(colors.black,colors.yellow),active_fg_bg=active_fg_bg}
|
App{parent=apps_1,x=2,y=2,text="U",title="Units",callback=function()open(APP_ID.UNITS)end,app_fg_bg=cpair(colors.black,colors.yellow),active_fg_bg=active_fg_bg}
|
||||||
App{parent=apps_1,x=10,y=2,text="\x17",title="PRC",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.purple),active_fg_bg=active_fg_bg}
|
App{parent=apps_1,x=9,y=2,text="F",title="Facil",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.orange),active_fg_bg=active_fg_bg}
|
||||||
App{parent=apps_1,x=17,y=2,text="\x15",title="CTL",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.green),active_fg_bg=active_fg_bg}
|
App{parent=apps_1,x=16,y=2,text="\x15",title="Control",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.green),active_fg_bg=active_fg_bg}
|
||||||
App{parent=apps_1,x=3,y=7,text="\x08",title="DEV",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.lightGray),active_fg_bg=active_fg_bg}
|
App{parent=apps_1,x=2,y=7,text="\x17",title="Process",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.purple),active_fg_bg=active_fg_bg}
|
||||||
App{parent=apps_1,x=10,y=7,text="\x7f",title="Waste",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.brown),active_fg_bg=active_fg_bg}
|
App{parent=apps_1,x=9,y=7,text="\x7f",title="Waste",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.brown),active_fg_bg=active_fg_bg}
|
||||||
App{parent=apps_1,x=17,y=7,text="\xb6",title="Guide",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.cyan),active_fg_bg=active_fg_bg}
|
App{parent=apps_1,x=16,y=7,text="\x08",title="Devices",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.lightGray),active_fg_bg=active_fg_bg}
|
||||||
App{parent=apps_1,x=3,y=12,text="?",title="About",callback=function()open(APP_ID.ABOUT)end,app_fg_bg=cpair(colors.black,colors.white),active_fg_bg=active_fg_bg}
|
App{parent=apps_1,x=2,y=12,text="\xb6",title="Guide",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.cyan),active_fg_bg=active_fg_bg}
|
||||||
|
App{parent=apps_1,x=9,y=12,text="?",title="About",callback=function()open(APP_ID.ABOUT)end,app_fg_bg=cpair(colors.black,colors.white),active_fg_bg=active_fg_bg}
|
||||||
|
|
||||||
TextBox{parent=apps_2,text="Diagnostic Apps",x=1,y=2,height=1,alignment=ALIGN.CENTER}
|
TextBox{parent=apps_2,text="Diagnostic Apps",x=1,y=2,height=1,alignment=ALIGN.CENTER}
|
||||||
|
|
||||||
App{parent=apps_2,x=3,y=4,text="\x0f",title="Alarm",callback=function()open(APP_ID.ALARMS)end,app_fg_bg=cpair(colors.black,colors.red),active_fg_bg=active_fg_bg}
|
App{parent=apps_2,x=2,y=4,text="\x0f",title="Alarm",callback=function()open(APP_ID.ALARMS)end,app_fg_bg=cpair(colors.black,colors.red),active_fg_bg=active_fg_bg}
|
||||||
App{parent=apps_2,x=10,y=4,text="\x1e",title="LoopT",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.cyan),active_fg_bg=active_fg_bg}
|
App{parent=apps_2,x=9,y=4,text="\x1e",title="LoopT",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.cyan),active_fg_bg=active_fg_bg}
|
||||||
App{parent=apps_2,x=17,y=4,text="@",title="Comps",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.orange),active_fg_bg=active_fg_bg}
|
App{parent=apps_2,x=16,y=4,text="@",title="Comps",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.orange),active_fg_bg=active_fg_bg}
|
||||||
|
|
||||||
return main
|
return main
|
||||||
end
|
end
|
||||||
|
@ -3,13 +3,31 @@
|
|||||||
--
|
--
|
||||||
|
|
||||||
local iocontrol = require("pocket.iocontrol")
|
local iocontrol = require("pocket.iocontrol")
|
||||||
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
local core = require("graphics.core")
|
local core = require("graphics.core")
|
||||||
|
|
||||||
local Div = require("graphics.elements.div")
|
local Div = require("graphics.elements.div")
|
||||||
|
local MultiPane = require("graphics.elements.multipane")
|
||||||
local TextBox = require("graphics.elements.textbox")
|
local TextBox = require("graphics.elements.textbox")
|
||||||
|
|
||||||
|
local AlarmLight = require("graphics.elements.indicators.alight")
|
||||||
|
local CoreMap = require("graphics.elements.indicators.coremap")
|
||||||
|
local DataIndicator = require("graphics.elements.indicators.data")
|
||||||
|
local IconIndicator = require("graphics.elements.indicators.icon")
|
||||||
|
local IndicatorLight = require("graphics.elements.indicators.light")
|
||||||
|
local RadIndicator = require("graphics.elements.indicators.rad")
|
||||||
|
local TriIndicatorLight = require("graphics.elements.indicators.trilight")
|
||||||
|
local VerticalBar = require("graphics.elements.indicators.vbar")
|
||||||
|
|
||||||
|
local HazardButton = require("graphics.elements.controls.hazard_button")
|
||||||
|
local MultiButton = require("graphics.elements.controls.multi_button")
|
||||||
|
local PushButton = require("graphics.elements.controls.push_button")
|
||||||
|
local RadioButton = require("graphics.elements.controls.radio_button")
|
||||||
|
local SpinboxNumeric = require("graphics.elements.controls.spinbox_numeric")
|
||||||
|
|
||||||
local ALIGN = core.ALIGN
|
local ALIGN = core.ALIGN
|
||||||
|
local cpair = core.cpair
|
||||||
|
|
||||||
-- new unit page view
|
-- new unit page view
|
||||||
---@param root graphics_element parent
|
---@param root graphics_element parent
|
||||||
@ -21,9 +39,112 @@ local function new_view(root)
|
|||||||
local app = db.nav.register_app(iocontrol.APP_ID.UNITS, main)
|
local app = db.nav.register_app(iocontrol.APP_ID.UNITS, main)
|
||||||
app.new_page(nil, function () end)
|
app.new_page(nil, function () end)
|
||||||
|
|
||||||
TextBox{parent=main,y=2,text="UNITS",height=1,alignment=ALIGN.CENTER}
|
TextBox{parent=main,y=2,text="Units App",height=1,alignment=ALIGN.CENTER}
|
||||||
|
|
||||||
TextBox{parent=main,y=4,text="work in progress",height=1,alignment=ALIGN.CENTER}
|
TextBox{parent=main,y=4,text="Loading...",height=1,alignment=ALIGN.CENTER}
|
||||||
|
|
||||||
|
local page_div = Div{parent=main,x=2,y=2,width=main.get_width()-2}
|
||||||
|
|
||||||
|
local btn_fg_bg = cpair(colors.yellow, colors.black)
|
||||||
|
local btn_active = cpair(colors.white, colors.black)
|
||||||
|
local label = cpair(colors.lightGray, colors.black)
|
||||||
|
|
||||||
|
local function set_sidebar(unit)
|
||||||
|
app.set_sidebar({
|
||||||
|
{ label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = function () db.nav.open_app(iocontrol.APP_ID.ROOT) end },
|
||||||
|
{ label = "U#" .. unit, color = core.cpair(colors.black, colors.yellow), callback = function () end },
|
||||||
|
{ label = "RPS", color = core.cpair(colors.black, colors.red), callback = function () end },
|
||||||
|
{ label = "RCS", color = core.cpair(colors.black, colors.blue), callback = function () end },
|
||||||
|
{ label = " R ", tall = true, color = core.cpair(colors.black, colors.orange), callback = function () end },
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
local function load()
|
||||||
|
local u_pages = {}
|
||||||
|
|
||||||
|
local active_unit = 1
|
||||||
|
set_sidebar(active_unit)
|
||||||
|
|
||||||
|
for _ = 1, db.facility.num_units do
|
||||||
|
local div = Div{parent=page_div}
|
||||||
|
table.insert(u_pages, div)
|
||||||
|
end
|
||||||
|
|
||||||
|
local u_pane = MultiPane{parent=page_div,x=1,y=1,panes=u_pages}
|
||||||
|
|
||||||
|
local function prev(x)
|
||||||
|
active_unit = util.trinary(x == 1, db.facility.num_units, x - 1)
|
||||||
|
u_pane.set_value(active_unit)
|
||||||
|
set_sidebar(active_unit)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function next(x)
|
||||||
|
active_unit = util.trinary(x == db.facility.num_units, 1, x + 1)
|
||||||
|
u_pane.set_value(active_unit)
|
||||||
|
set_sidebar(active_unit)
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1, db.facility.num_units do
|
||||||
|
local u_div = u_pages[i] ---@type graphics_element
|
||||||
|
local unit = db.units[i] ---@type pioctl_unit
|
||||||
|
|
||||||
|
TextBox{parent=u_div,y=1,text="Reactor Unit #"..i,height=1,alignment=ALIGN.CENTER}
|
||||||
|
PushButton{parent=u_div,x=1,y=1,text="<",fg_bg=btn_fg_bg,active_fg_bg=btn_active,callback=function()prev(i)end}
|
||||||
|
PushButton{parent=u_div,x=21,y=1,text=">",fg_bg=btn_fg_bg,active_fg_bg=btn_active,callback=function()next(i)end}
|
||||||
|
|
||||||
|
local type = util.trinary(unit.num_boilers > 0, "Sodium Cooled Reactor", "Boiling Water Reactor")
|
||||||
|
TextBox{parent=u_div,y=3,text=type,height=1,alignment=ALIGN.CENTER,fg_bg=cpair(colors.gray,colors.black)}
|
||||||
|
|
||||||
|
local lu_col = cpair(colors.lightGray, colors.lightGray)
|
||||||
|
local text_fg = cpair(colors.white, colors._INHERIT)
|
||||||
|
|
||||||
|
local rate = DataIndicator{parent=u_div,y=5,lu_colors=lu_col,label="Rate",unit="mB/t",format="%10.2f",value=0,commas=true,width=26,fg_bg=text_fg}
|
||||||
|
local temp = DataIndicator{parent=u_div,lu_colors=lu_col,label="Temp",unit="K",format="%10.2f",value=0,commas=true,width=26,fg_bg=text_fg}
|
||||||
|
|
||||||
|
local basic_states = {
|
||||||
|
{ color = cpair(colors.black,colors.lightGray), symbol = "\x07" },
|
||||||
|
{ color = cpair(colors.black,colors.red), symbol = "-" },
|
||||||
|
{ color = cpair(colors.black,colors.yellow), symbol = "\x1e" },
|
||||||
|
{ color = cpair(colors.black,colors.green), symbol = "+" }
|
||||||
|
}
|
||||||
|
|
||||||
|
local mode_states = {
|
||||||
|
{ color = cpair(colors.black,colors.lightGray), symbol = "\x07" },
|
||||||
|
{ color = cpair(colors.black,colors.red), symbol = "-" },
|
||||||
|
{ color = cpair(colors.black,colors.green), symbol = "+" },
|
||||||
|
{ color = cpair(colors.black,colors.purple), symbol = "A" }
|
||||||
|
}
|
||||||
|
|
||||||
|
local ctrl = IconIndicator{parent=u_div,x=1,y=8,label="Control State",states=mode_states}
|
||||||
|
|
||||||
|
ctrl.update(i+1)
|
||||||
|
|
||||||
|
u_div.line_break()
|
||||||
|
|
||||||
|
local rct = IconIndicator{parent=u_div,x=1,label="Fission Reactor",states=basic_states}
|
||||||
|
local rps = IconIndicator{parent=u_div,x=1,label="Protection System",states=basic_states}
|
||||||
|
|
||||||
|
u_div.line_break()
|
||||||
|
|
||||||
|
local rcs = IconIndicator{parent=u_div,x=1,label="Coolant System",states=basic_states}
|
||||||
|
|
||||||
|
for b = 1, unit.num_boilers do
|
||||||
|
local blr = IconIndicator{parent=u_div,x=1,label="Boiler "..b,states=basic_states}
|
||||||
|
blr.update(b+2)
|
||||||
|
end
|
||||||
|
|
||||||
|
for t = 1, unit.num_turbines do
|
||||||
|
local trb = IconIndicator{parent=u_div,x=1,label="Turbine "..t,states=basic_states}
|
||||||
|
trb.update(t)
|
||||||
|
end
|
||||||
|
|
||||||
|
rct.update(4)
|
||||||
|
rps.update(3)
|
||||||
|
rcs.update(3)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
app.set_on_load(load)
|
||||||
|
|
||||||
return main
|
return main
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user