diff --git a/pocket/pocket.lua b/pocket/pocket.lua index 432225e..c69b04d 100644 --- a/pocket/pocket.lua +++ b/pocket/pocket.lua @@ -89,13 +89,14 @@ local APP_ID = { UNITS = 3, CONTROL = 4, PROCESS = 5, - GUIDE = 6, - ABOUT = 7, + WASTE = 6, + GUIDE = 7, + ABOUT = 8, -- diagnostic app pages - ALARMS = 8, + ALARMS = 9, -- other - DUMMY = 9, - NUM_APPS = 9 + DUMMY = 10, + NUM_APPS = 10 } pocket.APP_ID = APP_ID diff --git a/pocket/ui/apps/waste.lua b/pocket/ui/apps/waste.lua new file mode 100644 index 0000000..e0e2f5a --- /dev/null +++ b/pocket/ui/apps/waste.lua @@ -0,0 +1,217 @@ +-- +-- Waste Control Page +-- + +local types = require("scada-common.types") +local util = require("scada-common.util") + +local iocontrol = require("pocket.iocontrol") +local pocket = require("pocket.pocket") +local process = require("pocket.process") + +local style = require("pocket.ui.style") + +local core = require("graphics.core") + +local Div = require("graphics.elements.Div") +local MultiPane = require("graphics.elements.MultiPane") +local Rectangle = require("graphics.elements.Rectangle") +local TextBox = require("graphics.elements.TextBox") + +local WaitingAnim = require("graphics.elements.animations.Waiting") + +local Checkbox = require("graphics.elements.controls.Checkbox") +local HazardButton = require("graphics.elements.controls.HazardButton") +local RadioButton = require("graphics.elements.controls.RadioButton") + +local NumberField = require("graphics.elements.form.NumberField") + +local IconIndicator = require("graphics.elements.indicators.IconIndicator") +local StateIndicator = require("graphics.elements.indicators.StateIndicator") + +local ALIGN = core.ALIGN +local cpair = core.cpair +local border = core.border + +local APP_ID = pocket.APP_ID + +local label_fg_bg = style.label +local text_fg = style.text_fg + +local field_fg_bg = style.field +local field_dis_fg_bg = style.field_disable + +local red_ind_s = style.icon_states.red_ind_s +local yel_ind_s = style.icon_states.yel_ind_s +local grn_ind_s = style.icon_states.grn_ind_s +local wht_ind_s = style.icon_states.wht_ind_s + +local hzd_fg_bg = style.hzd_fg_bg +local dis_colors = cpair(colors.white, colors.lightGray) + +-- new waste control page view +---@param root Container parent +local function new_view(root) + local db = iocontrol.get_db() + + local frame = Div{parent=root,x=1,y=1} + + local app = db.nav.register_app(APP_ID.WASTE, frame, nil, false, true) + + local load_div = Div{parent=frame,x=1,y=1} + local main = Div{parent=frame,x=1,y=1} + + TextBox{parent=load_div,y=12,text="Loading...",alignment=ALIGN.CENTER} + WaitingAnim{parent=load_div,x=math.floor(main.get_width()/2)-1,y=8,fg_bg=cpair(colors.brown,colors._INHERIT)} + + local load_pane = MultiPane{parent=main,x=1,y=1,panes={load_div,main}} + + app.set_sidebar({ { label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = db.nav.go_home } }) + + local page_div = nil ---@type Div|nil + + -- load the app (create the elements) + local function load() + local f_ps = db.facility.ps + + page_div = Div{parent=main,y=2,width=main.get_width()} + + local panes = {} ---@type Div[] + + -- create all page divs + for _ = 1, db.facility.num_units + 3 do + local div = Div{parent=page_div} + table.insert(panes, div) + end + + local last_update = 0 + -- refresh data callback, every 500ms it will re-send the query + local function update() + if util.time_ms() - last_update >= 500 then + -- db.api.get_waste() + last_update = util.time_ms() + end + end + + --#region unit settings/status + + for i = 1, db.facility.num_units do + local u_pane = panes[i] + local u_div = Div{parent=u_pane,x=2,width=main.get_width()-2} + local unit = db.units[i] + local u_ps = unit.unit_ps + + local u_page = app.new_page(nil, i) + u_page.tasks = { update } + + TextBox{parent=u_div,y=1,text="Reactor Unit #"..i,alignment=ALIGN.CENTER} + end + + --#endregion + + --#region waste options page + + local o_pane = panes[db.facility.num_units + 2] + local o_div = Div{parent=o_pane,x=2,width=main.get_width()-2} + + local opt_page = app.new_page(nil, db.facility.num_units + 2) + opt_page.tasks = { update } + + TextBox{parent=o_div,y=1,text="Waste Options",alignment=ALIGN.CENTER} + + local pu_fallback = Checkbox{parent=o_div,x=2,y=3,label="Pu Fallback",callback=function()end,box_fg_bg=cpair(colors.white,colors.gray)} + + TextBox{parent=o_div,x=2,y=5,height=3,text="Switch to Pu when SNAs cannot keep up with waste.",fg_bg=style.label} + + local lc_sps = Checkbox{parent=o_div,x=2,y=9,label="Low Charge SPS",callback=function()end,box_fg_bg=cpair(colors.white,colors.gray)} + + TextBox{parent=o_div,x=2,y=11,height=3,text="Use SPS at low charge, otherwise switches to Po.",fg_bg=style.label} + + pu_fallback.register(f_ps, "process_pu_fallback", pu_fallback.set_value) + lc_sps.register(f_ps, "process_sps_low_power", lc_sps.set_value) + + --#endregion + + --#region process control page + + local c_pane = panes[db.facility.num_units + 1] + local c_div = Div{parent=c_pane,x=2,width=main.get_width()-2} + + local wst_ctrl = app.new_page(nil, db.facility.num_units + 1) + wst_ctrl.tasks = { update } + + TextBox{parent=c_div,y=1,text="Waste Control",alignment=ALIGN.CENTER} + + local status = StateIndicator{parent=c_div,x=3,y=3,states=style.waste.states,value=1,min_width=17} + + status.register(f_ps, "current_waste_product", status.update) + + local waste_prod = RadioButton{parent=c_div,x=2,y=5,options=style.waste.options,callback=function()end,radio_colors=cpair(colors.white,colors.black),select_color=colors.brown} + + waste_prod.register(f_ps, "process_waste_product", waste_prod.set_value) + + local fb_active = IconIndicator{parent=c_div,x=2,y=9,label="Fallback Active",states=wht_ind_s} + local sps_disabled = IconIndicator{parent=c_div,x=2,y=10,label="SPS Disabled LC",states=yel_ind_s} + + fb_active.register(f_ps, "pu_fallback_active", fb_active.update) + sps_disabled.register(f_ps, "sps_disabled_low_power", sps_disabled.update) + + --#endregion + + --#region auto-SCRAM annunciator page + + local a_pane = panes[db.facility.num_units + 3] + local a_div = Div{parent=a_pane,x=2,width=main.get_width()-2} + + local annunc_page = app.new_page(nil, db.facility.num_units + 3) + annunc_page.tasks = { update } + + TextBox{parent=a_div,y=1,text="Automatic SCRAM",alignment=ALIGN.CENTER} + + --#endregion + + -- setup multipane + local u_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes} + app.set_root_pane(u_pane) + + -- setup sidebar + + local list = { + { label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = db.nav.go_home }, + { label = "WST", color = core.cpair(colors.black, colors.brown), callback = wst_ctrl.nav_to }, + { label = "OPT", color = core.cpair(colors.black, colors.white), callback = opt_page.nav_to }, + { label = "SPS", color = core.cpair(colors.black, colors.purple), callback = annunc_page.nav_to } + } + + for i = 1, db.facility.num_units do + table.insert(list, { label = "U-" .. i, color = core.cpair(colors.black, colors.lightGray), callback = function () app.switcher(i) end }) + end + + app.set_sidebar(list) + + -- done, show the app + wst_ctrl.nav_to() + load_pane.set_value(2) + end + + -- delete the elements and switch back to the loading screen + local function unload() + if page_div then + page_div.delete() + page_div = nil + end + + app.set_sidebar({ { label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = db.nav.go_home } }) + app.delete_pages() + + -- show loading screen + load_pane.set_value(1) + end + + app.set_load(load) + app.set_unload(unload) + + return main +end + +return new_view diff --git a/pocket/ui/main.lua b/pocket/ui/main.lua index 1596485..99b6ab3 100644 --- a/pocket/ui/main.lua +++ b/pocket/ui/main.lua @@ -15,6 +15,7 @@ local loader_app = require("pocket.ui.apps.loader") local process_app = require("pocket.ui.apps.process") local sys_apps = require("pocket.ui.apps.sys_apps") local unit_app = require("pocket.ui.apps.unit") +local waste_app = require("pocket.ui.apps.waste") local home_page = require("pocket.ui.pages.home_page") @@ -66,6 +67,7 @@ local function init(main) unit_app(page_div) control_app(page_div) process_app(page_div) + waste_app(page_div) guide_app(page_div) loader_app(page_div) sys_apps(page_div) diff --git a/pocket/ui/pages/home_page.lua b/pocket/ui/pages/home_page.lua index 1e478dc..345c9ce 100644 --- a/pocket/ui/pages/home_page.lua +++ b/pocket/ui/pages/home_page.lua @@ -49,7 +49,7 @@ local function new_view(root) 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=16,y=2,text="\x15",title="Control",callback=function()open(APP_ID.CONTROL)end,app_fg_bg=cpair(colors.black,colors.green),active_fg_bg=active_fg_bg} App{parent=apps_1,x=2,y=7,text="\x17",title="Process",callback=function()open(APP_ID.PROCESS)end,app_fg_bg=cpair(colors.black,colors.purple),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=9,y=7,text="\x7f",title="Waste",callback=function()open(APP_ID.WASTE)end,app_fg_bg=cpair(colors.black,colors.brown),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=2,y=12,text="\xb6",title="Guide",callback=function()open(APP_ID.GUIDE)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} diff --git a/pocket/ui/style.lua b/pocket/ui/style.lua index ff7fc9b..b8acfc2 100644 --- a/pocket/ui/style.lua +++ b/pocket/ui/style.lua @@ -214,4 +214,61 @@ style.imatrix = { } } +style.waste = { + -- auto waste processing states + states = { + { + color = cpair(colors.black, colors.green), + text = "PLUTONIUM" + }, + { + color = cpair(colors.black, colors.cyan), + text = "POLONIUM" + }, + { + color = cpair(colors.black, colors.purple), + text = "ANTI MATTER" + } + }, + states_abbrv = { + { + color = cpair(colors.black, colors.green), + text = "Pu" + }, + { + color = cpair(colors.black, colors.cyan), + text = "Po" + }, + { + color = cpair(colors.black, colors.purple), + text = "AM" + } + }, + -- process radio button options + options = { "Plutonium", "Polonium", "Antimatter" }, + -- unit waste selection + unit_opts = { + { + text = "Auto", + fg_bg = cpair(colors.black, colors.lightGray), + active_fg_bg = cpair(colors.white, colors.gray) + }, + { + text = "Pu", + fg_bg = cpair(colors.black, colors.lightGray), + active_fg_bg = cpair(colors.black, colors.green) + }, + { + text = "Po", + fg_bg = cpair(colors.black, colors.lightGray), + active_fg_bg = cpair(colors.black, colors.cyan) + }, + { + text = "AM", + fg_bg = cpair(colors.black, colors.lightGray), + active_fg_bg = cpair(colors.black, colors.purple) + } + } +} + return style