Compare commits
65 Commits
main
...
346-non-li
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f71fb91b8 | ||
|
|
1ae37f53c0 | ||
|
|
dcd04b36c2 | ||
|
|
e73a0a2d5b | ||
|
|
d35f43d575 | ||
|
|
3bf7f9cbd8 | ||
|
|
5e58d7482f | ||
|
|
83adad1ef6 | ||
|
|
7973d80486 | ||
|
|
6dcb6febdf | ||
|
|
5d90f879db | ||
|
|
522292d5df | ||
|
|
9b3842345c | ||
|
|
8bfd218fef | ||
|
|
2e423e641b | ||
|
|
ba1909e13f | ||
|
|
2abd212f28 | ||
|
|
308308d56f | ||
|
|
99239a135a | ||
|
|
1dbc89d4ce | ||
|
|
7ca0e9481d | ||
|
|
8781a063e6 | ||
|
|
50f830efa3 | ||
|
|
a5b134d446 | ||
|
|
0a6e33ac17 | ||
|
|
3e018aa412 | ||
|
|
b51a0d68e7 | ||
|
|
cdddb4d5c4 | ||
|
|
2f7a227ee8 | ||
|
|
36d40b7f3e | ||
|
|
b573c3cdbd | ||
|
|
3c5959caa9 | ||
|
|
3eefac4551 | ||
|
|
e84737f4fe | ||
|
|
a76afe9a5f | ||
|
|
69741bf228 | ||
|
|
1771cc5b08 | ||
|
|
d63b2d935b | ||
|
|
d6bd995c3a | ||
|
|
02c4f3d782 | ||
|
|
5f0019e803 | ||
|
|
15d7891b99 | ||
|
|
962807154d | ||
|
|
28e87fd8fa | ||
|
|
bc83a1b577 | ||
|
|
d408ca8748 | ||
|
|
ee29fbc4b6 | ||
|
|
f3dfcbd0cb | ||
|
|
b9b7b323dc | ||
|
|
fb5f339204 | ||
|
|
b39d52606c | ||
|
|
88975add1b | ||
|
|
30eb757889 | ||
|
|
dd11afe5cb | ||
|
|
18cadcf8ca | ||
|
|
dfda8b5d1a | ||
|
|
8929786315 | ||
|
|
1aafa8b574 | ||
|
|
6272473c95 | ||
|
|
311b8d19d1 | ||
|
|
d80c7a5826 | ||
|
|
25d31b8a0c | ||
|
|
6399301f9c | ||
|
|
d65750c282 | ||
|
|
d3d62fb924 |
@@ -8,7 +8,7 @@ local ppm = require("scada-common.ppm")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local coordinator = require("coordinator.coordinator")
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local ioctl = require("coordinator.ioctl")
|
||||
local sounder = require("coordinator.sounder")
|
||||
|
||||
local println = util.println
|
||||
@@ -84,7 +84,7 @@ function backplane.init_displays(config)
|
||||
|
||||
log.info("BKPLN: DISPLAY LINK_" .. util.trinary(disp, "UP", "DOWN") .. " MAIN/" .. iface)
|
||||
|
||||
iocontrol.fp_monitor_state("main", util.trinary(disp, 2, 1))
|
||||
ioctl.fp_monitor_state("main", util.trinary(disp, 2, 1))
|
||||
|
||||
if not disp then
|
||||
return false, "Main monitor is not connected."
|
||||
@@ -107,7 +107,7 @@ function backplane.init_displays(config)
|
||||
|
||||
log.info("BKPLN: DISPLAY LINK_" .. util.trinary(disp, "UP", "DOWN") .. " FLOW/" .. iface)
|
||||
|
||||
iocontrol.fp_monitor_state("flow", util.trinary(disp, 2, 1))
|
||||
ioctl.fp_monitor_state("flow", util.trinary(disp, 2, 1))
|
||||
|
||||
if not disp then
|
||||
return false, "Flow monitor is not connected."
|
||||
@@ -131,7 +131,7 @@ function backplane.init_displays(config)
|
||||
|
||||
log.info("BKPLN: DISPLAY LINK_" .. util.trinary(disp, "UP", "DOWN") .. " UNIT_" .. i .. "/" .. iface)
|
||||
|
||||
iocontrol.fp_monitor_state(i, util.trinary(disp, 2, 1))
|
||||
ioctl.fp_monitor_state(i, util.trinary(disp, 2, 1))
|
||||
|
||||
if not disp then
|
||||
return false, "Unit " .. i .. " monitor is not connected."
|
||||
@@ -176,7 +176,7 @@ function backplane.init(config, __shared_memory)
|
||||
wd_nic.closeAll()
|
||||
wd_nic.open(config.CRD_Channel)
|
||||
|
||||
iocontrol.fp_has_wd_modem(modem ~= nil)
|
||||
ioctl.fp_has_wd_modem(modem ~= nil)
|
||||
end
|
||||
|
||||
-- init wireless NIC(s)
|
||||
@@ -199,7 +199,7 @@ function backplane.init(config, __shared_memory)
|
||||
wl_nic.closeAll()
|
||||
wl_nic.open(config.CRD_Channel)
|
||||
|
||||
iocontrol.fp_has_wl_modem(modem ~= nil)
|
||||
ioctl.fp_has_wl_modem(modem ~= nil)
|
||||
end
|
||||
|
||||
-- at least one comms modem is required
|
||||
@@ -231,7 +231,7 @@ function backplane.init(config, __shared_memory)
|
||||
log_boot("tone generation took " .. (util.time_ms() - sounder_start) .. "ms")
|
||||
log_sys("annunciator alarm configured")
|
||||
|
||||
iocontrol.fp_has_speaker(true)
|
||||
ioctl.fp_has_speaker(true)
|
||||
end
|
||||
|
||||
return true
|
||||
@@ -252,8 +252,8 @@ function backplane.displays() return _bp.displays end
|
||||
|
||||
-- periodic backplane peripheral tasks
|
||||
function backplane.periodic()
|
||||
if _bp.wd_nic then iocontrol.fp_has_wd_net(_bp.wd_nic.periodic()) end
|
||||
if _bp.wl_nic then iocontrol.fp_has_wl_net(_bp.wl_nic.periodic()) end
|
||||
if _bp.wd_nic then ioctl.fp_has_wd_net(_bp.wd_nic.periodic()) end
|
||||
if _bp.wl_nic then ioctl.fp_has_wl_net(_bp.wl_nic.periodic()) end
|
||||
end
|
||||
|
||||
-- handle a backplane peripheral attach
|
||||
@@ -282,7 +282,7 @@ function backplane.attach(type, device, iface)
|
||||
log.info("BKPLN: WIRED PHY_UP " .. iface)
|
||||
log_sys("wired comms modem reconnected")
|
||||
|
||||
iocontrol.fp_has_wd_modem(true)
|
||||
ioctl.fp_has_wd_modem(true)
|
||||
|
||||
if (_bp.act_nic ~= wd_nic) and not _bp.wlan_pref then
|
||||
-- switch back to preferred wired
|
||||
@@ -299,7 +299,7 @@ function backplane.attach(type, device, iface)
|
||||
log.info("BKPLN: WIRELESS PHY_UP " .. iface)
|
||||
log_sys("wireless comms modem reconnected")
|
||||
|
||||
iocontrol.fp_has_wl_modem(true)
|
||||
ioctl.fp_has_wl_modem(true)
|
||||
|
||||
if (_bp.act_nic ~= wl_nic) and _bp.wlan_pref then
|
||||
-- switch back to preferred wireless
|
||||
@@ -333,14 +333,14 @@ function backplane.attach(type, device, iface)
|
||||
_bp.displays.main = device
|
||||
|
||||
log.info("BKPLN: main display reconnected")
|
||||
iocontrol.fp_monitor_state("main", 2)
|
||||
ioctl.fp_monitor_state("main", 2)
|
||||
elseif _bp.displays.flow_iface == iface then
|
||||
is_used = true
|
||||
|
||||
_bp.displays.flow = device
|
||||
|
||||
log.info("BKPLN: flow display reconnected")
|
||||
iocontrol.fp_monitor_state("flow", 2)
|
||||
ioctl.fp_monitor_state("flow", 2)
|
||||
else
|
||||
for idx, monitor in ipairs(_bp.displays.unit_ifaces) do
|
||||
if monitor == iface then
|
||||
@@ -349,7 +349,7 @@ function backplane.attach(type, device, iface)
|
||||
_bp.displays.unit_displays[idx] = device
|
||||
|
||||
log.info("BKPLN: unit " .. idx .. " display reconnected")
|
||||
iocontrol.fp_monitor_state(idx, 2)
|
||||
ioctl.fp_monitor_state(idx, 2)
|
||||
break
|
||||
end
|
||||
end
|
||||
@@ -371,7 +371,7 @@ function backplane.attach(type, device, iface)
|
||||
|
||||
log_sys("alarm sounder speaker reconnected")
|
||||
|
||||
iocontrol.fp_has_speaker(true)
|
||||
ioctl.fp_has_speaker(true)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -398,12 +398,12 @@ function backplane.detach(type, device, iface)
|
||||
wd_nic.disconnect()
|
||||
log.info("BKPLN: WIRED PHY_DOWN " .. iface)
|
||||
|
||||
iocontrol.fp_has_wd_modem(false)
|
||||
ioctl.fp_has_wd_modem(false)
|
||||
elseif wl_nic and wl_nic.is_modem(device) then
|
||||
wl_nic.disconnect()
|
||||
log.info("BKPLN: WIRELESS PHY_DOWN " .. iface)
|
||||
|
||||
iocontrol.fp_has_wl_modem(false)
|
||||
ioctl.fp_has_wl_modem(false)
|
||||
end
|
||||
|
||||
-- we only care if this is our active comms modem
|
||||
@@ -424,7 +424,7 @@ function backplane.detach(type, device, iface)
|
||||
|
||||
log.info("BKPLN: WIRELESS PHY_UP " .. m_iface)
|
||||
|
||||
iocontrol.fp_has_wl_modem(true)
|
||||
ioctl.fp_has_wl_modem(true)
|
||||
elseif wd_nic and wd_nic.is_connected() then
|
||||
_bp.act_nic = wd_nic
|
||||
|
||||
@@ -474,19 +474,19 @@ function backplane.detach(type, device, iface)
|
||||
is_used = true
|
||||
|
||||
log.info("BKPLN: main display disconnected")
|
||||
iocontrol.fp_monitor_state("main", 1)
|
||||
ioctl.fp_monitor_state("main", 1)
|
||||
elseif _bp.displays.flow == device then
|
||||
is_used = true
|
||||
|
||||
log.info("BKPLN: flow display disconnected")
|
||||
iocontrol.fp_monitor_state("flow", 1)
|
||||
ioctl.fp_monitor_state("flow", 1)
|
||||
else
|
||||
for idx, monitor in pairs(_bp.displays.unit_displays) do
|
||||
if monitor == device then
|
||||
is_used = true
|
||||
|
||||
log.info("BKPLN: unit " .. idx .. " display disconnected")
|
||||
iocontrol.fp_monitor_state(idx, 1)
|
||||
ioctl.fp_monitor_state(idx, 1)
|
||||
break
|
||||
end
|
||||
end
|
||||
@@ -506,7 +506,7 @@ function backplane.detach(type, device, iface)
|
||||
|
||||
log_sys("alarm sounder speaker disconnected")
|
||||
|
||||
iocontrol.fp_has_speaker(false)
|
||||
ioctl.fp_has_speaker(false)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -219,17 +219,17 @@ function facility.create(tool_ctl, main_pane, cfg_sys, fac_cfg, style)
|
||||
local fac_c_2 = Div{parent=fac_cfg,x=2,y=4,width=49}
|
||||
local fac_c_3 = Div{parent=fac_cfg,x=2,y=4,width=49}
|
||||
|
||||
local fac_pane = MultiPane{parent=fac_cfg,x=1,y=4,panes={fac_c_1,fac_c_2,fac_c_3}}
|
||||
local fac_pane = MultiPane{parent=fac_cfg,y=4,panes={fac_c_1,fac_c_2,fac_c_3}}
|
||||
|
||||
TextBox{parent=fac_cfg,x=1,y=2,text=" Facility Configuration",fg_bg=cpair(colors.black,colors.yellow)}
|
||||
TextBox{parent=fac_cfg,y=2,text=" Facility Configuration",fg_bg=cpair(colors.black,colors.yellow)}
|
||||
|
||||
TextBox{parent=fac_c_1,x=1,y=1,height=4,text="This tool can attempt to connect to your supervisor computer. This would load facility information in order to get the unit count and aid monitor setup."}
|
||||
TextBox{parent=fac_c_1,x=1,y=6,height=2,text="The supervisor startup app must be running and fully configured on your supervisor computer."}
|
||||
TextBox{parent=fac_c_1,y=1,height=4,text="This tool can attempt to connect to your supervisor computer. This would load facility information in order to get the unit count and aid monitor setup."}
|
||||
TextBox{parent=fac_c_1,y=6,height=2,text="The supervisor startup app must be running and fully configured on your supervisor computer."}
|
||||
|
||||
self.sv_conn_status = TextBox{parent=fac_c_1,x=11,y=9,text=""}
|
||||
self.sv_conn_detail = TextBox{parent=fac_c_1,x=1,y=11,height=2,text=""}
|
||||
self.sv_conn_detail = TextBox{parent=fac_c_1,y=11,height=2,text=""}
|
||||
|
||||
self.sv_conn_button = PushButton{parent=fac_c_1,x=1,y=9,text="Connect",min_width=9,callback=function()sv_connect(tmp_cfg)end,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
self.sv_conn_button = PushButton{parent=fac_c_1,y=9,text="Connect",min_width=9,callback=function()sv_connect(tmp_cfg)end,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
|
||||
local function sv_skip()
|
||||
tcd.abort(handle_timeout)
|
||||
@@ -244,15 +244,15 @@ function facility.create(tool_ctl, main_pane, cfg_sys, fac_cfg, style)
|
||||
fac_pane.set_value(3)
|
||||
end
|
||||
|
||||
PushButton{parent=fac_c_1,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_1,y=14,text="\x1b Back",callback=function()main_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
self.sv_skip = PushButton{parent=fac_c_1,x=44,y=14,text="Skip \x1a",callback=sv_skip,fg_bg=cpair(colors.black,colors.red),active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
self.sv_next = PushButton{parent=fac_c_1,x=44,y=14,text="Next \x1a",callback=sv_next,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg,hidden=true}
|
||||
|
||||
TextBox{parent=fac_c_2,x=1,y=1,height=3,text="Please enter the number of reactors you have, also referred to as reactor units or 'units' for short. A maximum of 4 is currently supported."}
|
||||
tool_ctl.num_units = NumberField{parent=fac_c_2,x=1,y=5,width=5,max_chars=2,default=ini_cfg.UnitCount,min=1,max=4,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=fac_c_2,y=1,height=3,text="Please enter the number of reactors you have, also referred to as reactor units or 'units' for short. A maximum of 4 is currently supported."}
|
||||
tool_ctl.num_units = NumberField{parent=fac_c_2,y=5,width=5,max_chars=2,default=ini_cfg.UnitCount,min=1,max=4,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=fac_c_2,x=7,y=5,text="reactors"}
|
||||
TextBox{parent=fac_c_2,x=1,y=7,height=3,text="This will decide how many monitors you need. If this does not match the supervisor's number of reactor units, the coordinator will not connect.",fg_bg=cpair(colors.yellow,colors._INHERIT)}
|
||||
TextBox{parent=fac_c_2,x=1,y=10,height=3,text="Since you skipped supervisor sync, the main monitor minimum height can't be determined precisely. It is marked with * on the next page.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=fac_c_2,y=7,height=3,text="This will decide how many monitors you need. If this does not match the supervisor's number of reactor units, the coordinator will not connect.",fg_bg=cpair(colors.yellow,colors._INHERIT)}
|
||||
TextBox{parent=fac_c_2,y=10,height=3,text="Since you skipped supervisor sync, the main monitor minimum height can't be determined precisely. It is marked with * on the next page.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local nu_error = TextBox{parent=fac_c_2,x=8,y=14,width=35,text="Please set the number of reactors.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
|
||||
@@ -266,14 +266,14 @@ function facility.create(tool_ctl, main_pane, cfg_sys, fac_cfg, style)
|
||||
else nu_error.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=fac_c_2,x=1,y=14,text="\x1b Back",callback=function()fac_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_2,y=14,text="\x1b Back",callback=function()fac_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_2,x=44,y=14,text="Next \x1a",callback=submit_num_units,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=fac_c_3,x=1,y=1,height=2,text="The following facility configuration was fetched from your supervisor computer."}
|
||||
TextBox{parent=fac_c_3,y=1,height=2,text="The following facility configuration was fetched from your supervisor computer."}
|
||||
|
||||
local fac_config_list = ListBox{parent=fac_c_3,x=1,y=4,height=9,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
local fac_config_list = ListBox{parent=fac_c_3,y=4,height=9,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
PushButton{parent=fac_c_3,x=1,y=14,text="\x1b Back",callback=function()fac_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_3,y=14,text="\x1b Back",callback=function()fac_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_3,x=44,y=14,text="Next \x1a",callback=function()main_pane.set_value(4)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
|
||||
@@ -52,12 +52,12 @@ function hmi.create(tool_ctl, main_pane, cfg_sys, divs, style)
|
||||
local mon_c_3 = Div{parent=mon_cfg,x=2,y=4,width=49}
|
||||
local mon_c_4 = Div{parent=mon_cfg,x=2,y=4,width=49}
|
||||
|
||||
local mon_pane = MultiPane{parent=mon_cfg,x=1,y=4,panes={mon_c_1,mon_c_2,mon_c_3,mon_c_4}}
|
||||
local mon_pane = MultiPane{parent=mon_cfg,y=4,panes={mon_c_1,mon_c_2,mon_c_3,mon_c_4}}
|
||||
|
||||
TextBox{parent=mon_cfg,x=1,y=2,text=" Monitor Configuration",fg_bg=cpair(colors.black,colors.blue)}
|
||||
TextBox{parent=mon_cfg,y=2,text=" Monitor Configuration",fg_bg=cpair(colors.black,colors.blue)}
|
||||
|
||||
TextBox{parent=mon_c_1,x=1,y=1,height=5,text="Your configuration requires the following monitors. The main and flow monitors' heights are dependent on your unit count and cooling setup. If you manually entered the unit count, a * will be shown on potentially inaccurate calculations."}
|
||||
local mon_reqs = ListBox{parent=mon_c_1,x=1,y=7,height=6,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
TextBox{parent=mon_c_1,y=1,height=5,text="Your configuration requires the following monitors. The main and flow monitors' heights are dependent on your unit count and cooling setup. If you manually entered the unit count, a * will be shown on potentially inaccurate calculations."}
|
||||
local mon_reqs = ListBox{parent=mon_c_1,y=7,height=6,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
local function next_from_reqs()
|
||||
-- unassign unit monitors above the unit count
|
||||
@@ -67,13 +67,13 @@ function hmi.create(tool_ctl, main_pane, cfg_sys, divs, style)
|
||||
mon_pane.set_value(2)
|
||||
end
|
||||
|
||||
PushButton{parent=mon_c_1,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=mon_c_1,y=14,text="\x1b Back",callback=function()main_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=mon_c_1,x=8,y=14,text="Legacy Options",min_width=16,callback=function()mon_pane.set_value(4)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=mon_c_1,x=44,y=14,text="Next \x1a",callback=next_from_reqs,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=mon_c_2,x=1,y=1,height=5,text="Please configure your monitors below. You can go back to the prior page without losing progress to double check what you need. All of those monitors must be assigned before you can proceed."}
|
||||
TextBox{parent=mon_c_2,y=1,height=5,text="Please configure your monitors below. You can go back to the prior page without losing progress to double check what you need. All of those monitors must be assigned before you can proceed."}
|
||||
|
||||
local mon_list = ListBox{parent=mon_c_2,x=1,y=6,height=7,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
local mon_list = ListBox{parent=mon_c_2,y=6,height=7,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
local assign_err = TextBox{parent=mon_c_2,x=8,y=14,width=35,text="",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
|
||||
@@ -98,14 +98,14 @@ function hmi.create(tool_ctl, main_pane, cfg_sys, divs, style)
|
||||
assign_err.show()
|
||||
end
|
||||
|
||||
PushButton{parent=mon_c_2,x=1,y=14,text="\x1b Back",callback=function()mon_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=mon_c_2,y=14,text="\x1b Back",callback=function()mon_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=mon_c_2,x=44,y=14,text="Next \x1a",callback=submit_monitors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
local mon_desc = TextBox{parent=mon_c_3,x=1,y=1,height=4,text=""}
|
||||
local mon_desc = TextBox{parent=mon_c_3,y=1,height=4,text=""}
|
||||
|
||||
local mon_unit_l, mon_unit = nil, nil ---@type TextBox, NumberField
|
||||
|
||||
local mon_warn = TextBox{parent=mon_c_3,x=1,y=11,height=2,text="",fg_bg=cpair(colors.red,colors.lightGray)}
|
||||
local mon_warn = TextBox{parent=mon_c_3,y=11,height=2,text="",fg_bg=cpair(colors.red,colors.lightGray)}
|
||||
|
||||
---@param val integer assignment type
|
||||
local function on_assign_mon(val)
|
||||
@@ -135,8 +135,8 @@ function hmi.create(tool_ctl, main_pane, cfg_sys, divs, style)
|
||||
if value == "0" or value == nil then mon_unit.set_value(0) end
|
||||
end
|
||||
|
||||
TextBox{parent=mon_c_3,x=1,y=6,width=10,text="Assignment"}
|
||||
local mon_assign = RadioButton{parent=mon_c_3,x=1,y=7,default=1,options={"Main Monitor","Flow Monitor","Unit Monitor"},callback=on_assign_mon,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.blue}
|
||||
TextBox{parent=mon_c_3,y=6,width=10,text="Assignment"}
|
||||
local mon_assign = RadioButton{parent=mon_c_3,y=7,default=1,options={"Main Monitor","Flow Monitor","Unit Monitor"},callback=on_assign_mon,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.blue}
|
||||
|
||||
mon_unit_l = TextBox{parent=mon_c_3,x=18,y=6,width=7,text="Unit ID"}
|
||||
mon_unit = NumberField{parent=mon_c_3,x=18,y=7,width=10,max_chars=2,min=1,max=4,fg_bg=bw_fg_bg}
|
||||
@@ -181,13 +181,13 @@ function hmi.create(tool_ctl, main_pane, cfg_sys, divs, style)
|
||||
mon_pane.set_value(2)
|
||||
end
|
||||
|
||||
PushButton{parent=mon_c_3,x=1,y=14,text="\x1b Back",callback=function()mon_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=mon_c_3,y=14,text="\x1b Back",callback=function()mon_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
self.apply_mon = PushButton{parent=mon_c_3,x=43,y=14,min_width=7,text="Apply",callback=apply_monitor,fg_bg=cpair(colors.black,colors.blue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
|
||||
TextBox{parent=mon_c_4,x=1,y=1,height=3,text="For legacy compatibility with facilities built without space for a flow monitor, you can disable the flow monitor requirement here."}
|
||||
TextBox{parent=mon_c_4,x=1,y=5,height=3,text="Please be aware that THIS OPTION WILL BE REMOVED ON RELEASE. Disabling it will only be available for the remainder of the beta."}
|
||||
TextBox{parent=mon_c_4,y=1,height=3,text="For legacy compatibility with facilities built without space for a flow monitor, you can disable the flow monitor requirement here."}
|
||||
TextBox{parent=mon_c_4,y=5,height=3,text="Please be aware that THIS OPTION WILL BE REMOVED ON RELEASE. Disabling it will only be available for the remainder of the beta."}
|
||||
|
||||
tool_ctl.dis_flow_view = Checkbox{parent=mon_c_4,x=1,y=9,default=ini_cfg.DisableFlowView,label="Disable Flow View Monitor",box_fg_bg=cpair(colors.blue,colors.black)}
|
||||
tool_ctl.dis_flow_view = Checkbox{parent=mon_c_4,y=9,default=ini_cfg.DisableFlowView,label="Disable Flow View Monitor",box_fg_bg=cpair(colors.blue,colors.black)}
|
||||
|
||||
local function back_from_legacy()
|
||||
tmp_cfg.DisableFlowView = tool_ctl.dis_flow_view.get_value()
|
||||
@@ -203,14 +203,14 @@ function hmi.create(tool_ctl, main_pane, cfg_sys, divs, style)
|
||||
|
||||
local spkr_c = Div{parent=spkr_cfg,x=2,y=4,width=49}
|
||||
|
||||
TextBox{parent=spkr_cfg,x=1,y=2,text=" Speaker Configuration",fg_bg=cpair(colors.black,colors.cyan)}
|
||||
TextBox{parent=spkr_cfg,y=2,text=" Speaker Configuration",fg_bg=cpair(colors.black,colors.cyan)}
|
||||
|
||||
TextBox{parent=spkr_c,x=1,y=1,height=2,text="The coordinator uses a speaker to play alarm sounds."}
|
||||
TextBox{parent=spkr_c,x=1,y=4,height=3,text="You can change the speaker audio volume from the default. The range is 0.0 to 3.0, where 1.0 is standard volume."}
|
||||
TextBox{parent=spkr_c,y=1,height=2,text="The coordinator uses a speaker to play alarm sounds."}
|
||||
TextBox{parent=spkr_c,y=4,height=3,text="You can change the speaker audio volume from the default. The range is 0.0 to 3.0, where 1.0 is standard volume."}
|
||||
|
||||
tool_ctl.s_vol = NumberField{parent=spkr_c,x=1,y=8,width=9,max_chars=7,allow_decimal=true,default=ini_cfg.SpeakerVolume,min=0,max=3,fg_bg=bw_fg_bg}
|
||||
tool_ctl.s_vol = NumberField{parent=spkr_c,y=8,width=9,max_chars=7,allow_decimal=true,default=ini_cfg.SpeakerVolume,min=0,max=3,fg_bg=bw_fg_bg}
|
||||
|
||||
TextBox{parent=spkr_c,x=1,y=10,height=3,text="Note: alarm sine waves are at half scale so that multiple will be required to reach full scale.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=spkr_c,y=10,height=3,text="Note: alarm sine waves are at half scale so that multiple will be required to reach full scale.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local s_vol_err = TextBox{parent=spkr_c,x=8,y=14,width=35,text="Please set a volume.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
|
||||
@@ -223,7 +223,7 @@ function hmi.create(tool_ctl, main_pane, cfg_sys, divs, style)
|
||||
else s_vol_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=spkr_c,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(4)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=spkr_c,y=14,text="\x1b Back",callback=function()main_pane.set_value(4)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=spkr_c,x=44,y=14,text="Next \x1a",callback=submit_vol,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -232,18 +232,18 @@ function hmi.create(tool_ctl, main_pane, cfg_sys, divs, style)
|
||||
|
||||
local crd_c_1 = Div{parent=crd_cfg,x=2,y=4,width=49}
|
||||
|
||||
TextBox{parent=crd_cfg,x=1,y=2,text=" Coordinator UI Configuration",fg_bg=cpair(colors.black,colors.lime)}
|
||||
TextBox{parent=crd_cfg,y=2,text=" Coordinator UI Configuration",fg_bg=cpair(colors.black,colors.lime)}
|
||||
|
||||
TextBox{parent=crd_c_1,x=1,y=1,height=2,text="You can customize the UI with the interface options below."}
|
||||
TextBox{parent=crd_c_1,y=1,height=2,text="You can customize the UI with the interface options below."}
|
||||
|
||||
TextBox{parent=crd_c_1,x=1,y=4,text="Clock Time Format"}
|
||||
tool_ctl.clock_fmt = RadioButton{parent=crd_c_1,x=1,y=5,default=util.trinary(ini_cfg.Time24Hour,1,2),options={"24-Hour","12-Hour"},radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.lime}
|
||||
TextBox{parent=crd_c_1,y=4,text="Clock Time Format"}
|
||||
tool_ctl.clock_fmt = RadioButton{parent=crd_c_1,y=5,default=util.trinary(ini_cfg.Time24Hour,1,2),options={"24-Hour","12-Hour"},radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.lime}
|
||||
|
||||
TextBox{parent=crd_c_1,x=20,y=4,text="Po/Pu Pellet Color"}
|
||||
tool_ctl.pellet_color = RadioButton{parent=crd_c_1,x=20,y=5,default=util.trinary(ini_cfg.GreenPuPellet,1,2),options={"Green Pu/Cyan Po","Cyan Pu/Green Po (Mek 10.4+)"},radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.lime}
|
||||
|
||||
TextBox{parent=crd_c_1,x=1,y=8,text="Temperature Scale"}
|
||||
tool_ctl.temp_scale = RadioButton{parent=crd_c_1,x=1,y=9,default=ini_cfg.TempScale,options=types.TEMP_SCALE_NAMES,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.lime}
|
||||
TextBox{parent=crd_c_1,y=8,text="Temperature Scale"}
|
||||
tool_ctl.temp_scale = RadioButton{parent=crd_c_1,y=9,default=ini_cfg.TempScale,options=types.TEMP_SCALE_NAMES,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.lime}
|
||||
|
||||
TextBox{parent=crd_c_1,x=20,y=8,text="Energy Scale"}
|
||||
tool_ctl.energy_scale = RadioButton{parent=crd_c_1,x=20,y=9,default=ini_cfg.EnergyScale,options=types.ENERGY_SCALE_NAMES,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.lime}
|
||||
@@ -256,7 +256,7 @@ function hmi.create(tool_ctl, main_pane, cfg_sys, divs, style)
|
||||
main_pane.set_value(7)
|
||||
end
|
||||
|
||||
PushButton{parent=crd_c_1,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(5)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=crd_c_1,y=14,text="\x1b Back",callback=function()main_pane.set_value(5)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=crd_c_1,x=44,y=14,text="Next \x1a",callback=submit_ui_opts,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -295,13 +295,13 @@ function hmi.create(tool_ctl, main_pane, cfg_sys, divs, style)
|
||||
|
||||
mon_reqs.remove_all()
|
||||
|
||||
TextBox{parent=mon_reqs,x=1,y=1,text="\x1a "..tmp_cfg.UnitCount.." Unit View Monitor"..util.trinary(plural,"s","")}
|
||||
TextBox{parent=mon_reqs,x=1,y=1,text=" "..util.trinary(plural,"each ","").."must be 4 blocks wide by 4 tall",fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=mon_reqs,x=1,y=1,text="\x1a 1 Main View Monitor"}
|
||||
TextBox{parent=mon_reqs,x=1,y=1,text=" must be 8 blocks wide by "..m_at_least..tool_ctl.main_mon_h..asterisk.." tall",fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=mon_reqs,y=1,text="\x1a "..tmp_cfg.UnitCount.." Unit View Monitor"..util.trinary(plural,"s","")}
|
||||
TextBox{parent=mon_reqs,y=1,text=" "..util.trinary(plural,"each ","").."must be 4 blocks wide by 4 tall",fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=mon_reqs,y=1,text="\x1a 1 Main View Monitor"}
|
||||
TextBox{parent=mon_reqs,y=1,text=" must be 8 blocks wide by "..m_at_least..tool_ctl.main_mon_h..asterisk.." tall",fg_bg=cpair(colors.gray,colors.white)}
|
||||
if not tmp_cfg.DisableFlowView then
|
||||
TextBox{parent=mon_reqs,x=1,y=1,text="\x1a 1 Flow View Monitor"}
|
||||
TextBox{parent=mon_reqs,x=1,y=1,text=" must be 8 blocks wide by "..f_at_least..tool_ctl.flow_mon_h.." tall",fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=mon_reqs,y=1,text="\x1a 1 Flow View Monitor"}
|
||||
TextBox{parent=mon_reqs,y=1,text=" must be 8 blocks wide by "..f_at_least..tool_ctl.flow_mon_h.." tall",fg_bg=cpair(colors.gray,colors.white)}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -401,9 +401,9 @@ function hmi.create(tool_ctl, main_pane, cfg_sys, divs, style)
|
||||
end
|
||||
end
|
||||
|
||||
local line = Div{parent=mon_list,x=1,y=1,height=1}
|
||||
local line = Div{parent=mon_list,y=1,height=1}
|
||||
|
||||
TextBox{parent=line,x=1,y=1,width=6,text=assignment,fg_bg=cpair(util.trinary(assignment=="Unused",colors.red,colors.blue),colors.white)}
|
||||
TextBox{parent=line,y=1,width=6,text=assignment,fg_bg=cpair(util.trinary(assignment=="Unused",colors.red,colors.blue),colors.white)}
|
||||
TextBox{parent=line,x=8,y=1,text=iface}
|
||||
|
||||
local w, h = ppm.monitor_block_size(dev.getSize())
|
||||
@@ -430,9 +430,9 @@ function hmi.create(tool_ctl, main_pane, cfg_sys, divs, style)
|
||||
|
||||
-- add monitors that are assigned but not connected
|
||||
for i = 1, #dc_list do
|
||||
local line = Div{parent=mon_list,x=1,y=1,height=1}
|
||||
local line = Div{parent=mon_list,y=1,height=1}
|
||||
|
||||
TextBox{parent=line,x=1,y=1,width=6,text=dc_list[i][1],fg_bg=cpair(colors.blue,colors.white)}
|
||||
TextBox{parent=line,y=1,width=6,text=dc_list[i][1],fg_bg=cpair(colors.blue,colors.white)}
|
||||
TextBox{parent=line,x=8,y=1,text="disconnected",fg_bg=cpair(colors.red,colors.white)}
|
||||
|
||||
local function unset_mon()
|
||||
|
||||
@@ -70,21 +70,21 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
local net_c_5 = Div{parent=net_cfg,x=2,y=4,width=49}
|
||||
local net_c_6 = Div{parent=net_cfg,x=2,y=4,width=49}
|
||||
|
||||
local net_pane = MultiPane{parent=net_cfg,x=1,y=4,panes={net_c_1,net_c_2,net_c_3,net_c_4,net_c_5,net_c_6}}
|
||||
local net_pane = MultiPane{parent=net_cfg,y=4,panes={net_c_1,net_c_2,net_c_3,net_c_4,net_c_5,net_c_6}}
|
||||
|
||||
TextBox{parent=net_cfg,x=1,y=2,text=" Network Configuration",fg_bg=cpair(colors.black,colors.lightBlue)}
|
||||
TextBox{parent=net_cfg,y=2,text=" Network Configuration",fg_bg=cpair(colors.black,colors.lightBlue)}
|
||||
|
||||
TextBox{parent=net_c_1,x=1,y=1,text="Please select the network interface(s)."}
|
||||
TextBox{parent=net_c_1,y=1,text="Please select the network interface(s)."}
|
||||
TextBox{parent=net_c_1,x=41,y=1,text="new!",fg_bg=cpair(colors.red,colors._INHERIT)} ---@todo remove NEW tag on next revision
|
||||
|
||||
local function on_wired_change(_) tool_ctl.gen_modem_list() end
|
||||
|
||||
local wireless = Checkbox{parent=net_c_1,x=1,y=3,label="Wireless/Ender Modem",default=ini_cfg.WirelessModem,box_fg_bg=cpair(colors.lightBlue,colors.black)}
|
||||
local wireless = Checkbox{parent=net_c_1,y=3,label="Wireless/Ender Modem",default=ini_cfg.WirelessModem,box_fg_bg=cpair(colors.lightBlue,colors.black)}
|
||||
TextBox{parent=net_c_1,x=24,y=3,text="(required for Pocket)",fg_bg=g_lg_fg_bg}
|
||||
local wired = Checkbox{parent=net_c_1,x=1,y=5,label="Wired Modem",default=ini_cfg.WiredModem~=false,box_fg_bg=cpair(colors.lightBlue,colors.black),callback=on_wired_change}
|
||||
local wired = Checkbox{parent=net_c_1,y=5,label="Wired Modem",default=ini_cfg.WiredModem~=false,box_fg_bg=cpair(colors.lightBlue,colors.black),callback=on_wired_change}
|
||||
TextBox{parent=net_c_1,x=3,y=6,text="this one MUST ONLY connect to SCADA computers",fg_bg=cpair(colors.red,colors._INHERIT)}
|
||||
TextBox{parent=net_c_1,x=3,y=7,text="connecting it to peripherals will cause issues",fg_bg=g_lg_fg_bg}
|
||||
local modem_list = ListBox{parent=net_c_1,x=1,y=8,height=5,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
local modem_list = ListBox{parent=net_c_1,y=8,height=5,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
local modem_err = TextBox{parent=net_c_1,x=8,y=14,width=35,text="",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
|
||||
@@ -122,7 +122,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_1,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_1,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_1,x=44,y=14,text="Next \x1a",callback=submit_interfaces,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_2,text="If you selected multiple interfaces, please specify if this device should prefer wireless or otherwise wired. The preferred interface is switched too when reconnected even if failover has succeeded onto the fallback interface."}
|
||||
@@ -153,21 +153,21 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
net_pane.set_value(3)
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_2,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_2,y=14,text="\x1b Back",callback=function()net_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_2,x=44,y=14,text="Next \x1a",callback=submit_net_cfg_opts,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_3,x=1,y=1,text="Please set the network channels below."}
|
||||
TextBox{parent=net_c_3,x=1,y=3,height=4,text="Each of the 5 uniquely named channels, including the 3 below, must be the same for each device in this SCADA network. For multiplayer servers, it is recommended to not use the default channels.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_3,y=1,text="Please set the network channels below."}
|
||||
TextBox{parent=net_c_3,y=3,height=4,text="Each of the 5 uniquely named channels, including the 3 below, must be the same for each device in this SCADA network. For multiplayer servers, it is recommended to not use the default channels.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_3,x=1,y=8,width=18,text="Supervisor Channel"}
|
||||
TextBox{parent=net_c_3,y=8,width=18,text="Supervisor Channel"}
|
||||
local svr_chan = NumberField{parent=net_c_3,x=21,y=8,width=7,default=ini_cfg.SVR_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_3,x=29,y=8,height=4,text="[SVR_CHANNEL]",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_3,x=1,y=10,width=19,text="Coordinator Channel"}
|
||||
TextBox{parent=net_c_3,y=10,width=19,text="Coordinator Channel"}
|
||||
local crd_chan = NumberField{parent=net_c_3,x=21,y=10,width=7,default=ini_cfg.CRD_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_3,x=29,y=10,height=4,text="[CRD_CHANNEL]",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_3,x=1,y=12,width=14,text="Pocket Channel"}
|
||||
TextBox{parent=net_c_3,y=12,width=14,text="Pocket Channel"}
|
||||
self.pkt_chan = NumberField{parent=net_c_3,x=21,y=12,width=7,default=ini_cfg.PKT_Channel,min=1,max=65535,fg_bg=bw_fg_bg,dis_fg_bg=cpair(colors.lightGray,colors.white)}
|
||||
TextBox{parent=net_c_3,x=29,y=12,height=4,text="[PKT_CHANNEL]",fg_bg=g_lg_fg_bg}
|
||||
|
||||
@@ -185,16 +185,16 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
else chan_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_3,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_3,y=14,text="\x1b Back",callback=function()net_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_3,x=44,y=14,text="Next \x1a",callback=submit_channels,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_4,x=1,y=1,text="Please set the connection timeouts below."}
|
||||
TextBox{parent=net_c_4,x=1,y=3,height=4,text="You generally should not need to modify these. On slow servers, you can try to increase this to make the system wait longer before assuming a disconnection. The default for all is 5 seconds.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_4,y=1,text="Please set the connection timeouts below."}
|
||||
TextBox{parent=net_c_4,y=3,height=4,text="You generally should not need to modify these. On slow servers, you can try to increase this to make the system wait longer before assuming a disconnection. The default for all is 5 seconds.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_4,x=1,y=8,width=19,text="Supervisor Timeout"}
|
||||
TextBox{parent=net_c_4,y=8,width=19,text="Supervisor Timeout"}
|
||||
local svr_timeout = NumberField{parent=net_c_4,x=20,y=8,width=7,default=ini_cfg.SVR_Timeout,min=2,max=25,max_chars=6,max_frac_digits=2,allow_decimal=true,fg_bg=bw_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_4,x=1,y=10,width=14,text="Pocket Timeout"}
|
||||
TextBox{parent=net_c_4,y=10,width=14,text="Pocket Timeout"}
|
||||
self.api_timeout = NumberField{parent=net_c_4,x=20,y=10,width=7,default=ini_cfg.API_Timeout,min=2,max=25,max_chars=6,max_frac_digits=2,allow_decimal=true,fg_bg=bw_fg_bg,dis_fg_bg=cpair(colors.lightGray,colors.white)}
|
||||
|
||||
TextBox{parent=net_c_4,x=28,y=8,height=4,width=7,text="seconds\n\nseconds",fg_bg=g_lg_fg_bg}
|
||||
@@ -227,14 +227,14 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
else ct_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_4,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_4,y=14,text="\x1b Back",callback=function()net_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_4,x=44,y=14,text="Next \x1a",callback=submit_timeouts,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_5,x=1,y=1,text="Please set the wireless trusted range below."}
|
||||
TextBox{parent=net_c_5,x=1,y=3,height=3,text="Setting this to a value larger than 0 prevents wireless connections with devices that many meters (blocks) away in any direction.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_5,x=1,y=7,height=2,text="This is optional. You can disable this functionality by setting the value to 0.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_5,y=1,text="Please set the wireless trusted range below."}
|
||||
TextBox{parent=net_c_5,y=3,height=3,text="Setting this to a value larger than 0 prevents wireless connections with devices that many meters (blocks) away in any direction.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_5,y=7,height=2,text="This is optional. You can disable this functionality by setting the value to 0.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local range = NumberField{parent=net_c_5,x=1,y=10,width=10,default=ini_cfg.TrustedRange,min=0,max_chars=20,allow_decimal=true,fg_bg=bw_fg_bg}
|
||||
local range = NumberField{parent=net_c_5,y=10,width=10,default=ini_cfg.TrustedRange,min=0,max_chars=20,allow_decimal=true,fg_bg=bw_fg_bg}
|
||||
|
||||
local tr_err = TextBox{parent=net_c_5,x=8,y=14,width=35,text="Please set the trusted range.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
|
||||
@@ -248,14 +248,14 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
else tr_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_5,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(4)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_5,y=14,text="\x1b Back",callback=function()net_pane.set_value(4)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_5,x=44,y=14,text="Next \x1a",callback=submit_tr,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_6,x=1,y=1,height=2,text="Optionally, set the facility authentication key below. Do NOT use one of your passwords."}
|
||||
TextBox{parent=net_c_6,x=1,y=4,height=6,text="This enables verifying that messages are authentic, so it is intended for wireless security on multiplayer servers. All devices on the same wireless network MUST use the same key if any device has a key. This does result in some extra computation (can slow things down).",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_6,y=1,height=2,text="Optionally, set the facility authentication key below. Do NOT use one of your passwords."}
|
||||
TextBox{parent=net_c_6,y=4,height=6,text="This enables verifying that messages are authentic, so it is intended for wireless security on multiplayer servers. All devices on the same wireless network MUST use the same key if any device has a key. This does result in some extra computation (can slow things down).",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_6,x=1,y=11,text="Auth Key (Wireless Only, Not Used for Wired)"}
|
||||
local key, _ = TextField{parent=net_c_6,x=1,y=12,max_len=64,value=ini_cfg.AuthKey,width=32,height=1,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_6,y=11,text="Auth Key (Wireless Only, Not Used for Wired)"}
|
||||
local key, _ = TextField{parent=net_c_6,y=12,max_len=64,value=ini_cfg.AuthKey,width=32,height=1,fg_bg=bw_fg_bg}
|
||||
|
||||
local function censor_key(enable) key.censor(tri(enable, "*", nil)) end
|
||||
|
||||
@@ -282,7 +282,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
else key_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_6,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(5)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_6,y=14,text="\x1b Back",callback=function()net_pane.set_value(5)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_6,x=44,y=14,text="Next \x1a",callback=submit_auth,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -291,17 +291,17 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
|
||||
local log_c_1 = Div{parent=log_cfg,x=2,y=4,width=49}
|
||||
|
||||
TextBox{parent=log_cfg,x=1,y=2,text=" Logging Configuration",fg_bg=cpair(colors.black,colors.pink)}
|
||||
TextBox{parent=log_cfg,y=2,text=" Logging Configuration",fg_bg=cpair(colors.black,colors.pink)}
|
||||
|
||||
TextBox{parent=log_c_1,x=1,y=1,text="Please configure logging below."}
|
||||
TextBox{parent=log_c_1,y=1,text="Please configure logging below."}
|
||||
|
||||
TextBox{parent=log_c_1,x=1,y=3,text="Log File Mode"}
|
||||
local mode = RadioButton{parent=log_c_1,x=1,y=4,default=ini_cfg.LogMode+1,options={"Append on Startup","Replace on Startup"},radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.pink}
|
||||
TextBox{parent=log_c_1,y=3,text="Log File Mode"}
|
||||
local mode = RadioButton{parent=log_c_1,y=4,default=ini_cfg.LogMode+1,options={"Append on Startup","Replace on Startup"},radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.pink}
|
||||
|
||||
TextBox{parent=log_c_1,x=1,y=7,text="Log File Path"}
|
||||
local path = TextField{parent=log_c_1,x=1,y=8,width=49,height=1,value=ini_cfg.LogPath,max_len=128,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=log_c_1,y=7,text="Log File Path"}
|
||||
local path = TextField{parent=log_c_1,y=8,width=49,height=1,value=ini_cfg.LogPath,max_len=128,fg_bg=bw_fg_bg}
|
||||
|
||||
local en_dbg = Checkbox{parent=log_c_1,x=1,y=10,default=ini_cfg.LogDebug,label="Enable Logging Debug Messages",box_fg_bg=cpair(colors.pink,colors.black)}
|
||||
local en_dbg = Checkbox{parent=log_c_1,y=10,default=ini_cfg.LogDebug,label="Enable Logging Debug Messages",box_fg_bg=cpair(colors.pink,colors.black)}
|
||||
TextBox{parent=log_c_1,x=3,y=11,height=2,text="This results in much larger log files. It is best to only use this when there is a problem.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local path_err = TextBox{parent=log_c_1,x=8,y=14,width=35,text="Please provide a log file path.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
@@ -318,7 +318,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
else path_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=log_c_1,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(6)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=log_c_1,y=14,text="\x1b Back",callback=function()main_pane.set_value(6)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=log_c_1,x=44,y=14,text="Next \x1a",callback=submit_log,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -330,20 +330,20 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
local clr_c_3 = Div{parent=clr_cfg,x=2,y=4,width=49}
|
||||
local clr_c_4 = Div{parent=clr_cfg,x=2,y=4,width=49}
|
||||
|
||||
local clr_pane = MultiPane{parent=clr_cfg,x=1,y=4,panes={clr_c_1,clr_c_2,clr_c_3,clr_c_4}}
|
||||
local clr_pane = MultiPane{parent=clr_cfg,y=4,panes={clr_c_1,clr_c_2,clr_c_3,clr_c_4}}
|
||||
|
||||
TextBox{parent=clr_cfg,x=1,y=2,text=" Color Configuration",fg_bg=cpair(colors.black,colors.magenta)}
|
||||
TextBox{parent=clr_cfg,y=2,text=" Color Configuration",fg_bg=cpair(colors.black,colors.magenta)}
|
||||
|
||||
TextBox{parent=clr_c_1,x=1,y=1,height=2,text="Here you can select the color themes for the different UI displays."}
|
||||
TextBox{parent=clr_c_1,x=1,y=4,height=2,text="Click 'Accessibility' below to access colorblind assistive options.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=clr_c_1,y=1,height=2,text="Here you can select the color themes for the different UI displays."}
|
||||
TextBox{parent=clr_c_1,y=4,height=2,text="Click 'Accessibility' below to access colorblind assistive options.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=clr_c_1,x=1,y=7,text="Main UI Theme"}
|
||||
local main_theme = RadioButton{parent=clr_c_1,x=1,y=8,default=ini_cfg.MainTheme,options=themes.UI_THEME_NAMES,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||
TextBox{parent=clr_c_1,y=7,text="Main UI Theme"}
|
||||
local main_theme = RadioButton{parent=clr_c_1,y=8,default=ini_cfg.MainTheme,options=themes.UI_THEME_NAMES,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||
|
||||
TextBox{parent=clr_c_1,x=18,y=7,text="Front Panel Theme"}
|
||||
local fp_theme = RadioButton{parent=clr_c_1,x=18,y=8,default=ini_cfg.FrontPanelTheme,options=themes.FP_THEME_NAMES,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||
|
||||
TextBox{parent=clr_c_2,x=1,y=1,height=6,text="This system uses color heavily to distinguish ok and not, with some indicators using many colors. By selecting a mode below, indicators will change as shown. For non-standard modes, indicators with more than two colors will usually be split up."}
|
||||
TextBox{parent=clr_c_2,y=1,height=6,text="This system uses color heavily to distinguish ok and not, with some indicators using many colors. By selecting a mode below, indicators will change as shown. For non-standard modes, indicators with more than two colors will usually be split up."}
|
||||
|
||||
TextBox{parent=clr_c_2,x=21,y=7,text="Preview"}
|
||||
local _ = IndLight{parent=clr_c_2,x=21,y=8,label="Good",colors=cpair(colors.black,colors.green)}
|
||||
@@ -372,8 +372,8 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
end
|
||||
end
|
||||
|
||||
TextBox{parent=clr_c_2,x=1,y=7,width=10,text="Color Mode"}
|
||||
local c_mode = RadioButton{parent=clr_c_2,x=1,y=8,default=ini_cfg.ColorMode,options=themes.COLOR_MODE_NAMES,callback=recolor,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||
TextBox{parent=clr_c_2,y=7,width=10,text="Color Mode"}
|
||||
local c_mode = RadioButton{parent=clr_c_2,y=8,default=ini_cfg.ColorMode,options=themes.COLOR_MODE_NAMES,callback=recolor,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||
|
||||
TextBox{parent=clr_c_2,x=21,y=13,height=2,width=18,text="Note: exact color varies by theme.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
@@ -416,7 +416,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=clr_c_1,x=1,y=14,text="\x1b Back",callback=back_from_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=clr_c_1,y=14,text="\x1b Back",callback=back_from_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=clr_c_1,x=8,y=14,min_width=15,text="Accessibility",callback=show_access,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
tool_ctl.color_next = PushButton{parent=clr_c_1,x=44,y=14,text="Next \x1a",callback=submit_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
tool_ctl.color_apply = PushButton{parent=clr_c_1,x=43,y=14,min_width=7,text="Apply",callback=submit_colors,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg}
|
||||
@@ -428,12 +428,12 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
clr_pane.set_value(1)
|
||||
end
|
||||
|
||||
TextBox{parent=clr_c_3,x=1,y=1,text="Settings saved!"}
|
||||
PushButton{parent=clr_c_3,x=1,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
TextBox{parent=clr_c_3,y=1,text="Settings saved!"}
|
||||
PushButton{parent=clr_c_3,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
PushButton{parent=clr_c_3,x=44,y=14,min_width=6,text="Home",callback=c_go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=clr_c_4,x=1,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=clr_c_4,x=1,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
TextBox{parent=clr_c_4,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=clr_c_4,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
PushButton{parent=clr_c_4,x=44,y=14,min_width=6,text="Home",callback=c_go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -445,11 +445,11 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
local sum_c_3 = Div{parent=summary,x=2,y=4,width=49}
|
||||
local sum_c_4 = Div{parent=summary,x=2,y=4,width=49}
|
||||
|
||||
local sum_pane = MultiPane{parent=summary,x=1,y=4,panes={sum_c_1,sum_c_2,sum_c_3,sum_c_4}}
|
||||
local sum_pane = MultiPane{parent=summary,y=4,panes={sum_c_1,sum_c_2,sum_c_3,sum_c_4}}
|
||||
|
||||
TextBox{parent=summary,x=1,y=2,text=" Summary",fg_bg=cpair(colors.black,colors.green)}
|
||||
TextBox{parent=summary,y=2,text=" Summary",fg_bg=cpair(colors.black,colors.green)}
|
||||
|
||||
local setting_list = ListBox{parent=sum_c_1,x=1,y=1,height=12,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
local setting_list = ListBox{parent=sum_c_1,y=1,height=12,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
local function back_from_summary()
|
||||
if tool_ctl.viewing_config or self.importing_legacy then
|
||||
@@ -521,11 +521,11 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=sum_c_1,x=1,y=14,text="\x1b Back",callback=back_from_summary,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_1,y=14,text="\x1b Back",callback=back_from_summary,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
self.show_key_btn = PushButton{parent=sum_c_1,x=8,y=14,min_width=17,text="Unhide Auth Key",callback=function()self.show_auth_key()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
tool_ctl.settings_apply = PushButton{parent=sum_c_1,x=43,y=14,min_width=7,text="Apply",callback=save_and_continue,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=sum_c_2,x=1,y=1,text="Settings saved!"}
|
||||
TextBox{parent=sum_c_2,y=1,text="Settings saved!"}
|
||||
|
||||
local function go_home()
|
||||
main_pane.set_value(1)
|
||||
@@ -536,10 +536,10 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
sum_pane.set_value(1)
|
||||
end
|
||||
|
||||
PushButton{parent=sum_c_2,x=1,y=14,min_width=6,text="Home",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_2,y=14,min_width=6,text="Home",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_2,x=44,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
|
||||
TextBox{parent=sum_c_3,x=1,y=1,height=2,text="The old config.lua and coord.settings files will now be deleted, then the configurator will exit."}
|
||||
TextBox{parent=sum_c_3,y=1,height=2,text="The old config.lua and coord.settings files will now be deleted, then the configurator will exit."}
|
||||
|
||||
local function delete_legacy()
|
||||
fs.delete("/coordinator/config.lua")
|
||||
@@ -547,11 +547,11 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
exit()
|
||||
end
|
||||
|
||||
PushButton{parent=sum_c_3,x=1,y=14,min_width=8,text="Cancel",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_3,y=14,min_width=8,text="Cancel",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_3,x=44,y=14,min_width=6,text="OK",callback=delete_legacy,fg_bg=cpair(colors.black,colors.green),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
|
||||
TextBox{parent=sum_c_4,x=1,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=sum_c_4,x=1,y=14,min_width=6,text="Home",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
TextBox{parent=sum_c_4,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=sum_c_4,y=14,min_width=6,text="Home",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_4,x=44,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
|
||||
--#endregion
|
||||
@@ -677,7 +677,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
|
||||
local textbox
|
||||
if height > 1 then
|
||||
textbox = TextBox{parent=line,x=1,y=2,text=val,height=height-1}
|
||||
textbox = TextBox{parent=line,y=2,text=val,height=height-1}
|
||||
else
|
||||
textbox = TextBox{parent=line,x=label_w+1,y=1,text=val,alignment=RIGHT}
|
||||
end
|
||||
@@ -706,19 +706,19 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
end
|
||||
|
||||
if missing.tmp and tmp_cfg.WiredModem then
|
||||
local line = Div{parent=modem_list,x=1,y=1,height=1}
|
||||
local line = Div{parent=modem_list,y=1,height=1}
|
||||
|
||||
TextBox{parent=line,x=1,y=1,width=4,text="Used",fg_bg=cpair(tri(enable,colors.blue,colors.gray),colors.white)}
|
||||
TextBox{parent=line,y=1,width=4,text="Used",fg_bg=cpair(tri(enable,colors.blue,colors.gray),colors.white)}
|
||||
PushButton{parent=line,x=6,y=1,min_width=8,height=1,text="SELECT",callback=function()end,fg_bg=cpair(colors.black,colors.lightBlue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=g_lg_fg_bg}.disable()
|
||||
TextBox{parent=line,x=15,y=1,text="[missing]",fg_bg=cpair(colors.red,colors.white)}
|
||||
TextBox{parent=line,x=25,y=1,text=tmp_cfg.WiredModem}
|
||||
end
|
||||
|
||||
if missing.ini and ini_cfg.WiredModem and (tmp_cfg.WiredModem ~= ini_cfg.WiredModem) then
|
||||
local line = Div{parent=modem_list,x=1,y=1,height=1}
|
||||
local line = Div{parent=modem_list,y=1,height=1}
|
||||
local used = tmp_cfg.WiredModem == ini_cfg.WiredModem
|
||||
|
||||
TextBox{parent=line,x=1,y=1,width=4,text=tri(used,"Used","----"),fg_bg=cpair(tri(used and enable,colors.blue,colors.gray),colors.white)}
|
||||
TextBox{parent=line,y=1,width=4,text=tri(used,"Used","----"),fg_bg=cpair(tri(used and enable,colors.blue,colors.gray),colors.white)}
|
||||
local select_btn = PushButton{parent=line,x=6,y=1,min_width=8,height=1,text="SELECT",callback=function()select(ini_cfg.WiredModem)end,fg_bg=cpair(colors.black,colors.lightBlue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=line,x=15,y=1,text="[missing]",fg_bg=cpair(colors.red,colors.white)}
|
||||
TextBox{parent=line,x=25,y=1,text=ini_cfg.WiredModem}
|
||||
@@ -728,10 +728,10 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
|
||||
-- list wired modems
|
||||
for iface, _ in pairs(modems) do
|
||||
local line = Div{parent=modem_list,x=1,y=1,height=1}
|
||||
local line = Div{parent=modem_list,y=1,height=1}
|
||||
local used = tmp_cfg.WiredModem == iface
|
||||
|
||||
TextBox{parent=line,x=1,y=1,width=4,text=tri(used,"Used","----"),fg_bg=cpair(tri(used and enable,colors.blue,colors.gray),colors.white)}
|
||||
TextBox{parent=line,y=1,width=4,text=tri(used,"Used","----"),fg_bg=cpair(tri(used and enable,colors.blue,colors.gray),colors.white)}
|
||||
local select_btn = PushButton{parent=line,x=6,y=1,min_width=8,height=1,text="SELECT",callback=function()select(iface)end,fg_bg=cpair(colors.black,colors.lightBlue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=line,x=15,y=1,text=iface}
|
||||
|
||||
|
||||
@@ -200,20 +200,20 @@ local function config_view(display)
|
||||
|
||||
TextBox{parent=display,y=1,text="Coordinator Configurator",alignment=CENTER,fg_bg=style.header}
|
||||
|
||||
local root_pane_div = Div{parent=display,x=1,y=2}
|
||||
local root_pane_div = Div{parent=display,y=2}
|
||||
|
||||
local main_page = Div{parent=root_pane_div,x=1,y=1}
|
||||
local net_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local fac_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local mon_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local spkr_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local crd_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local log_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local clr_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local summary = Div{parent=root_pane_div,x=1,y=1}
|
||||
local changelog = Div{parent=root_pane_div,x=1,y=1}
|
||||
local main_page = Div{parent=root_pane_div,y=1}
|
||||
local net_cfg = Div{parent=root_pane_div,y=1}
|
||||
local fac_cfg = Div{parent=root_pane_div,y=1}
|
||||
local mon_cfg = Div{parent=root_pane_div,y=1}
|
||||
local spkr_cfg = Div{parent=root_pane_div,y=1}
|
||||
local crd_cfg = Div{parent=root_pane_div,y=1}
|
||||
local log_cfg = Div{parent=root_pane_div,y=1}
|
||||
local clr_cfg = Div{parent=root_pane_div,y=1}
|
||||
local summary = Div{parent=root_pane_div,y=1}
|
||||
local changelog = Div{parent=root_pane_div,y=1}
|
||||
|
||||
local main_pane = MultiPane{parent=root_pane_div,x=1,y=1,panes={main_page,net_cfg,fac_cfg,mon_cfg,spkr_cfg,crd_cfg,log_cfg,clr_cfg,summary,changelog}}
|
||||
local main_pane = MultiPane{parent=root_pane_div,y=1,panes={main_page,net_cfg,fac_cfg,mon_cfg,spkr_cfg,crd_cfg,log_cfg,clr_cfg,summary,changelog}}
|
||||
|
||||
--#region Main Page
|
||||
|
||||
@@ -298,20 +298,20 @@ local function config_view(display)
|
||||
|
||||
local cl = Div{parent=changelog,x=2,y=4,width=49}
|
||||
|
||||
TextBox{parent=changelog,x=1,y=2,text=" Config Change Log",fg_bg=bw_fg_bg}
|
||||
TextBox{parent=changelog,y=2,text=" Config Change Log",fg_bg=bw_fg_bg}
|
||||
|
||||
local c_log = ListBox{parent=cl,x=1,y=1,height=12,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
local c_log = ListBox{parent=cl,y=1,height=12,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
for _, change in ipairs(changes) do
|
||||
TextBox{parent=c_log,text=change[1],fg_bg=bw_fg_bg}
|
||||
for _, v in ipairs(change[2]) do
|
||||
local e = Div{parent=c_log,height=#util.strwrap(v,46)}
|
||||
TextBox{parent=e,y=1,x=1,text="- ",fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=e,y=1,text="- ",fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=e,y=1,x=3,text=v,height=e.get_height(),fg_bg=cpair(colors.gray,colors.white)}
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=cl,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=cl,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@ local types = require("scada-common.types")
|
||||
|
||||
local themes = require("graphics.themes")
|
||||
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local ioctl = require("coordinator.ioctl")
|
||||
local process = require("coordinator.process")
|
||||
|
||||
local apisessions = require("coordinator.session.apisessions")
|
||||
@@ -362,26 +362,20 @@ function coordinator.comms(version, backplane, sv_watchdog)
|
||||
self.sv_addr = comms.BROADCAST
|
||||
self.sv_linked = false
|
||||
self.sv_r_seq_num = nil
|
||||
iocontrol.fp_link_state(types.PANEL_LINK_STATE.DISCONNECTED)
|
||||
ioctl.fp_link_state(types.PANEL_LINK_STATE.DISCONNECTED)
|
||||
end
|
||||
|
||||
-- close the connection to the server
|
||||
function public.close()
|
||||
sv_watchdog.cancel()
|
||||
public.unlink()
|
||||
_send_sv(PROTOCOL.SCADA_MGMT, MGMT_TYPE.CLOSE, {})
|
||||
public.unlink()
|
||||
end
|
||||
|
||||
-- send the resume ready state to the supervisor
|
||||
---@param mode PROCESS process control mode
|
||||
---@param burn_target number burn rate target
|
||||
---@param charge_target number charge level target
|
||||
---@param gen_target number generation rate target
|
||||
---@param limits number[] unit burn rate limits
|
||||
function public.send_ready(mode, burn_target, charge_target, gen_target, limits)
|
||||
_send_sv(PROTOCOL.SCADA_CRDN, CRDN_TYPE.PROCESS_READY, {
|
||||
mode, burn_target, charge_target, gen_target, limits
|
||||
})
|
||||
---@param settings auto_ctl_cfg auto control settings
|
||||
function public.send_ready(settings)
|
||||
_send_sv(PROTOCOL.SCADA_CRDN, CRDN_TYPE.PROCESS_READY, { table.unpack(settings) })
|
||||
end
|
||||
|
||||
-- send a facility command
|
||||
@@ -392,15 +386,9 @@ function coordinator.comms(version, backplane, sv_watchdog)
|
||||
end
|
||||
|
||||
-- send the auto process control configuration with a start command
|
||||
---@param mode PROCESS process control mode
|
||||
---@param burn_target number burn rate target
|
||||
---@param charge_target number charge level target
|
||||
---@param gen_target number generation rate target
|
||||
---@param limits number[] unit burn rate limits
|
||||
function public.send_auto_start(mode, burn_target, charge_target, gen_target, limits)
|
||||
_send_sv(PROTOCOL.SCADA_CRDN, CRDN_TYPE.FAC_CMD, {
|
||||
FAC_COMMAND.START, mode, burn_target, charge_target, gen_target, limits
|
||||
})
|
||||
---@param settings auto_ctl_cfg auto control settings
|
||||
function public.send_auto_start(settings)
|
||||
_send_sv(PROTOCOL.SCADA_CRDN, CRDN_TYPE.FAC_CMD, { FAC_COMMAND.START, table.unpack(settings) })
|
||||
end
|
||||
|
||||
-- send a unit command
|
||||
@@ -507,7 +495,7 @@ function coordinator.comms(version, backplane, sv_watchdog)
|
||||
local id = apisessions.establish_session(src_addr, packet.scada_frame.seq_num(), firmware_v)
|
||||
coordinator.log_comms(util.c("API_ESTABLISH: pocket (", firmware_v, ") [@", src_addr, "] connected with session ID ", id))
|
||||
|
||||
local conf = iocontrol.get_db().facility.conf
|
||||
local conf = ioctl.get_db().facility.conf
|
||||
_send_api_establish_ack(packet.scada_frame, ESTABLISH_ACK.ALLOW, { conf.num_units, conf.cooling })
|
||||
else
|
||||
log.debug(util.c("API_ESTABLISH: illegal establish packet for device ", dev_type, " on pocket channel"))
|
||||
@@ -548,8 +536,8 @@ function coordinator.comms(version, backplane, sv_watchdog)
|
||||
if packet.type == CRDN_TYPE.INITIAL_BUILDS then
|
||||
if packet.length == 2 then
|
||||
-- record builds
|
||||
local fac_builds = iocontrol.record_facility_builds(packet.data[1])
|
||||
local unit_builds = iocontrol.record_unit_builds(packet.data[2])
|
||||
local fac_builds = ioctl.record_facility_builds(packet.data[1])
|
||||
local unit_builds = ioctl.record_unit_builds(packet.data[2])
|
||||
|
||||
if fac_builds and unit_builds then
|
||||
-- acknowledge receipt of builds
|
||||
@@ -563,7 +551,7 @@ function coordinator.comms(version, backplane, sv_watchdog)
|
||||
elseif packet.type == CRDN_TYPE.FAC_BUILDS then
|
||||
if packet.length == 1 then
|
||||
-- record facility builds
|
||||
if iocontrol.record_facility_builds(packet.data[1]) then
|
||||
if ioctl.record_facility_builds(packet.data[1]) then
|
||||
-- acknowledge receipt of builds
|
||||
_send_sv(PROTOCOL.SCADA_CRDN, CRDN_TYPE.FAC_BUILDS, {})
|
||||
else
|
||||
@@ -574,7 +562,7 @@ function coordinator.comms(version, backplane, sv_watchdog)
|
||||
end
|
||||
elseif packet.type == CRDN_TYPE.FAC_STATUS then
|
||||
-- update facility status
|
||||
if not iocontrol.update_facility_status(packet.data) then
|
||||
if not ioctl.update_facility_status(packet.data) then
|
||||
log.debug("received invalid FAC_STATUS packet")
|
||||
end
|
||||
elseif packet.type == CRDN_TYPE.FAC_CMD then
|
||||
@@ -588,7 +576,7 @@ function coordinator.comms(version, backplane, sv_watchdog)
|
||||
elseif cmd == FAC_COMMAND.STOP then
|
||||
process.fac_ack(cmd, ack)
|
||||
elseif cmd == FAC_COMMAND.START then
|
||||
if packet.length == 7 then
|
||||
if packet.length == 9 then
|
||||
process.start_ack_handle({ table.unpack(packet.data, 2) })
|
||||
else
|
||||
log.debug("SCADA_CRDN process start (with configuration) ack echo packet length mismatch")
|
||||
@@ -610,7 +598,7 @@ function coordinator.comms(version, backplane, sv_watchdog)
|
||||
elseif packet.type == CRDN_TYPE.UNIT_BUILDS then
|
||||
-- record builds
|
||||
if packet.length == 1 then
|
||||
if iocontrol.record_unit_builds(packet.data[1]) then
|
||||
if ioctl.record_unit_builds(packet.data[1]) then
|
||||
-- acknowledge receipt of builds
|
||||
_send_sv(PROTOCOL.SCADA_CRDN, CRDN_TYPE.UNIT_BUILDS, {})
|
||||
else
|
||||
@@ -621,7 +609,7 @@ function coordinator.comms(version, backplane, sv_watchdog)
|
||||
end
|
||||
elseif packet.type == CRDN_TYPE.UNIT_STATUSES then
|
||||
-- update statuses
|
||||
if not iocontrol.update_unit_statuses(packet.data) then
|
||||
if not ioctl.update_unit_statuses(packet.data) then
|
||||
log.debug("received invalid UNIT_STATUSES packet")
|
||||
end
|
||||
elseif packet.type == CRDN_TYPE.UNIT_CMD then
|
||||
@@ -631,7 +619,7 @@ function coordinator.comms(version, backplane, sv_watchdog)
|
||||
local unit_id = packet.data[2]
|
||||
local ack = packet.data[3] == true
|
||||
|
||||
local unit = iocontrol.get_db().units[unit_id]
|
||||
local unit = ioctl.get_db().units[unit_id]
|
||||
|
||||
if unit ~= nil then
|
||||
if cmd == UNIT_COMMAND.SCRAM then
|
||||
@@ -672,7 +660,7 @@ function coordinator.comms(version, backplane, sv_watchdog)
|
||||
|
||||
-- log.debug("coordinator RTT = " .. trip_time .. "ms")
|
||||
|
||||
iocontrol.get_db().facility.ps.publish("sv_ping", trip_time)
|
||||
ioctl.get_db().facility.ps.publish("sv_ping", trip_time)
|
||||
|
||||
_send_keep_alive_ack(timestamp)
|
||||
else
|
||||
@@ -681,10 +669,7 @@ function coordinator.comms(version, backplane, sv_watchdog)
|
||||
elseif packet.type == MGMT_TYPE.CLOSE then
|
||||
-- handle session close
|
||||
sv_watchdog.cancel()
|
||||
self.sv_addr = comms.BROADCAST
|
||||
self.sv_linked = false
|
||||
self.sv_r_seq_num = nil
|
||||
iocontrol.fp_link_state(types.PANEL_LINK_STATE.DISCONNECTED)
|
||||
public.unlink()
|
||||
log.info("server connection closed by remote host")
|
||||
else
|
||||
log.debug("received unknown SCADA_MGMT packet type " .. packet.type)
|
||||
@@ -697,7 +682,7 @@ function coordinator.comms(version, backplane, sv_watchdog)
|
||||
|
||||
if est_ack == ESTABLISH_ACK.ALLOW then
|
||||
-- reset to disconnected before validating
|
||||
iocontrol.fp_link_state(types.PANEL_LINK_STATE.DISCONNECTED)
|
||||
ioctl.fp_link_state(types.PANEL_LINK_STATE.DISCONNECTED)
|
||||
|
||||
if type(sv_config) == "table" and #sv_config == 2 then
|
||||
-- get configuration
|
||||
@@ -714,13 +699,13 @@ function coordinator.comms(version, backplane, sv_watchdog)
|
||||
log.info(util.c("supervisor establish request approved, linked to SV (CID#", src_addr, ") on ", tx_nic.phy_name()))
|
||||
|
||||
-- init io controller
|
||||
iocontrol.init(conf, public, config.TempScale, config.EnergyScale)
|
||||
ioctl.init(conf, public, config.TempScale, config.EnergyScale)
|
||||
|
||||
self.sv_addr = src_addr
|
||||
self.sv_linked = true
|
||||
self.sv_config_err = false
|
||||
|
||||
iocontrol.fp_link_state(types.PANEL_LINK_STATE.LINKED)
|
||||
ioctl.fp_link_state(types.PANEL_LINK_STATE.LINKED)
|
||||
else
|
||||
self.sv_config_err = true
|
||||
log.warning("supervisor config's number of units don't match coordinator's config, establish failed")
|
||||
@@ -738,17 +723,17 @@ function coordinator.comms(version, backplane, sv_watchdog)
|
||||
|
||||
if est_ack == ESTABLISH_ACK.DENY then
|
||||
if self.last_est_ack ~= est_ack then
|
||||
iocontrol.fp_link_state(types.PANEL_LINK_STATE.DENIED)
|
||||
ioctl.fp_link_state(types.PANEL_LINK_STATE.DENIED)
|
||||
log.info("supervisor connection denied")
|
||||
end
|
||||
elseif est_ack == ESTABLISH_ACK.COLLISION then
|
||||
if self.last_est_ack ~= est_ack then
|
||||
iocontrol.fp_link_state(types.PANEL_LINK_STATE.COLLISION)
|
||||
ioctl.fp_link_state(types.PANEL_LINK_STATE.COLLISION)
|
||||
log.warning("supervisor connection denied due to collision")
|
||||
end
|
||||
elseif est_ack == ESTABLISH_ACK.BAD_VERSION then
|
||||
if self.last_est_ack ~= est_ack then
|
||||
iocontrol.fp_link_state(types.PANEL_LINK_STATE.BAD_VERSION)
|
||||
ioctl.fp_link_state(types.PANEL_LINK_STATE.BAD_VERSION)
|
||||
log.warning("supervisor comms version mismatch")
|
||||
end
|
||||
else
|
||||
|
||||
@@ -31,7 +31,7 @@ local SPS_STATE = types.SPS_STATE
|
||||
local WARN_RTT = 1000 -- 2x as long as expected w/ 0 ping
|
||||
local HIGH_RTT = 1500 -- 3.33x as long as expected w/ 0 ping
|
||||
|
||||
local iocontrol = {}
|
||||
local ioctl = {}
|
||||
|
||||
local _ioctl = {
|
||||
-- connection states for status evaluation
|
||||
@@ -42,9 +42,9 @@ local _ioctl = {
|
||||
coroutines = {}
|
||||
}
|
||||
|
||||
---@class ioctl
|
||||
---@class crd_io
|
||||
local io = {
|
||||
---@class ioctl_front_panel
|
||||
---@class crd_io_fp
|
||||
fp = { ps = psil.create() }
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ local io = {
|
||||
---@param comms coord_comms comms reference
|
||||
---@param temp_scale TEMP_SCALE temperature unit
|
||||
---@param energy_scale ENERGY_SCALE energy unit
|
||||
function iocontrol.init(conf, comms, temp_scale, energy_scale)
|
||||
function ioctl.init(conf, comms, temp_scale, energy_scale)
|
||||
io.temp_label = TEMP_UNITS[temp_scale]
|
||||
io.energy_label = ENERGY_UNITS[energy_scale]
|
||||
|
||||
@@ -82,7 +82,7 @@ function iocontrol.init(conf, comms, temp_scale, energy_scale)
|
||||
end
|
||||
|
||||
-- facility data structure
|
||||
---@class ioctl_facility
|
||||
---@class crd_io_facility
|
||||
io.facility = {
|
||||
conf = conf,
|
||||
num_units = conf.num_units,
|
||||
@@ -153,12 +153,12 @@ function iocontrol.init(conf, comms, temp_scale, energy_scale)
|
||||
end
|
||||
|
||||
-- create unit data structures
|
||||
io.units = {} ---@type ioctl_unit[]
|
||||
io.units = {} ---@type crd_io_unit[]
|
||||
for i = 1, conf.num_units do
|
||||
local function ack(alarm) process.ack_alarm(i, alarm) end
|
||||
local function reset(alarm) process.reset_alarm(i, alarm) end
|
||||
|
||||
---@class ioctl_unit
|
||||
---@class crd_io_unit
|
||||
local entry = {
|
||||
unit_id = i,
|
||||
connected = false,
|
||||
@@ -298,19 +298,19 @@ local function fp_eval_status()
|
||||
end
|
||||
|
||||
-- toggle heartbeat indicator
|
||||
function iocontrol.heartbeat() io.fp.ps.toggle("heartbeat") end
|
||||
function ioctl.heartbeat() io.fp.ps.toggle("heartbeat") end
|
||||
|
||||
-- report versions to front panel
|
||||
---@param firmware_v string coordinator version
|
||||
---@param comms_v string comms version
|
||||
function iocontrol.fp_versions(firmware_v, comms_v)
|
||||
function ioctl.fp_versions(firmware_v, comms_v)
|
||||
io.fp.ps.publish("version", firmware_v)
|
||||
io.fp.ps.publish("comms_version", comms_v)
|
||||
end
|
||||
|
||||
-- report presence of the wired comms modem
|
||||
---@param has_modem boolean
|
||||
function iocontrol.fp_has_wd_modem(has_modem)
|
||||
function ioctl.fp_has_wd_modem(has_modem)
|
||||
io.fp.ps.publish("has_wd_modem", has_modem)
|
||||
|
||||
_ioctl.wd_modem = has_modem
|
||||
@@ -319,7 +319,7 @@ end
|
||||
|
||||
-- report presence of the wireless comms modem
|
||||
---@param has_modem boolean
|
||||
function iocontrol.fp_has_wl_modem(has_modem)
|
||||
function ioctl.fp_has_wl_modem(has_modem)
|
||||
io.fp.ps.publish("has_wl_modem", has_modem)
|
||||
|
||||
_ioctl.wl_modem = has_modem
|
||||
@@ -328,19 +328,19 @@ end
|
||||
|
||||
-- report if the wired network is up
|
||||
---@param up boolean
|
||||
function iocontrol.fp_has_wd_net(up)
|
||||
function ioctl.fp_has_wd_net(up)
|
||||
io.fp.ps.publish("has_wd_net", up)
|
||||
end
|
||||
|
||||
-- report if the wireless network is up
|
||||
---@param up boolean
|
||||
function iocontrol.fp_has_wl_net(up)
|
||||
function ioctl.fp_has_wl_net(up)
|
||||
io.fp.ps.publish("has_wl_net", up)
|
||||
end
|
||||
|
||||
-- report presence of the speaker
|
||||
---@param has_speaker boolean
|
||||
function iocontrol.fp_has_speaker(has_speaker)
|
||||
function ioctl.fp_has_speaker(has_speaker)
|
||||
io.fp.ps.publish("has_speaker", has_speaker)
|
||||
|
||||
_ioctl.speaker = has_speaker
|
||||
@@ -349,12 +349,12 @@ end
|
||||
|
||||
-- report supervisor link state
|
||||
---@param state integer
|
||||
function iocontrol.fp_link_state(state) io.fp.ps.publish("link_state", state) end
|
||||
function ioctl.fp_link_state(state) io.fp.ps.publish("link_state", state) end
|
||||
|
||||
-- report monitor connection state
|
||||
---@param id string|integer unit ID for unit monitor, "main" for main monitor, or "flow" for flow monitor
|
||||
---@param connected 1|2|3 1 for disconnected, 2 for connected but no view (may not fit), 3 for connected with view rendered
|
||||
function iocontrol.fp_monitor_state(id, connected)
|
||||
function ioctl.fp_monitor_state(id, connected)
|
||||
local name = nil
|
||||
|
||||
if id == "main" then
|
||||
@@ -376,7 +376,7 @@ end
|
||||
-- report thread (routine) statuses
|
||||
---@param thread string thread name
|
||||
---@param ok boolean thread state
|
||||
function iocontrol.fp_rt_status(thread, ok)
|
||||
function ioctl.fp_rt_status(thread, ok)
|
||||
local name = util.c("routine__", thread)
|
||||
|
||||
io.fp.ps.publish(name, ok)
|
||||
@@ -389,7 +389,7 @@ end
|
||||
---@param session_id integer PKT session
|
||||
---@param fw string firmware version
|
||||
---@param s_addr integer PKT computer ID
|
||||
function iocontrol.fp_pkt_connected(session_id, fw, s_addr)
|
||||
function ioctl.fp_pkt_connected(session_id, fw, s_addr)
|
||||
io.fp.ps.publish("pkt_" .. session_id .. "_fw", fw)
|
||||
io.fp.ps.publish("pkt_" .. session_id .. "_addr", util.sprintf("@ C% 3d", s_addr))
|
||||
pgi.create_pkt_entry(session_id)
|
||||
@@ -397,14 +397,14 @@ end
|
||||
|
||||
-- report PKT session disconnected
|
||||
---@param session_id integer PKT session
|
||||
function iocontrol.fp_pkt_disconnected(session_id)
|
||||
function ioctl.fp_pkt_disconnected(session_id)
|
||||
pgi.delete_pkt_entry(session_id)
|
||||
end
|
||||
|
||||
-- transmit PKT session RTT
|
||||
---@param session_id integer PKT session
|
||||
---@param rtt integer round trip time
|
||||
function iocontrol.fp_pkt_rtt(session_id, rtt)
|
||||
function ioctl.fp_pkt_rtt(session_id, rtt)
|
||||
io.fp.ps.publish("pkt_" .. session_id .. "_rtt", rtt)
|
||||
|
||||
if rtt > HIGH_RTT then
|
||||
@@ -450,7 +450,7 @@ end
|
||||
-- populate facility structure builds
|
||||
---@param build table
|
||||
---@return boolean valid
|
||||
function iocontrol.record_facility_builds(build)
|
||||
function ioctl.record_facility_builds(build)
|
||||
local valid = true
|
||||
|
||||
if type(build) == "table" then
|
||||
@@ -493,12 +493,12 @@ end
|
||||
-- populate unit structure builds
|
||||
---@param builds table
|
||||
---@return boolean valid
|
||||
function iocontrol.record_unit_builds(builds)
|
||||
function ioctl.record_unit_builds(builds)
|
||||
local valid = true
|
||||
|
||||
-- note: if not all units and RTUs are connected, some will be nil
|
||||
for id, build in pairs(builds) do
|
||||
local unit = io.units[id] ---@type ioctl_unit
|
||||
local unit = io.units[id] ---@type crd_io_unit
|
||||
|
||||
local log_header = util.c("iocontrol.record_unit_builds[UNIT ", id, "]: ")
|
||||
|
||||
@@ -624,7 +624,7 @@ end
|
||||
-- update facility status
|
||||
---@param status table
|
||||
---@return boolean valid
|
||||
function iocontrol.update_facility_status(status)
|
||||
function ioctl.update_facility_status(status)
|
||||
local valid = true
|
||||
local log_header = util.c("iocontrol.update_facility_status: ")
|
||||
|
||||
@@ -916,7 +916,7 @@ end
|
||||
-- update unit statuses
|
||||
---@param statuses table
|
||||
---@return boolean valid
|
||||
function iocontrol.update_unit_statuses(statuses)
|
||||
function ioctl.update_unit_statuses(statuses)
|
||||
local valid = true
|
||||
|
||||
if type(statuses) ~= "table" then
|
||||
@@ -1370,6 +1370,6 @@ end
|
||||
--#endregion
|
||||
|
||||
-- get the IO controller database
|
||||
function iocontrol.get_db() return io end
|
||||
function ioctl.get_db() return io end
|
||||
|
||||
return iocontrol
|
||||
return ioctl
|
||||
@@ -19,14 +19,17 @@ local REQUEST_TIMEOUT_MS = 10000
|
||||
local process = {}
|
||||
|
||||
local pctl = {
|
||||
io = nil, ---@type ioctl
|
||||
io = nil, ---@type crd_io
|
||||
comms = nil, ---@type coord_comms
|
||||
---@class sys_control_states
|
||||
control_states = {
|
||||
---@class sys_auto_config
|
||||
process = {
|
||||
mode = PROCESS.INACTIVE, ---@type PROCESS
|
||||
alt_mode = false,
|
||||
burn_target = 0.0,
|
||||
range_start = 10,
|
||||
range_stop = 90,
|
||||
charge_target = 0.0,
|
||||
gen_target = 0.0,
|
||||
limits = {}, ---@type number[]
|
||||
@@ -64,10 +67,10 @@ end
|
||||
--#region Core
|
||||
|
||||
-- initialize the process controller
|
||||
---@param iocontrol ioctl iocontrl system
|
||||
---@param crd_io crd_io iocontrol system
|
||||
---@param coord_comms coord_comms coordinator communications
|
||||
function process.init(iocontrol, coord_comms)
|
||||
pctl.io = iocontrol
|
||||
function process.init(crd_io, coord_comms)
|
||||
pctl.io = crd_io
|
||||
pctl.comms = coord_comms
|
||||
|
||||
-- create command handling objects
|
||||
@@ -85,29 +88,13 @@ function process.init(iocontrol, coord_comms)
|
||||
|
||||
local ctrl_states = settings.get("ControlStates", {}) ---@type sys_control_states
|
||||
local config = ctrl_states.process
|
||||
local f_ps = crd_io.facility.ps
|
||||
|
||||
-- facility auto control configuration
|
||||
if type(config) == "table" then
|
||||
ctl_proc.mode = config.mode
|
||||
ctl_proc.burn_target = config.burn_target
|
||||
ctl_proc.charge_target = config.charge_target
|
||||
ctl_proc.gen_target = config.gen_target
|
||||
ctl_proc.limits = config.limits
|
||||
ctl_proc.waste_product = config.waste_product
|
||||
ctl_proc.pu_fallback = config.pu_fallback
|
||||
ctl_proc.sps_low_power = config.sps_low_power
|
||||
|
||||
pctl.io.facility.ps.publish("process_mode", ctl_proc.mode)
|
||||
pctl.io.facility.ps.publish("process_burn_target", ctl_proc.burn_target)
|
||||
pctl.io.facility.ps.publish("process_charge_target", pctl.io.energy_convert_from_fe(ctl_proc.charge_target))
|
||||
pctl.io.facility.ps.publish("process_gen_target", pctl.io.energy_convert_from_fe(ctl_proc.gen_target))
|
||||
pctl.io.facility.ps.publish("process_waste_product", ctl_proc.waste_product)
|
||||
pctl.io.facility.ps.publish("process_pu_fallback", ctl_proc.pu_fallback)
|
||||
pctl.io.facility.ps.publish("process_sps_low_power", ctl_proc.sps_low_power)
|
||||
|
||||
for id = 1, math.min(#ctl_proc.limits, pctl.io.facility.num_units) do
|
||||
local unit = pctl.io.units[id]
|
||||
unit.unit_ps.publish("burn_limit", ctl_proc.limits[id])
|
||||
-- update each field if present in the config
|
||||
for key, _ in pairs(ctl_proc) do
|
||||
ctl_proc[key] = config[key] or ctl_proc[key]
|
||||
end
|
||||
|
||||
log.info("PROCESS: loaded auto control settings")
|
||||
@@ -118,6 +105,22 @@ function process.init(iocontrol, coord_comms)
|
||||
pctl.comms.send_fac_command(F_CMD.SET_SPS_LP, ctl_proc.sps_low_power)
|
||||
end
|
||||
|
||||
f_ps.publish("process_mode", ctl_proc.mode)
|
||||
f_ps.publish("process_alt_mode", ctl_proc.alt_mode)
|
||||
f_ps.publish("process_burn_target", ctl_proc.burn_target)
|
||||
f_ps.publish("process_range_start", ctl_proc.range_start)
|
||||
f_ps.publish("process_range_stop", ctl_proc.range_stop)
|
||||
f_ps.publish("process_charge_target", pctl.io.energy_convert_from_fe(ctl_proc.charge_target))
|
||||
f_ps.publish("process_gen_target", pctl.io.energy_convert_from_fe(ctl_proc.gen_target))
|
||||
f_ps.publish("process_waste_product", ctl_proc.waste_product)
|
||||
f_ps.publish("process_pu_fallback", ctl_proc.pu_fallback)
|
||||
f_ps.publish("process_sps_low_power", ctl_proc.sps_low_power)
|
||||
|
||||
for id = 1, math.min(#ctl_proc.limits, pctl.io.facility.num_units) do
|
||||
local unit = pctl.io.units[id]
|
||||
unit.unit_ps.publish("burn_limit", ctl_proc.limits[id])
|
||||
end
|
||||
|
||||
-- unit waste states
|
||||
local waste_modes = ctrl_states.waste_modes
|
||||
if type(waste_modes) == "table" then
|
||||
@@ -142,8 +145,9 @@ function process.init(iocontrol, coord_comms)
|
||||
|
||||
-- report to the supervisor all initial configuration data has been sent
|
||||
-- startup resume can occur if needed
|
||||
local p = ctl_proc
|
||||
pctl.comms.send_ready(p.mode, p.burn_target, p.charge_target, p.gen_target, p.limits)
|
||||
local p = ctl_proc
|
||||
local mode = util.trinary(p.alt_mode and p.mode == PROCESS.CHARGE, PROCESS.RANGE_CONTROL, p.mode)
|
||||
pctl.comms.send_ready({ mode, p.burn_target, p.range_start, p.range_stop, p.charge_target, p.gen_target, p.limits })
|
||||
end
|
||||
|
||||
-- create a handle to process control for usage of commands that get acknowledgements
|
||||
@@ -191,21 +195,19 @@ function process.create_handle()
|
||||
-- start automatic process control with current settings
|
||||
function handle.process_start()
|
||||
if f_request(F_CMD.START, handle.fac_ack.on_start) then
|
||||
local p = pctl.control_states.process
|
||||
pctl.comms.send_auto_start(p.mode, p.burn_target, p.charge_target, p.gen_target, p.limits)
|
||||
local p = pctl.control_states.process
|
||||
local mode = util.trinary(p.alt_mode and p.mode == PROCESS.CHARGE, PROCESS.RANGE_CONTROL, p.mode)
|
||||
|
||||
pctl.comms.send_auto_start({ mode, p.burn_target, p.range_start, p.range_stop, p.charge_target, p.gen_target, p.limits })
|
||||
log.debug("PROCESS: START AUTO CTRL")
|
||||
end
|
||||
end
|
||||
|
||||
-- start automatic process control with remote settings that haven't been set on the coordinator
|
||||
---@param mode PROCESS process control mode
|
||||
---@param burn_target number burn rate target
|
||||
---@param charge_target number charge level target
|
||||
---@param gen_target number generation rate target
|
||||
---@param limits number[] unit burn rate limits
|
||||
function handle.process_start_remote(mode, burn_target, charge_target, gen_target, limits)
|
||||
---@param settings auto_ctl_cfg auto control settings
|
||||
function handle.process_start_remote(settings)
|
||||
if f_request(F_CMD.START, handle.fac_ack.on_start) then
|
||||
pctl.comms.send_auto_start(mode, burn_target, charge_target, gen_target, limits)
|
||||
pctl.comms.send_auto_start(settings)
|
||||
log.debug("PROCESS: START AUTO CTRL")
|
||||
end
|
||||
end
|
||||
@@ -470,20 +472,26 @@ end
|
||||
|
||||
-- save process control settings
|
||||
---@param mode PROCESS process control mode
|
||||
---@param alt_mode boolean true if using range control instead of charge control
|
||||
---@param burn_target number burn rate target
|
||||
---@param range_start integer range control activation threshold
|
||||
---@param range_stop integer range control deactivation threshold
|
||||
---@param charge_target number charge level target
|
||||
---@param gen_target number generation rate target
|
||||
---@param limits number[] unit burn rate limits
|
||||
function process.save(mode, burn_target, charge_target, gen_target, limits)
|
||||
function process.save(mode, alt_mode, burn_target, range_start, range_stop, charge_target, gen_target, limits)
|
||||
log.debug("PROCESS: SAVE")
|
||||
|
||||
-- update config table
|
||||
local ctl_proc = pctl.control_states.process
|
||||
ctl_proc.mode = mode
|
||||
ctl_proc.burn_target = burn_target
|
||||
ctl_proc.charge_target = charge_target
|
||||
ctl_proc.gen_target = gen_target
|
||||
ctl_proc.limits = limits
|
||||
local p = pctl.control_states.process
|
||||
p.mode = mode
|
||||
p.alt_mode = alt_mode
|
||||
p.burn_target = burn_target
|
||||
p.range_start = range_start
|
||||
p.range_stop = range_stop
|
||||
p.charge_target = charge_target
|
||||
p.gen_target = gen_target
|
||||
p.limits = limits
|
||||
|
||||
-- save config
|
||||
pctl.io.facility.save_cfg_ack(_write_auto_config())
|
||||
@@ -494,21 +502,35 @@ end
|
||||
function process.start_ack_handle(response)
|
||||
local ack = response[1]
|
||||
|
||||
local ctl_proc = pctl.control_states.process
|
||||
ctl_proc.mode = response[2]
|
||||
ctl_proc.burn_target = response[3]
|
||||
ctl_proc.charge_target = response[4]
|
||||
ctl_proc.gen_target = response[5]
|
||||
local p = pctl.control_states.process
|
||||
p.mode = response[2]
|
||||
p.burn_target = response[3]
|
||||
p.range_start = response[4]
|
||||
p.range_stop = response[5]
|
||||
p.charge_target = response[6]
|
||||
p.gen_target = response[7]
|
||||
|
||||
for i = 1, math.min(#response[6], pctl.io.facility.num_units) do
|
||||
ctl_proc.limits[i] = response[6][i]
|
||||
pctl.io.units[i].unit_ps.publish("burn_limit", ctl_proc.limits[i])
|
||||
for i = 1, math.min(#response[8], pctl.io.facility.num_units) do
|
||||
p.limits[i] = response[8][i]
|
||||
pctl.io.units[i].unit_ps.publish("burn_limit", p.limits[i])
|
||||
end
|
||||
|
||||
pctl.io.facility.ps.publish("process_mode", ctl_proc.mode)
|
||||
pctl.io.facility.ps.publish("process_burn_target", ctl_proc.burn_target)
|
||||
pctl.io.facility.ps.publish("process_charge_target", pctl.io.energy_convert_from_fe(ctl_proc.charge_target))
|
||||
pctl.io.facility.ps.publish("process_gen_target", pctl.io.energy_convert_from_fe(ctl_proc.gen_target))
|
||||
if p.mode == PROCESS.RANGE_CONTROL then
|
||||
p.mode = PROCESS.CHARGE
|
||||
p.alt_mode = true
|
||||
elseif p.mode == PROCESS.CHARGE then
|
||||
p.alt_mode = false
|
||||
end
|
||||
|
||||
local f_ps = pctl.io.facility.ps
|
||||
|
||||
f_ps.publish("process_mode", p.mode)
|
||||
f_ps.publish("process_alt_mode", p.alt_mode)
|
||||
f_ps.publish("process_burn_target", p.burn_target)
|
||||
f_ps.publish("process_range_start", p.range_start)
|
||||
f_ps.publish("process_range_stop", p.range_stop)
|
||||
f_ps.publish("process_charge_target", pctl.io.energy_convert_from_fe(p.charge_target))
|
||||
f_ps.publish("process_gen_target", pctl.io.energy_convert_from_fe(p.gen_target))
|
||||
|
||||
_write_auto_config()
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ local log = require("scada-common.log")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local coordinator = require("coordinator.coordinator")
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local ioctl = require("coordinator.ioctl")
|
||||
|
||||
local style = require("coordinator.ui.style")
|
||||
local pgi = require("coordinator.ui.pgi")
|
||||
@@ -193,7 +193,7 @@ function renderer.try_start_ui()
|
||||
if engine.monitors.main ~= nil then
|
||||
engine.ui.main_display = DisplayBox{window=engine.monitors.main,fg_bg=style.root}
|
||||
main_view(engine.ui.main_display)
|
||||
iocontrol.fp_monitor_state("main", 3)
|
||||
ioctl.fp_monitor_state("main", 3)
|
||||
util.nop()
|
||||
end
|
||||
|
||||
@@ -201,7 +201,7 @@ function renderer.try_start_ui()
|
||||
if engine.monitors.flow ~= nil then
|
||||
engine.ui.flow_display = DisplayBox{window=engine.monitors.flow,fg_bg=style.root}
|
||||
flow_view(engine.ui.flow_display)
|
||||
iocontrol.fp_monitor_state("flow", 3)
|
||||
ioctl.fp_monitor_state("flow", 3)
|
||||
util.nop()
|
||||
end
|
||||
|
||||
@@ -209,7 +209,7 @@ function renderer.try_start_ui()
|
||||
for idx, display in pairs(engine.monitors.unit_displays) do
|
||||
engine.ui.unit_displays[idx] = DisplayBox{window=display,fg_bg=style.root}
|
||||
unit_view(engine.ui.unit_displays[idx], idx)
|
||||
iocontrol.fp_monitor_state(idx, 3)
|
||||
ioctl.fp_monitor_state(idx, 3)
|
||||
util.nop()
|
||||
end
|
||||
end)
|
||||
@@ -239,17 +239,17 @@ function renderer.close_ui()
|
||||
|
||||
if engine.ui.main_display ~= nil then
|
||||
engine.ui.main_display.delete()
|
||||
iocontrol.fp_monitor_state("main", 2)
|
||||
ioctl.fp_monitor_state("main", 2)
|
||||
end
|
||||
|
||||
if engine.ui.flow_display ~= nil then
|
||||
engine.ui.flow_display.delete()
|
||||
iocontrol.fp_monitor_state("flow", 2)
|
||||
ioctl.fp_monitor_state("flow", 2)
|
||||
end
|
||||
|
||||
for idx, display in pairs(engine.ui.unit_displays) do
|
||||
display.delete()
|
||||
iocontrol.fp_monitor_state(idx, 2)
|
||||
ioctl.fp_monitor_state(idx, 2)
|
||||
end
|
||||
|
||||
-- report ui as not ready
|
||||
@@ -360,7 +360,7 @@ function renderer.handle_resize(name)
|
||||
ui.main_display = nil
|
||||
end
|
||||
|
||||
iocontrol.fp_monitor_state("main", 2)
|
||||
ioctl.fp_monitor_state("main", 2)
|
||||
|
||||
engine.dmesg_window.setVisible(not engine.ui_ready)
|
||||
|
||||
@@ -372,7 +372,7 @@ function renderer.handle_resize(name)
|
||||
end)
|
||||
|
||||
if ok then
|
||||
iocontrol.fp_monitor_state("main", 3)
|
||||
ioctl.fp_monitor_state("main", 3)
|
||||
|
||||
log_render("main view re-draw completed in " .. (util.time_ms() - draw_start) .. "ms")
|
||||
else
|
||||
@@ -399,7 +399,7 @@ function renderer.handle_resize(name)
|
||||
ui.flow_display = nil
|
||||
end
|
||||
|
||||
iocontrol.fp_monitor_state("flow", 2)
|
||||
ioctl.fp_monitor_state("flow", 2)
|
||||
|
||||
if engine.ui_ready then
|
||||
local draw_start = util.time_ms()
|
||||
@@ -409,7 +409,7 @@ function renderer.handle_resize(name)
|
||||
end)
|
||||
|
||||
if ok then
|
||||
iocontrol.fp_monitor_state("flow", 3)
|
||||
ioctl.fp_monitor_state("flow", 3)
|
||||
|
||||
log_render("flow view re-draw completed in " .. (util.time_ms() - draw_start) .. "ms")
|
||||
else
|
||||
@@ -438,7 +438,7 @@ function renderer.handle_resize(name)
|
||||
ui.unit_displays[idx] = nil
|
||||
end
|
||||
|
||||
iocontrol.fp_monitor_state(idx, 2)
|
||||
ioctl.fp_monitor_state(idx, 2)
|
||||
|
||||
if engine.ui_ready then
|
||||
local draw_start = util.time_ms()
|
||||
@@ -448,7 +448,7 @@ function renderer.handle_resize(name)
|
||||
end)
|
||||
|
||||
if ok then
|
||||
iocontrol.fp_monitor_state(idx, 3)
|
||||
ioctl.fp_monitor_state(idx, 3)
|
||||
|
||||
log_render("unit " .. idx .. " view re-draw completed in " .. (util.time_ms() - draw_start) .. "ms")
|
||||
else
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
|
||||
local log = require("scada-common.log")
|
||||
local mqueue = require("scada-common.mqueue")
|
||||
local util = require("scada-common.util")
|
||||
local log = require("scada-common.log")
|
||||
local mqueue = require("scada-common.mqueue")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local ioctl = require("coordinator.ioctl")
|
||||
|
||||
local pocket = require("coordinator.session.pocket")
|
||||
local pocket = require("coordinator.session.pocket")
|
||||
|
||||
local apisessions = {}
|
||||
|
||||
@@ -112,7 +112,7 @@ function apisessions.establish_session(source_addr, i_seq_num, version)
|
||||
|
||||
setmetatable(pkt_s, mt)
|
||||
|
||||
iocontrol.fp_pkt_connected(id, version, source_addr)
|
||||
ioctl.fp_pkt_connected(id, version, source_addr)
|
||||
log.debug(util.c("API: established new session: ", pkt_s))
|
||||
|
||||
self.next_id = id + 1
|
||||
@@ -123,6 +123,7 @@ end
|
||||
|
||||
-- attempt to identify which session's watchdog timer fired
|
||||
---@param timer_event number
|
||||
---@return boolean was_watchdog if this event was one of the watchdogs
|
||||
function apisessions.check_all_watchdogs(timer_event)
|
||||
for i = 1, #self.sessions do
|
||||
local session = self.sessions[i]
|
||||
@@ -131,9 +132,12 @@ function apisessions.check_all_watchdogs(timer_event)
|
||||
if triggered then
|
||||
log.debug(util.c("API: watchdog closing session ", session, "..."))
|
||||
_shutdown(session)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- iterate all the API sessions
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
local comms = require("scada-common.comms")
|
||||
local log = require("scada-common.log")
|
||||
local mqueue = require("scada-common.mqueue")
|
||||
local types = require("scada-common.types")
|
||||
local util = require("scada-common.util")
|
||||
local comms = require("scada-common.comms")
|
||||
local log = require("scada-common.log")
|
||||
local mqueue = require("scada-common.mqueue")
|
||||
local types = require("scada-common.types")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local process = require("coordinator.process")
|
||||
local ioctl = require("coordinator.ioctl")
|
||||
local process = require("coordinator.process")
|
||||
|
||||
local pocket = {}
|
||||
|
||||
@@ -16,6 +16,7 @@ local FAC_COMMAND = comms.FAC_COMMAND
|
||||
local UNIT_COMMAND = comms.UNIT_COMMAND
|
||||
|
||||
local AUTO_GROUP = types.AUTO_GROUP
|
||||
local PROCESS = types.PROCESS
|
||||
local WASTE_MODE = types.WASTE_MODE
|
||||
|
||||
-- retry time constants in ms
|
||||
@@ -79,7 +80,7 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout)
|
||||
local function _close()
|
||||
self.conn_watchdog.cancel()
|
||||
self.connected = false
|
||||
iocontrol.fp_pkt_disconnected(id)
|
||||
ioctl.fp_pkt_disconnected(id)
|
||||
end
|
||||
|
||||
-- send a CRDN packet
|
||||
@@ -118,7 +119,7 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout)
|
||||
f_ack.on_start = function (success) _send(CRDN_TYPE.FAC_CMD, { FAC_COMMAND.START, success }) end
|
||||
f_ack.on_stop = function (success) _send(CRDN_TYPE.FAC_CMD, { FAC_COMMAND.STOP, success }) end
|
||||
|
||||
for u = 1, iocontrol.get_db().facility.num_units do
|
||||
for u = 1, ioctl.get_db().facility.num_units do
|
||||
local u_ack = self.proc_handle.unit_ack[u]
|
||||
u_ack.on_start = function (success) _send(CRDN_TYPE.UNIT_CMD, { UNIT_COMMAND.START, u, success }) end
|
||||
u_ack.on_scram = function (success) _send(CRDN_TYPE.UNIT_CMD, { UNIT_COMMAND.SCRAM, u, success }) end
|
||||
@@ -144,7 +145,7 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout)
|
||||
if pkt.scada_frame.protocol() == PROTOCOL.SCADA_CRDN then
|
||||
---@cast pkt crdn_packet
|
||||
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
-- handle packet by type
|
||||
if pkt.type == CRDN_TYPE.FAC_CMD then
|
||||
@@ -158,9 +159,9 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout)
|
||||
log.info(log_tag .. "STOP PROCESS CTRL")
|
||||
self.proc_handle.process_stop()
|
||||
elseif cmd == FAC_COMMAND.START then
|
||||
if pkt.length == 6 then
|
||||
if pkt.length == 8 then
|
||||
log.info(log_tag .. "START PROCESS CTRL")
|
||||
self.proc_handle.process_start_remote(pkt.data[2], pkt.data[3], pkt.data[4], pkt.data[5], pkt.data[6])
|
||||
self.proc_handle.process_start_remote({ table.unpack(pkt.data, 2) })
|
||||
else
|
||||
log.debug(log_tag .. "CRDN auto start (with configuration) packet length mismatch")
|
||||
end
|
||||
@@ -374,13 +375,15 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout)
|
||||
}
|
||||
end
|
||||
|
||||
local mode = util.trinary(proc.alt_mode and proc.mode == PROCESS.CHARGE, PROCESS.RANGE_CONTROL, proc.mode)
|
||||
|
||||
-- facility data
|
||||
data[#db.units + 1] = {
|
||||
fac.status_lines,
|
||||
{ fac.auto_ready, fac.auto_active, fac.auto_ramping, fac.auto_saturated },
|
||||
fac.auto_scram,
|
||||
fac.ascram_status,
|
||||
{ proc.mode, proc.burn_target, proc.charge_target, proc.gen_target }
|
||||
{ mode, proc.burn_target, proc.range_start, proc.range_stop, proc.charge_target, proc.gen_target }
|
||||
}
|
||||
|
||||
_send(CRDN_TYPE.API_GET_PROC, data)
|
||||
@@ -452,7 +455,7 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout)
|
||||
-- log.debug(log_header .. "PKT RTT = " .. self.last_rtt .. "ms")
|
||||
-- log.debug(log_header .. "PKT TT = " .. (srv_now - api_send) .. "ms")
|
||||
|
||||
iocontrol.fp_pkt_rtt(id, self.last_rtt)
|
||||
ioctl.fp_pkt_rtt(id, self.last_rtt)
|
||||
else
|
||||
log.debug(log_tag .. "SCADA keep alive packet length mismatch")
|
||||
end
|
||||
|
||||
@@ -15,12 +15,12 @@ local util = require("scada-common.util")
|
||||
local backplane = require("coordinator.backplane")
|
||||
local configure = require("coordinator.configure")
|
||||
local coordinator = require("coordinator.coordinator")
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local ioctl = require("coordinator.ioctl")
|
||||
local renderer = require("coordinator.renderer")
|
||||
local sounder = require("coordinator.sounder")
|
||||
local threads = require("coordinator.threads")
|
||||
|
||||
local COORDINATOR_VERSION = "v1.7.8"
|
||||
local COORDINATOR_VERSION = "v1.8.1"
|
||||
|
||||
local CHUNK_LOAD_DELAY_S = 30.0
|
||||
|
||||
@@ -137,7 +137,7 @@ local function main()
|
||||
----------------------------------------
|
||||
|
||||
-- report versions
|
||||
iocontrol.fp_versions(COORDINATOR_VERSION, comms.version)
|
||||
ioctl.fp_versions(COORDINATOR_VERSION, comms.version)
|
||||
|
||||
-- init renderer
|
||||
renderer.configure(config)
|
||||
|
||||
@@ -6,7 +6,7 @@ local util = require("scada-common.util")
|
||||
|
||||
local backplane = require("coordinator.backplane")
|
||||
local coordinator = require("coordinator.coordinator")
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local ioctl = require("coordinator.ioctl")
|
||||
local process = require("coordinator.process")
|
||||
local renderer = require("coordinator.renderer")
|
||||
local sounder = require("coordinator.sounder")
|
||||
@@ -33,7 +33,7 @@ function threads.thread__main(smem)
|
||||
|
||||
-- execute thread
|
||||
function public.exec()
|
||||
iocontrol.fp_rt_status("main", true)
|
||||
ioctl.fp_rt_status("main", true)
|
||||
log.debug("OS: main thread start")
|
||||
|
||||
local loop_clock = util.new_clock(MAIN_CLOCK)
|
||||
@@ -51,78 +51,52 @@ function threads.thread__main(smem)
|
||||
local MQ__RENDER_CMD = smem.q_types.MQ__RENDER_CMD
|
||||
local MQ__RENDER_DATA = smem.q_types.MQ__RENDER_DATA
|
||||
|
||||
-- main loop periodic tasks
|
||||
---@return boolean exit if the application should exit
|
||||
local function loop_tick()
|
||||
-- toggle heartbeat
|
||||
ioctl.heartbeat()
|
||||
|
||||
-- periodic hardware tasks
|
||||
backplane.periodic()
|
||||
|
||||
-- maintain connection
|
||||
local ok, start_ui = coord_comms.manage_link()
|
||||
if not ok then
|
||||
crd_state.link_fail = true
|
||||
crd_state.shutdown = true
|
||||
log_sys("supervisor connection failed, shutting down...")
|
||||
log.fatal("failed to connect to supervisor")
|
||||
return true
|
||||
elseif start_ui then
|
||||
log_sys("supervisor connected, dispatching main UI start")
|
||||
smem.q.mq_render.push_command(MQ__RENDER_CMD.START_MAIN_UI)
|
||||
end
|
||||
|
||||
-- iterate sessions and free any closed ones
|
||||
apisessions.iterate_all()
|
||||
apisessions.free_all_closed()
|
||||
|
||||
-- clear timed out process commands
|
||||
process.clear_timed_out()
|
||||
|
||||
if renderer.ui_ready() then
|
||||
-- update clock used on main and flow monitors
|
||||
ioctl.get_db().facility.ps.publish("date_time", os.date(smem.date_format))
|
||||
end
|
||||
|
||||
-- start next clock timer
|
||||
loop_clock.start()
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- event loop
|
||||
while true do
|
||||
local event, param1, param2, param3, param4, param5 = util.pull_event()
|
||||
|
||||
-- handle event
|
||||
if event == "peripheral_detach" then
|
||||
local type, device = ppm.handle_unmount(param1)
|
||||
if type ~= nil and device ~= nil then
|
||||
backplane.detach(type, device, param1)
|
||||
end
|
||||
elseif event == "peripheral" then
|
||||
local type, device = ppm.mount(param1)
|
||||
if type ~= nil and device ~= nil then
|
||||
backplane.attach(type, device, param1)
|
||||
end
|
||||
elseif event == "monitor_resize" then
|
||||
smem.q.mq_render.push_data(MQ__RENDER_DATA.MON_RESIZE, param1)
|
||||
elseif event == "timer" then
|
||||
if loop_clock.is_clock(param1) then
|
||||
-- main loop tick
|
||||
|
||||
-- toggle heartbeat
|
||||
iocontrol.heartbeat()
|
||||
|
||||
-- periodic hardware tasks
|
||||
backplane.periodic()
|
||||
|
||||
-- maintain connection
|
||||
local ok, start_ui = coord_comms.manage_link()
|
||||
if not ok then
|
||||
crd_state.link_fail = true
|
||||
crd_state.shutdown = true
|
||||
log_sys("supervisor connection failed, shutting down...")
|
||||
log.fatal("failed to connect to supervisor")
|
||||
break
|
||||
elseif start_ui then
|
||||
log_sys("supervisor connected, dispatching main UI start")
|
||||
smem.q.mq_render.push_command(MQ__RENDER_CMD.START_MAIN_UI)
|
||||
end
|
||||
|
||||
-- iterate sessions and free any closed ones
|
||||
apisessions.iterate_all()
|
||||
apisessions.free_all_closed()
|
||||
|
||||
-- clear timed out process commands
|
||||
process.clear_timed_out()
|
||||
|
||||
if renderer.ui_ready() then
|
||||
-- update clock used on main and flow monitors
|
||||
iocontrol.get_db().facility.ps.publish("date_time", os.date(smem.date_format))
|
||||
end
|
||||
|
||||
-- start next clock timer
|
||||
loop_clock.start()
|
||||
elseif conn_watchdog.is_timer(param1) then
|
||||
-- supervisor watchdog timeout
|
||||
log_comms("supervisor server timeout")
|
||||
|
||||
-- close main UI, connection, and stop sounder
|
||||
smem.q.mq_render.push_command(MQ__RENDER_CMD.CLOSE_MAIN_UI)
|
||||
coord_comms.close()
|
||||
sounder.stop()
|
||||
else
|
||||
-- a non-clock/main watchdog timer event
|
||||
|
||||
-- check API watchdogs
|
||||
apisessions.check_all_watchdogs(param1)
|
||||
|
||||
-- notify timer callback dispatcher
|
||||
tcd.handle(param1)
|
||||
end
|
||||
elseif event == "modem_message" then
|
||||
if event == "modem_message" then
|
||||
-- got a packet
|
||||
local packet = coord_comms.parse_packet(param1, param2, param3, param4, param5)
|
||||
|
||||
@@ -135,13 +109,42 @@ function threads.thread__main(smem)
|
||||
coord_comms.close()
|
||||
sounder.stop()
|
||||
end
|
||||
elseif event == "timer" then
|
||||
-- pass this timer event onto the right handler
|
||||
if loop_clock.is_clock(param1) then
|
||||
-- main loop tick
|
||||
if loop_tick() then break end
|
||||
elseif conn_watchdog.is_timer(param1) then
|
||||
-- supervisor connection timed out
|
||||
log_comms("supervisor server timeout")
|
||||
|
||||
-- close main UI, connection, and stop sounder
|
||||
smem.q.mq_render.push_command(MQ__RENDER_CMD.CLOSE_MAIN_UI)
|
||||
coord_comms.close()
|
||||
sounder.stop()
|
||||
elseif not apisessions.check_all_watchdogs(param1) then -- check API watchdogs
|
||||
-- notify timer callback dispatcher, no other handler claimed this event
|
||||
tcd.handle(param1)
|
||||
end
|
||||
elseif event == "speaker_audio_empty" then
|
||||
-- handle speaker buffer emptied
|
||||
sounder.continue()
|
||||
elseif event == "monitor_touch" or event == "mouse_click" or event == "mouse_up" or
|
||||
event == "mouse_drag" or event == "mouse_scroll" or event == "double_click" then
|
||||
-- handle a mouse event
|
||||
renderer.handle_mouse(core.events.new_mouse_event(event, param1, param2, param3))
|
||||
elseif event == "speaker_audio_empty" then
|
||||
-- handle speaker buffer emptied
|
||||
sounder.continue()
|
||||
elseif event == "monitor_resize" then
|
||||
smem.q.mq_render.push_data(MQ__RENDER_DATA.MON_RESIZE, param1)
|
||||
elseif event == "peripheral" then
|
||||
local type, device = ppm.mount(param1)
|
||||
if type ~= nil and device ~= nil then
|
||||
backplane.attach(type, device, param1)
|
||||
end
|
||||
elseif event == "peripheral_detach" then
|
||||
local type, device = ppm.handle_unmount(param1)
|
||||
if type ~= nil and device ~= nil then
|
||||
backplane.detach(type, device, param1)
|
||||
end
|
||||
end
|
||||
|
||||
-- check for termination request or UI crash
|
||||
@@ -183,7 +186,7 @@ function threads.thread__main(smem)
|
||||
log.fatal(util.strval(result))
|
||||
end
|
||||
|
||||
iocontrol.fp_rt_status("main", false)
|
||||
ioctl.fp_rt_status("main", false)
|
||||
|
||||
-- if status is true, then we are probably exiting, so this won't matter
|
||||
-- this thread cannot be slept because it will miss events (namely "terminate")
|
||||
@@ -205,7 +208,7 @@ function threads.thread__render(smem)
|
||||
|
||||
-- execute thread
|
||||
function public.exec()
|
||||
iocontrol.fp_rt_status("render", true)
|
||||
ioctl.fp_rt_status("render", true)
|
||||
log.debug("OS: render thread start")
|
||||
|
||||
-- load in from shared memory
|
||||
@@ -300,7 +303,7 @@ function threads.thread__render(smem)
|
||||
log.fatal(util.strval(result))
|
||||
end
|
||||
|
||||
iocontrol.fp_rt_status("render", false)
|
||||
ioctl.fp_rt_status("render", false)
|
||||
|
||||
if not crd_state.shutdown then
|
||||
log.info("OS: render thread restarting in 5 seconds...")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local ioctl = require("coordinator.ioctl")
|
||||
|
||||
local style = require("coordinator.ui.style")
|
||||
|
||||
@@ -23,7 +23,7 @@ local function new_view(root, x, y, ps)
|
||||
local text_fg = style.theme.text_fg
|
||||
local lu_col = style.lu_colors
|
||||
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local boiler = Rectangle{parent=root,border=border(1,colors.gray,true),width=31,height=7,x=x,y=y}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local ioctl = require("coordinator.ioctl")
|
||||
|
||||
local style = require("coordinator.ui.style")
|
||||
|
||||
@@ -35,7 +35,7 @@ local function new_view(root, x, y, ps, id)
|
||||
local ind_yel = style.ind_yel
|
||||
local ind_wht = style.ind_wht
|
||||
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local title = "INDUCTION MATRIX"
|
||||
if type(id) == "number" then title = title .. id end
|
||||
@@ -45,10 +45,10 @@ local function new_view(root, x, y, ps, id)
|
||||
-- black has low contrast with dark gray, so if background is black use white instead
|
||||
local cutout_fg_bg = cpair(util.trinary(style.theme.bg == colors.black, colors.white, style.theme.bg), colors.gray)
|
||||
|
||||
TextBox{parent=matrix,text=" ",width=33,x=1,y=1,fg_bg=cutout_fg_bg}
|
||||
TextBox{parent=matrix,text=title,alignment=ALIGN.CENTER,width=33,x=1,y=2,fg_bg=cutout_fg_bg}
|
||||
TextBox{parent=matrix,text=" ",width=33,y=1,fg_bg=cutout_fg_bg}
|
||||
TextBox{parent=matrix,text=title,alignment=ALIGN.CENTER,width=33,y=2,fg_bg=cutout_fg_bg}
|
||||
|
||||
local rect = Rectangle{parent=matrix,border=border(1,colors.gray,true),width=33,height=22,x=1,y=3}
|
||||
local rect = Rectangle{parent=matrix,border=border(1,colors.gray,true),width=33,height=22,y=3}
|
||||
|
||||
local status = StateIndicator{parent=rect,x=10,y=1,states=style.imatrix.states,value=1,min_width=14}
|
||||
local capacity = PowerIndicator{parent=rect,x=7,y=3,lu_colors=lu_col,label="Capacity:",unit=db.energy_label,format="%8.2f",value=0,width=26,fg_bg=text_fg}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
-- Pocket Connection Entry
|
||||
--
|
||||
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local ioctl = require("coordinator.ioctl")
|
||||
|
||||
local style = require("coordinator.ui.style")
|
||||
|
||||
@@ -26,7 +26,7 @@ local function init(parent, id)
|
||||
|
||||
local label_fg = style.fp.label_fg
|
||||
|
||||
local ps = iocontrol.get_db().fp.ps
|
||||
local ps = ioctl.get_db().fp.ps
|
||||
|
||||
local term_w, _ = term.getSize()
|
||||
|
||||
@@ -36,9 +36,9 @@ local function init(parent, id)
|
||||
|
||||
local ps_prefix = "pkt_" .. id .. "_"
|
||||
|
||||
TextBox{parent=entry,x=1,y=1,text="",width=8,fg_bg=s_hi_box}
|
||||
local pkt_addr = TextBox{parent=entry,x=1,y=2,text="@ C ??",alignment=ALIGN.CENTER,width=8,fg_bg=s_hi_box,nav_active=cpair(colors.gray,colors.black)}
|
||||
TextBox{parent=entry,x=1,y=3,text="",width=8,fg_bg=s_hi_box}
|
||||
TextBox{parent=entry,y=1,text="",width=8,fg_bg=s_hi_box}
|
||||
local pkt_addr = TextBox{parent=entry,y=2,text="@ C ??",alignment=ALIGN.CENTER,width=8,fg_bg=s_hi_box,nav_active=cpair(colors.gray,colors.black)}
|
||||
TextBox{parent=entry,y=3,text="",width=8,fg_bg=s_hi_box}
|
||||
pkt_addr.register(ps, ps_prefix .. "addr", pkt_addr.set_value)
|
||||
|
||||
TextBox{parent=entry,x=10,y=2,text="FW:",width=3}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
local tcd = require("scada-common.tcd")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local ioctl = require("coordinator.ioctl")
|
||||
local process = require("coordinator.process")
|
||||
|
||||
local style = require("coordinator.ui.style")
|
||||
@@ -22,6 +22,7 @@ local Checkbox = require("graphics.elements.controls.Checkbox")
|
||||
local HazardButton = require("graphics.elements.controls.HazardButton")
|
||||
local NumericSpinbox = require("graphics.elements.controls.NumericSpinbox")
|
||||
local RadioButton = require("graphics.elements.controls.RadioButton")
|
||||
local SwitchButton = require("graphics.elements.controls.SwitchButton")
|
||||
|
||||
local ALIGN = core.ALIGN
|
||||
|
||||
@@ -56,14 +57,14 @@ local function new_view(root, x, y)
|
||||
local blk_brn = cpair(colors.black, colors.brown)
|
||||
local blk_pur = cpair(colors.black, colors.purple)
|
||||
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local facility = db.facility
|
||||
local units = db.units
|
||||
|
||||
local main = Div{parent=root,width=128,height=24,x=x,y=y}
|
||||
|
||||
local scram = HazardButton{parent=main,x=1,y=1,text="FAC SCRAM",accent=colors.yellow,dis_colors=dis_colors,callback=db.process.fac_scram,fg_bg=hzd_fg_bg}
|
||||
local scram = HazardButton{parent=main,y=1,text="FAC SCRAM",accent=colors.yellow,dis_colors=dis_colors,callback=db.process.fac_scram,fg_bg=hzd_fg_bg}
|
||||
local ack_a = HazardButton{parent=main,x=16,y=1,text="ACK \x13",accent=colors.orange,dis_colors=dis_colors,callback=db.process.fac_ack_alarms,fg_bg=hzd_fg_bg}
|
||||
|
||||
db.process.fac_ack.on_scram = scram.on_response
|
||||
@@ -125,9 +126,9 @@ local function new_view(root, x, y)
|
||||
-- process control targets --
|
||||
-----------------------------
|
||||
|
||||
local targets = Div{parent=proc,width=31,height=24,x=1,y=1}
|
||||
local targets = Div{parent=proc,width=31,height=24,y=1}
|
||||
|
||||
local burn_tag = Div{parent=targets,x=1,y=1,width=8,height=4,fg_bg=blk_pur}
|
||||
local burn_tag = Div{parent=targets,y=1,width=8,height=4,fg_bg=blk_pur}
|
||||
TextBox{parent=burn_tag,x=2,y=2,text="Burn Target",width=7,height=2}
|
||||
|
||||
local burn_target = Div{parent=targets,x=9,y=1,width=23,height=3,fg_bg=s_hi_box}
|
||||
@@ -138,18 +139,47 @@ local function new_view(root, x, y)
|
||||
b_target.register(facility.ps, "process_burn_target", b_target.set_value)
|
||||
burn_sum.register(facility.ps, "burn_sum", burn_sum.update)
|
||||
|
||||
local chg_tag = Div{parent=targets,x=1,y=6,width=8,height=4,fg_bg=blk_pur}
|
||||
TextBox{parent=chg_tag,x=2,y=2,text="Charge Target",width=7,height=2}
|
||||
local chg_tag = Div{parent=targets,y=6,width=8,height=4,fg_bg=blk_pur}
|
||||
local chg_tag_text = TextBox{parent=chg_tag,x=2,y=2,text="Charge Target",width=7,height=2}
|
||||
|
||||
local chg_target = Div{parent=targets,x=9,y=6,width=23,height=3,fg_bg=s_hi_box}
|
||||
local c_target = NumericSpinbox{parent=chg_target,x=2,y=1,whole_num_precision=15,fractional_precision=0,min=0,arrow_fg_bg=arrow_fg_bg,arrow_disable=style.theme.disabled}
|
||||
TextBox{parent=chg_target,x=18,y=2,text="M"..db.energy_label,fg_bg=style.theme.label_fg}
|
||||
local cur_charge = DataIndicator{parent=targets,x=9,y=9,label="",format="%19d",value=0,unit="M"..db.energy_label,commas=true,lu_colors=black,width=23,fg_bg=blk_brn}
|
||||
|
||||
local range_start, range_stop ---@type NumericSpinbox, NumericSpinbox
|
||||
|
||||
local function _update_start_val(value) range_start.set_value(math.min(range_start.get_value(), value - 1)) end
|
||||
local function _update_stop_val(value) range_stop.set_value(math.max(range_stop.get_value(), value + 1)) end
|
||||
|
||||
local chg_range = Div{parent=targets,x=9,y=6,width=23,height=3,fg_bg=s_hi_box,hidden=true}
|
||||
TextBox{parent=chg_range,x=2,y=2,text="START",fg_bg=style.theme.label_fg}
|
||||
range_start = NumericSpinbox{parent=chg_range,x=8,y=1,whole_num_precision=3,fractional_precision=0,min=0,max=99,callback=_update_stop_val,arrow_fg_bg=arrow_fg_bg,arrow_disable=style.theme.disabled}
|
||||
TextBox{parent=chg_range,x=11,y=2,text="% \x1a STOP",fg_bg=style.theme.label_fg}
|
||||
range_stop = NumericSpinbox{parent=chg_range,x=20,y=1,whole_num_precision=3,fractional_precision=0,min=1,max=100,callback=_update_start_val,arrow_fg_bg=arrow_fg_bg,arrow_disable=style.theme.disabled}
|
||||
TextBox{parent=chg_range,x=23,y=2,text="%",fg_bg=style.theme.label_fg}
|
||||
|
||||
local cur_charge = DataIndicator{parent=targets,x=11,y=9,label="",format="%17d",value=0,unit="M"..db.energy_label,commas=true,lu_colors=black,width=23,fg_bg=blk_brn}
|
||||
local chg_mode = SwitchButton{parent=targets,x=9,y=9,text="\x12T",active_text="\x12R",callback=function(v)facility.ps.publish("process_alt_mode", v)end,fg_bg=cpair(colors.black,colors.pink),dis_fg_bg=dis_colors}
|
||||
|
||||
c_target.register(facility.ps, "process_charge_target", c_target.set_value)
|
||||
range_start.register(facility.ps, "process_range_start", range_start.set_value)
|
||||
range_stop.register(facility.ps, "process_range_stop", range_stop.set_value)
|
||||
cur_charge.register(facility.induction_ps_tbl[1], "avg_charge", function (fe) cur_charge.update(db.energy_convert_from_fe(fe) / 1000000) end)
|
||||
chg_mode.register(facility.ps, "process_alt_mode", chg_mode.set_value)
|
||||
|
||||
local gen_tag = Div{parent=targets,x=1,y=11,width=8,height=4,fg_bg=blk_pur}
|
||||
targets.register(facility.ps, "process_alt_mode", function (alt)
|
||||
if alt then
|
||||
chg_target.hide()
|
||||
chg_range.show()
|
||||
chg_tag_text.set_value("Charge Range")
|
||||
else
|
||||
chg_target.show()
|
||||
chg_range.hide()
|
||||
chg_tag_text.set_value("Charge Target")
|
||||
end
|
||||
end)
|
||||
|
||||
local gen_tag = Div{parent=targets,y=11,width=8,height=4,fg_bg=blk_pur}
|
||||
TextBox{parent=gen_tag,x=2,y=2,text="Gen. Target",width=7,height=2}
|
||||
|
||||
local gen_target = Div{parent=targets,x=9,y=11,width=23,height=3,fg_bg=s_hi_box}
|
||||
@@ -187,7 +217,7 @@ local function new_view(root, x, y)
|
||||
|
||||
local _y = ((i - 1) * 5) + 1
|
||||
|
||||
local unit_tag = Div{parent=limit_div,x=1,y=_y,width=8,height=4,fg_bg=tag_fg_bg}
|
||||
local unit_tag = Div{parent=limit_div,y=_y,width=8,height=4,fg_bg=tag_fg_bg}
|
||||
TextBox{parent=unit_tag,x=2,y=2,text="Unit "..i.." Limit",width=7,height=2}
|
||||
|
||||
local lim_ctl = Div{parent=limit_div,x=9,y=_y,width=14,height=3,fg_bg=s_hi_box}
|
||||
@@ -226,7 +256,7 @@ local function new_view(root, x, y)
|
||||
|
||||
local _y = ((i - 1) * 5) + 1
|
||||
|
||||
local unit_tag = Div{parent=stat_div,x=1,y=_y,width=8,height=4,fg_bg=tag_fg_bg}
|
||||
local unit_tag = Div{parent=stat_div,y=_y,width=8,height=4,fg_bg=tag_fg_bg}
|
||||
TextBox{parent=unit_tag,x=2,y=2,text="Unit "..i.." Status",width=7,height=2}
|
||||
|
||||
local lights = Div{parent=stat_div,x=9,y=_y,width=14,height=4,fg_bg=ind_fg_bg}
|
||||
@@ -246,26 +276,48 @@ local function new_view(root, x, y)
|
||||
-------------------------
|
||||
|
||||
local ctl_opts = { "Monitored Max Burn", "Combined Burn Rate", "Charge Level", "Generation Rate" }
|
||||
local alt_opts = { "Monitored Max Burn", "Combined Burn Rate", "Charge Range", "Generation Rate" }
|
||||
local mode = RadioButton{parent=proc,x=34,y=1,options=ctl_opts,radio_colors=cpair(style.theme.accent_dark,style.theme.accent_light),select_color=colors.purple}
|
||||
local alt_mode = RadioButton{parent=proc,x=34,y=1,options=alt_opts,radio_colors=cpair(style.theme.accent_dark,style.theme.accent_light),select_color=colors.purple,callback=function(v)mode.set_value(v)end,hidden=true}
|
||||
|
||||
mode.register(facility.ps, "process_mode", mode.set_value)
|
||||
alt_mode.register(facility.ps, "process_mode", alt_mode.set_value)
|
||||
|
||||
local u_stat = Rectangle{parent=proc,border=border(1,colors.gray,true),thin=true,width=31,height=4,x=1,y=16,fg_bg=bw_fg_bg}
|
||||
local stat_line_1 = TextBox{parent=u_stat,x=1,y=1,text="UNKNOWN",width=31,alignment=ALIGN.CENTER,fg_bg=bw_fg_bg}
|
||||
local stat_line_2 = TextBox{parent=u_stat,x=1,y=2,text="awaiting data...",width=31,alignment=ALIGN.CENTER,fg_bg=cpair(colors.gray,colors.white)}
|
||||
proc.register(facility.ps, "process_alt_mode", function (alt)
|
||||
if alt then
|
||||
alt_mode.set_value(mode.get_value())
|
||||
mode.hide()
|
||||
alt_mode.show()
|
||||
chg_tag_text.set_value("Charge Range")
|
||||
else
|
||||
mode.set_value(alt_mode.get_value())
|
||||
alt_mode.hide()
|
||||
mode.show()
|
||||
chg_tag_text.set_value("Charge Target")
|
||||
end
|
||||
end)
|
||||
|
||||
local u_stat = Rectangle{parent=proc,border=border(1,colors.gray,true),thin=true,width=31,height=4,y=16,fg_bg=bw_fg_bg}
|
||||
local stat_line_1 = TextBox{parent=u_stat,y=1,text="UNKNOWN",width=31,alignment=ALIGN.CENTER,fg_bg=bw_fg_bg}
|
||||
local stat_line_2 = TextBox{parent=u_stat,y=2,text="awaiting data...",width=31,alignment=ALIGN.CENTER,fg_bg=cpair(colors.gray,colors.white)}
|
||||
|
||||
stat_line_1.register(facility.ps, "status_line_1", stat_line_1.set_value)
|
||||
stat_line_2.register(facility.ps, "status_line_2", stat_line_2.set_value)
|
||||
|
||||
local auto_controls = Div{parent=proc,x=1,y=20,width=31,height=5,fg_bg=s_hi_box}
|
||||
local auto_controls = Div{parent=proc,y=20,width=31,height=5,fg_bg=s_hi_box}
|
||||
|
||||
-- save the automatic process control configuration without starting
|
||||
local function _save_cfg()
|
||||
local limits = {}
|
||||
for i = 1, #rate_limits do limits[i] = rate_limits[i].get_value() end
|
||||
|
||||
process.save(mode.get_value(), b_target.get_value(), db.energy_convert_to_fe(c_target.get_value()),
|
||||
db.energy_convert_to_fe(g_target.get_value()), limits)
|
||||
-- make sure stop is always above start (start maxes at 99 and stop maxes at 100 so this always works)
|
||||
if range_stop.get_value() <= range_start.get_value() then
|
||||
range_stop.set_value(range_start.get_value() + 1)
|
||||
end
|
||||
|
||||
process.save(mode.get_value(), chg_mode.get_value(), b_target.get_value(), range_start.get_value(), range_stop.get_value(),
|
||||
db.energy_convert_to_fe(c_target.get_value()), db.energy_convert_to_fe(g_target.get_value()), limits)
|
||||
end
|
||||
|
||||
-- start automatic control after saving process control settings
|
||||
@@ -296,18 +348,26 @@ local function new_view(root, x, y)
|
||||
if active then
|
||||
b_target.disable()
|
||||
c_target.disable()
|
||||
range_start.disable()
|
||||
range_stop.disable()
|
||||
g_target.disable()
|
||||
|
||||
mode.disable()
|
||||
alt_mode.disable()
|
||||
chg_mode.disable()
|
||||
start.disable()
|
||||
|
||||
for i = 1, #rate_limits do rate_limits[i].disable() end
|
||||
else
|
||||
b_target.enable()
|
||||
c_target.enable()
|
||||
range_start.enable()
|
||||
range_stop.enable()
|
||||
g_target.enable()
|
||||
|
||||
mode.enable()
|
||||
alt_mode.enable()
|
||||
chg_mode.enable()
|
||||
if facility.auto_ready then start.enable() end
|
||||
|
||||
for i = 1, #rate_limits do rate_limits[i].enable() end
|
||||
@@ -335,10 +395,10 @@ local function new_view(root, x, y)
|
||||
|
||||
local cutout_fg_bg = cpair(style.theme.bg, colors.brown)
|
||||
|
||||
TextBox{parent=waste_sel,text=" ",width=21,x=1,y=1,fg_bg=cutout_fg_bg}
|
||||
TextBox{parent=waste_sel,text="WASTE PRODUCTION",alignment=ALIGN.CENTER,width=21,x=1,y=2,fg_bg=cutout_fg_bg}
|
||||
TextBox{parent=waste_sel,text=" ",width=21,y=1,fg_bg=cutout_fg_bg}
|
||||
TextBox{parent=waste_sel,text="WASTE PRODUCTION",alignment=ALIGN.CENTER,width=21,y=2,fg_bg=cutout_fg_bg}
|
||||
|
||||
local rect = Rectangle{parent=waste_sel,border=border(1,colors.brown,true),width=21,height=22,x=1,y=3}
|
||||
local rect = Rectangle{parent=waste_sel,border=border(1,colors.brown,true),width=21,height=22,y=3}
|
||||
local status = StateIndicator{parent=rect,x=2,y=1,states=style.get_waste().states,value=1,min_width=17}
|
||||
|
||||
status.register(facility.ps, "current_waste_product", status.update)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
local types = require("scada-common.types")
|
||||
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local ioctl = require("coordinator.ioctl")
|
||||
|
||||
local style = require("coordinator.ui.style")
|
||||
|
||||
@@ -25,7 +25,7 @@ local function new_view(root, x, y, ps)
|
||||
local text_fg = style.theme.text_fg
|
||||
local lu_col = style.lu_colors
|
||||
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local reactor = Rectangle{parent=root,border=border(1,colors.gray,true),width=30,height=7,x=x,y=y}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local ioctl = require("coordinator.ioctl")
|
||||
|
||||
local style = require("coordinator.ui.style")
|
||||
|
||||
@@ -24,7 +24,7 @@ local function new_view(root, x, y, ps)
|
||||
local text_fg = style.theme.text_fg
|
||||
local lu_col = style.lu_colors
|
||||
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local turbine = Rectangle{parent=root,border=border(1,colors.gray,true),width=23,height=7,x=x,y=y}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
local types = require("scada-common.types")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local ioctl = require("coordinator.ioctl")
|
||||
|
||||
local style = require("coordinator.ui.style")
|
||||
|
||||
@@ -61,11 +61,11 @@ local function init(parent, id)
|
||||
local ind_red = style.ind_red
|
||||
local ind_wht = style.ind_wht
|
||||
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
local unit = db.units[id]
|
||||
local f_ps = db.facility.ps
|
||||
|
||||
local main = Div{parent=parent,x=1,y=1}
|
||||
local main = Div{parent=parent,y=1}
|
||||
|
||||
if unit == nil then return main end
|
||||
|
||||
@@ -146,8 +146,8 @@ local function init(parent, id)
|
||||
-------------------
|
||||
|
||||
local u_stat = Rectangle{parent=main,border=border(1,colors.gray,true),thin=true,width=33,height=4,x=46,y=3,fg_bg=bw_fg_bg}
|
||||
local stat_line_1 = TextBox{parent=u_stat,x=1,y=1,text="UNKNOWN",width=33,alignment=ALIGN.CENTER,fg_bg=bw_fg_bg}
|
||||
local stat_line_2 = TextBox{parent=u_stat,x=1,y=2,text="awaiting data...",width=33,alignment=ALIGN.CENTER,fg_bg=gry_wht}
|
||||
local stat_line_1 = TextBox{parent=u_stat,y=1,text="UNKNOWN",width=33,alignment=ALIGN.CENTER,fg_bg=bw_fg_bg}
|
||||
local stat_line_2 = TextBox{parent=u_stat,y=2,text="awaiting data...",width=33,alignment=ALIGN.CENTER,fg_bg=gry_wht}
|
||||
|
||||
stat_line_1.register(u_ps, "U_StatusLine1", stat_line_1.set_value)
|
||||
stat_line_2.register(u_ps, "U_StatusLine2", stat_line_2.set_value)
|
||||
@@ -238,7 +238,7 @@ local function init(parent, id)
|
||||
TextBox{parent=main,text="REACTOR COOLANT SYSTEM",fg_bg=cpair(colors.black,colors.blue),alignment=ALIGN.CENTER,width=33,x=46,y=22}
|
||||
local rcs = Rectangle{parent=main,border=border(1,colors.blue,true),thin=true,width=33,height=24,x=46,y=23}
|
||||
local rcs_annunc = Div{parent=rcs,width=27,height=22,x=3,y=1}
|
||||
local rcs_tags = Div{parent=rcs,width=2,height=16,x=1,y=7}
|
||||
local rcs_tags = Div{parent=rcs,width=2,height=16,y=7}
|
||||
|
||||
local c_flt = IndicatorLight{parent=rcs_annunc,label="RCS Hardware Fault",colors=ind_yel}
|
||||
local c_emg = TriIndicatorLight{parent=rcs_annunc,label="Emergency Coolant",c1=ind_bkg,c2=ind_wht.fgd,c3=ind_grn.fgd}
|
||||
@@ -267,7 +267,7 @@ local function init(parent, id)
|
||||
if unit.num_boilers > 0 then
|
||||
if available_space > 0 then _add_space() end
|
||||
|
||||
TextBox{parent=rcs_tags,x=1,text="B1",width=2,fg_bg=hc_text}
|
||||
TextBox{parent=rcs_tags,text="B1",width=2,fg_bg=hc_text}
|
||||
local b1_wll = IndicatorLight{parent=rcs_annunc,label="Water Level Low",colors=ind_red}
|
||||
b1_wll.register(b_ps[1], "WaterLevelLow", b1_wll.update)
|
||||
|
||||
@@ -398,7 +398,7 @@ local function init(parent, id)
|
||||
local waste_proc = Rectangle{parent=main,border=border(1,colors.brown,true),thin=true,width=33,height=3,x=46,y=49}
|
||||
local waste_div = Div{parent=waste_proc,x=2,y=1,width=31,height=1}
|
||||
|
||||
local waste_mode = MultiButton{parent=waste_div,x=1,y=1,options=style.get_waste().unit_opts,callback=unit.set_waste,min_width=6}
|
||||
local waste_mode = MultiButton{parent=waste_div,y=1,options=style.get_waste().unit_opts,callback=unit.set_waste,min_width=6}
|
||||
|
||||
waste_mode.register(u_ps, "U_WasteMode", waste_mode.set_value)
|
||||
|
||||
@@ -484,7 +484,7 @@ local function init(parent, id)
|
||||
|
||||
TextBox{parent=main,text="AUTO CTRL",fg_bg=cpair(colors.black,colors.purple),alignment=ALIGN.CENTER,width=13,x=32,y=36}
|
||||
local auto_ctl = Rectangle{parent=main,border=border(1,colors.purple,true),thin=true,width=13,height=15,x=32,y=37}
|
||||
local auto_div = Div{parent=auto_ctl,width=13,height=15,x=1,y=1}
|
||||
local auto_div = Div{parent=auto_ctl,width=13,height=15,y=1}
|
||||
|
||||
local group = RadioButton{parent=auto_div,options=types.AUTO_GROUP_NAMES,radio_colors=cpair(style.theme.accent_dark,style.theme.accent_light),select_color=colors.purple}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
local types = require("scada-common.types")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local ioctl = require("coordinator.ioctl")
|
||||
|
||||
local style = require("coordinator.ui.style")
|
||||
|
||||
@@ -53,11 +53,11 @@ local function make(parent, x, y, wide, unit_id)
|
||||
|
||||
local height = 16
|
||||
|
||||
local facility = iocontrol.get_db().facility
|
||||
local unit = iocontrol.get_db().units[unit_id]
|
||||
local fac = ioctl.get_db().facility
|
||||
local unit = ioctl.get_db().units[unit_id]
|
||||
|
||||
local tank_conns = facility.tank_conns
|
||||
local tank_types = facility.tank_fluid_types
|
||||
local tank_conns = fac.tank_conns
|
||||
local tank_types = fac.tank_fluid_types
|
||||
|
||||
local v_start = 1 + ((unit.unit_id - 1) * 6)
|
||||
local prv_start = 1 + ((unit.unit_id - 1) * 3)
|
||||
@@ -83,7 +83,7 @@ local function make(parent, x, y, wide, unit_id)
|
||||
-- COOLING LOOP --
|
||||
------------------
|
||||
|
||||
local reactor = Rectangle{parent=root,x=1,y=1,border=border(1,colors.gray,true),width=19,height=5,fg_bg=wh_gray}
|
||||
local reactor = Rectangle{parent=root,y=1,border=border(1,colors.gray,true),width=19,height=5,fg_bg=wh_gray}
|
||||
TextBox{parent=reactor,y=1,text="FISSION REACTOR",alignment=ALIGN.CENTER}
|
||||
TextBox{parent=reactor,y=3,text="UNIT #"..unit.unit_id,alignment=ALIGN.CENTER}
|
||||
TextBox{parent=root,x=19,y=2,text="\x1b \x80 \x1a",width=1,height=3,fg_bg=lg_gray}
|
||||
@@ -98,7 +98,7 @@ local function make(parent, x, y, wide, unit_id)
|
||||
table.insert(rc_pipes, pipe(_wide(46, 39), 3, _wide(72, 58), 3, colors.white, true))
|
||||
|
||||
if unit.aux_coolant then
|
||||
local em_water = facility.tank_fluid_types[facility.tank_conns[unit_id]] == COOLANT_TYPE.WATER
|
||||
local em_water = fac.tank_fluid_types[fac.tank_conns[unit_id]] == COOLANT_TYPE.WATER
|
||||
local offset = util.trinary(unit.has_tank and em_water, 3, 0)
|
||||
table.insert(rc_pipes, pipe(_wide(51, 41) + offset, 0, _wide(51, 41) + offset, 0, colors.blue, true))
|
||||
end
|
||||
@@ -191,7 +191,7 @@ local function make(parent, x, y, wide, unit_id)
|
||||
pipe(_wide(132, 110), 6, _wide(130, 108), 6, waste_c, true, true)
|
||||
}
|
||||
|
||||
PipeNetwork{parent=waste,x=1,y=1,pipes=waste_pipes,bg=style.theme.bg}
|
||||
PipeNetwork{parent=waste,y=1,pipes=waste_pipes,bg=style.theme.bg}
|
||||
|
||||
local function _valve(vx, vy, n)
|
||||
TextBox{parent=waste,x=vx,y=vy,text="\x10\x11",fg_bg=text_c,width=2}
|
||||
@@ -207,7 +207,7 @@ local function make(parent, x, y, wide, unit_id)
|
||||
TextBox{parent=waste,x=mx,y=my+1,text=name,alignment=ALIGN.CENTER,fg_bg=style.theme.header,width=l}
|
||||
end
|
||||
|
||||
local waste_rate = DataIndicator{parent=waste,x=1,y=3,lu_colors=lu_c,label="",unit="mB/t",format="%7.2f",value=0,width=12,fg_bg=s_field}
|
||||
local waste_rate = DataIndicator{parent=waste,y=3,lu_colors=lu_c,label="",unit="mB/t",format="%7.2f",value=0,width=12,fg_bg=s_field}
|
||||
local pu_rate = DataIndicator{parent=waste,x=_wide(82,70),y=3,lu_colors=lu_c,label="",unit="mB/t",format="%7.3f",value=0,width=12,fg_bg=s_field}
|
||||
local po_rate = DataIndicator{parent=waste,x=_wide(52,45),y=6,lu_colors=lu_c,label="",unit="mB/t",format="%7.2f",value=0,width=12,fg_bg=s_field}
|
||||
local popl_rate = DataIndicator{parent=waste,x=_wide(82,70),y=6,lu_colors=lu_c,label="",unit="mB/t",format="%7.2f",value=0,width=12,fg_bg=s_field}
|
||||
|
||||
@@ -22,7 +22,7 @@ local pipe = core.pipe
|
||||
---@param parent Container parent
|
||||
---@param x integer top left x
|
||||
---@param y integer top left y
|
||||
---@param unit ioctl_unit unit database entry
|
||||
---@param unit crd_io_unit unit database entry
|
||||
local function make(parent, x, y, unit)
|
||||
local num_boilers = #unit.boiler_data_tbl
|
||||
local num_turbines = #unit.turbine_data_tbl
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
local types = require("scada-common.types")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local ioctl = require("coordinator.ioctl")
|
||||
|
||||
local style = require("coordinator.ui.style")
|
||||
|
||||
@@ -43,20 +43,20 @@ local function init(main)
|
||||
local lu_col = style.lu_colors
|
||||
local lu_c_d = style.lu_colors_dark
|
||||
|
||||
local facility = iocontrol.get_db().facility
|
||||
local units = iocontrol.get_db().units
|
||||
local fac = ioctl.get_db().facility
|
||||
local units = ioctl.get_db().units
|
||||
|
||||
local tank_defs = facility.tank_defs
|
||||
local tank_conns = facility.tank_conns
|
||||
local tank_list = facility.tank_list
|
||||
local tank_types = facility.tank_fluid_types
|
||||
local tank_defs = fac.tank_defs
|
||||
local tank_conns = fac.tank_conns
|
||||
local tank_list = fac.tank_list
|
||||
local tank_types = fac.tank_fluid_types
|
||||
|
||||
-- window header message
|
||||
local header = TextBox{parent=main,y=1,text="Facility Coolant and Waste Flow Monitor",alignment=ALIGN.CENTER,fg_bg=style.theme.header}
|
||||
-- max length example: "01:23:45 AM - Wednesday, September 28 2022"
|
||||
local datetime = TextBox{parent=main,x=(header.get_width()-42),y=1,text="",alignment=ALIGN.RIGHT,width=42,fg_bg=style.theme.header}
|
||||
|
||||
datetime.register(facility.ps, "date_time", datetime.set_value)
|
||||
datetime.register(fac.ps, "date_time", datetime.set_value)
|
||||
|
||||
local po_pipes = {}
|
||||
local emcool_pipes = {}
|
||||
@@ -83,9 +83,9 @@ local function init(main)
|
||||
return first, last
|
||||
end
|
||||
|
||||
if facility.tank_mode == 0 or facility.tank_mode == 8 then
|
||||
if fac.tank_mode == 0 or fac.tank_mode == 8 then
|
||||
-- (0) tanks belong to reactor units OR (8) 4 total facility tanks (A B C D)
|
||||
for i = 1, facility.num_units do
|
||||
for i = 1, fac.num_units do
|
||||
if units[i].has_tank then
|
||||
local y = y_ofs(i)
|
||||
local color = c_clr(i)
|
||||
@@ -116,7 +116,7 @@ local function init(main)
|
||||
end
|
||||
end
|
||||
|
||||
if facility.tank_mode == 1 then
|
||||
if fac.tank_mode == 1 then
|
||||
-- (1) 1 total facility tank (A A A A)
|
||||
local first_fdef, last_fdef = find_fdef(1, #tank_defs)
|
||||
|
||||
@@ -133,7 +133,7 @@ local function init(main)
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif facility.tank_mode == 2 then
|
||||
elseif fac.tank_mode == 2 then
|
||||
-- (2) 2 total facility tanks (A A A B)
|
||||
local first_fdef, last_fdef = find_fdef(1, math.min(3, #tank_defs))
|
||||
|
||||
@@ -155,7 +155,7 @@ local function init(main)
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif facility.tank_mode == 3 then
|
||||
elseif fac.tank_mode == 3 then
|
||||
-- (3) 2 total facility tanks (A A B B)
|
||||
for _, a in pairs({ 1, 3 }) do
|
||||
local b = a + 1
|
||||
@@ -168,7 +168,7 @@ local function init(main)
|
||||
table.insert(emcool_pipes, pipe(0, y_ofs(b), 1, y_ofs(b) + 6, c_clr(b), true))
|
||||
end
|
||||
end
|
||||
elseif facility.tank_mode == 4 then
|
||||
elseif fac.tank_mode == 4 then
|
||||
-- (4) 2 total facility tanks (A B B B)
|
||||
local first_fdef, last_fdef = find_fdef(2, #tank_defs)
|
||||
|
||||
@@ -190,7 +190,7 @@ local function init(main)
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif facility.tank_mode == 5 then
|
||||
elseif fac.tank_mode == 5 then
|
||||
-- (5) 3 total facility tanks (A A B C)
|
||||
local first_fdef, last_fdef = find_fdef(1, math.min(2, #tank_defs))
|
||||
|
||||
@@ -212,7 +212,7 @@ local function init(main)
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif facility.tank_mode == 6 then
|
||||
elseif fac.tank_mode == 6 then
|
||||
-- (6) 3 total facility tanks (A B B C)
|
||||
local first_fdef, last_fdef = find_fdef(2, math.min(3, #tank_defs))
|
||||
|
||||
@@ -234,7 +234,7 @@ local function init(main)
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif facility.tank_mode == 7 then
|
||||
elseif fac.tank_mode == 7 then
|
||||
-- (7) 3 total facility tanks (A B C C)
|
||||
local first_fdef, last_fdef = find_fdef(3, #tank_defs)
|
||||
|
||||
@@ -265,7 +265,7 @@ local function init(main)
|
||||
PipeNetwork{parent=main,x=2,y=3,pipes=emcool_pipes,bg=style.theme.bg}
|
||||
end
|
||||
|
||||
for i = 1, facility.num_units do
|
||||
for i = 1, fac.num_units do
|
||||
local y_offset = y_ofs(i)
|
||||
unit_flow(main, flow_x, 5 + y_offset, #emcool_pipes == 0, i)
|
||||
table.insert(po_pipes, pipe(0, 3 + y_offset, 4, 0, colors.green, true, true))
|
||||
@@ -298,7 +298,7 @@ local function init(main)
|
||||
-- auxiliary coolant valves --
|
||||
------------------------------
|
||||
|
||||
for i = 1, facility.num_units do
|
||||
for i = 1, fac.num_units do
|
||||
if units[i].aux_coolant then
|
||||
local vx
|
||||
local vy = 3 + y_ofs(i)
|
||||
@@ -340,7 +340,7 @@ local function init(main)
|
||||
|
||||
local tank = Div{parent=main,x=3,y=7+y_offset,width=20,height=14}
|
||||
|
||||
TextBox{parent=tank,text=" ",x=1,y=1,fg_bg=style.lg_gray}
|
||||
TextBox{parent=tank,text=" ",y=1,fg_bg=style.lg_gray}
|
||||
TextBox{parent=tank,text="DYNAMIC TANK "..id,alignment=ALIGN.CENTER,fg_bg=style.wh_gray}
|
||||
|
||||
local tank_box = Rectangle{parent=tank,border=border(1,colors.gray,true),width=20,height=12}
|
||||
@@ -376,12 +376,12 @@ local function init(main)
|
||||
can_fill.register(units[i].tank_ps_tbl[1], "container_mode", _can_fill)
|
||||
can_empty.register(units[i].tank_ps_tbl[1], "container_mode", _can_empty)
|
||||
else
|
||||
status.register(facility.tank_ps_tbl[f_id], "computed_status", status.update)
|
||||
tank_pcnt.register(facility.tank_ps_tbl[f_id], "fill", function (f) tank_pcnt.update(f * 100) end)
|
||||
tank_amnt.register(facility.tank_ps_tbl[f_id], "stored", function (sto) tank_amnt.update(sto.amount) end)
|
||||
level.register(facility.tank_ps_tbl[f_id], "fill", level.update)
|
||||
can_fill.register(facility.tank_ps_tbl[f_id], "container_mode", _can_fill)
|
||||
can_empty.register(facility.tank_ps_tbl[f_id], "container_mode", _can_empty)
|
||||
status.register(fac.tank_ps_tbl[f_id], "computed_status", status.update)
|
||||
tank_pcnt.register(fac.tank_ps_tbl[f_id], "fill", function (f) tank_pcnt.update(f * 100) end)
|
||||
tank_amnt.register(fac.tank_ps_tbl[f_id], "stored", function (sto) tank_amnt.update(sto.amount) end)
|
||||
level.register(fac.tank_ps_tbl[f_id], "fill", level.update)
|
||||
can_fill.register(fac.tank_ps_tbl[f_id], "container_mode", _can_fill)
|
||||
can_empty.register(fac.tank_ps_tbl[f_id], "container_mode", _can_empty)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -394,24 +394,24 @@ local function init(main)
|
||||
|
||||
local sps = Div{parent=main,x=140,y=3,height=12}
|
||||
|
||||
TextBox{parent=sps,text=" ",width=24,x=1,y=1,fg_bg=style.lg_gray}
|
||||
TextBox{parent=sps,text=" ",width=24,y=1,fg_bg=style.lg_gray}
|
||||
TextBox{parent=sps,text="SPS",alignment=ALIGN.CENTER,width=24,fg_bg=wh_gray}
|
||||
|
||||
local sps_box = Rectangle{parent=sps,border=border(1,colors.gray,true),width=24,height=10}
|
||||
|
||||
local status = StateIndicator{parent=sps_box,x=5,y=1,states=style.sps.states,value=1,min_width=14}
|
||||
|
||||
status.register(facility.sps_ps_tbl[1], "computed_status", status.update)
|
||||
status.register(fac.sps_ps_tbl[1], "computed_status", status.update)
|
||||
|
||||
TextBox{parent=sps_box,x=2,y=3,text="Input Rate",width=10,fg_bg=style.label}
|
||||
local sps_in = DataIndicator{parent=sps_box,x=2,label="",format="%15.2f",value=0,unit="mB/t",lu_colors=lu_col,width=20,fg_bg=s_field}
|
||||
|
||||
sps_in.register(facility.ps, "po_am_rate", sps_in.update)
|
||||
sps_in.register(fac.ps, "po_am_rate", sps_in.update)
|
||||
|
||||
TextBox{parent=sps_box,x=2,y=6,text="Production Rate",width=15,fg_bg=style.label}
|
||||
local sps_rate = DataIndicator{parent=sps_box,x=2,label="",format="%15d",value=0,unit="\xb5B/t",lu_colors=lu_col,width=20,fg_bg=s_field}
|
||||
|
||||
sps_rate.register(facility.sps_ps_tbl[1], "process_rate", function (r) sps_rate.update(r * 1000) end)
|
||||
sps_rate.register(fac.sps_ps_tbl[1], "process_rate", function (r) sps_rate.update(r * 1000) end)
|
||||
|
||||
----------------
|
||||
-- statistics --
|
||||
@@ -421,7 +421,7 @@ local function init(main)
|
||||
local raw_waste = Rectangle{parent=main,x=145,y=17,border=border(1,colors.gray,true),width=19,height=3,thin=true,fg_bg=s_hi_bright}
|
||||
local sum_raw_waste = DataIndicator{parent=raw_waste,lu_colors=lu_c_d,label="SUM",unit="mB/t",format="%8.2f",value=0,width=17}
|
||||
|
||||
sum_raw_waste.register(facility.ps, "burn_sum", sum_raw_waste.update)
|
||||
sum_raw_waste.register(fac.ps, "burn_sum", sum_raw_waste.update)
|
||||
|
||||
TextBox{parent=main,x=145,y=21,text="PROC. WASTE",alignment=ALIGN.CENTER,width=19,fg_bg=wh_gray}
|
||||
local pr_waste = Rectangle{parent=main,x=145,y=22,border=border(1,colors.gray,true),width=19,height=5,thin=true,fg_bg=s_hi_bright}
|
||||
@@ -429,15 +429,15 @@ local function init(main)
|
||||
local po = DataIndicator{parent=pr_waste,lu_colors=lu_c_d,label="Po",unit="mB/t",format="%9.2f",value=0,width=17}
|
||||
local popl = DataIndicator{parent=pr_waste,lu_colors=lu_c_d,label="PoPl",unit="mB/t",format="%7.2f",value=0,width=17}
|
||||
|
||||
pu.register(facility.ps, "pu_rate", pu.update)
|
||||
po.register(facility.ps, "po_rate", po.update)
|
||||
popl.register(facility.ps, "po_pl_rate", popl.update)
|
||||
pu.register(fac.ps, "pu_rate", pu.update)
|
||||
po.register(fac.ps, "po_rate", po.update)
|
||||
popl.register(fac.ps, "po_pl_rate", popl.update)
|
||||
|
||||
TextBox{parent=main,x=145,y=28,text="SPENT WASTE",alignment=ALIGN.CENTER,width=19,fg_bg=wh_gray}
|
||||
local sp_waste = Rectangle{parent=main,x=145,y=29,border=border(1,colors.gray,true),width=19,height=3,thin=true,fg_bg=s_hi_bright}
|
||||
local sum_sp_waste = DataIndicator{parent=sp_waste,lu_colors=lu_c_d,label="SUM",unit="mB/t",format="%8.3f",value=0,width=17}
|
||||
|
||||
sum_sp_waste.register(facility.ps, "spent_waste_rate", sum_sp_waste.update)
|
||||
sum_sp_waste.register(fac.ps, "spent_waste_rate", sum_sp_waste.update)
|
||||
end
|
||||
|
||||
return init
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
local types = require("scada-common.types")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local ioctl = require("coordinator.ioctl")
|
||||
|
||||
local pgi = require("coordinator.ui.pgi")
|
||||
local style = require("coordinator.ui.style")
|
||||
@@ -41,19 +41,19 @@ local led_grn = style.led_grn
|
||||
local function init(panel, config)
|
||||
local s_hi_box = style.fp_theme.highlight_box
|
||||
|
||||
local ps = iocontrol.get_db().fp.ps
|
||||
local ps = ioctl.get_db().fp.ps
|
||||
|
||||
local term_w, term_h = term.getSize()
|
||||
|
||||
TextBox{parent=panel,y=1,text="SCADA COORDINATOR",alignment=ALIGN.CENTER,fg_bg=style.fp_theme.header}
|
||||
|
||||
local page_div = Div{parent=panel,x=1,y=3}
|
||||
local page_div = Div{parent=panel,y=3}
|
||||
|
||||
--
|
||||
-- system indicators
|
||||
--
|
||||
|
||||
local main_page = Div{parent=page_div,x=1,y=1}
|
||||
local main_page = Div{parent=page_div,y=1}
|
||||
|
||||
local system = Div{parent=main_page,width=14,height=17,x=2,y=2}
|
||||
|
||||
@@ -185,7 +185,7 @@ local function init(panel, config)
|
||||
|
||||
-- API page
|
||||
|
||||
local api_page = Div{parent=page_div,x=1,y=1,hidden=true}
|
||||
local api_page = Div{parent=page_div,y=1,hidden=true}
|
||||
local api_list = ListBox{parent=api_page,y=1,height=term_h-2,width=term_w,scroll_height=1000,fg_bg=style.fp.text_fg,nav_fg_bg=cpair(colors.gray,colors.lightGray),nav_active=cpair(colors.black,colors.gray)}
|
||||
local _ = Div{parent=api_list,height=1} -- padding
|
||||
|
||||
@@ -193,7 +193,7 @@ local function init(panel, config)
|
||||
|
||||
local panes = { main_page, api_page }
|
||||
|
||||
local page_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes}
|
||||
local page_pane = MultiPane{parent=page_div,y=1,panes=panes}
|
||||
|
||||
local tabs = {
|
||||
{ name = "CRD", color = style.fp.text },
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local ioctl = require("coordinator.ioctl")
|
||||
|
||||
local style = require("coordinator.ui.style")
|
||||
|
||||
@@ -25,17 +25,17 @@ local ALIGN = core.ALIGN
|
||||
local function init(main)
|
||||
local s_header = style.theme.header
|
||||
|
||||
local facility = iocontrol.get_db().facility
|
||||
local units = iocontrol.get_db().units
|
||||
local fac = ioctl.get_db().facility
|
||||
local units = ioctl.get_db().units
|
||||
|
||||
-- window header message
|
||||
local header = TextBox{parent=main,y=1,text="Nuclear Generation Facility SCADA Coordinator",alignment=ALIGN.CENTER,fg_bg=s_header}
|
||||
local ping = DataIndicator{parent=main,x=1,y=1,label="SVTT",format="%d",value=0,unit="ms",lu_colors=style.lg_white,width=12,fg_bg=s_header}
|
||||
local ping = DataIndicator{parent=main,y=1,label="SVTT",format="%d",value=0,unit="ms",lu_colors=style.lg_white,width=12,fg_bg=s_header}
|
||||
-- max length example: "01:23:45 AM - Wednesday, September 28 2022"
|
||||
local datetime = TextBox{parent=main,x=(header.get_width()-42),y=1,text="",alignment=ALIGN.RIGHT,width=42,fg_bg=s_header}
|
||||
|
||||
ping.register(facility.ps, "sv_ping", ping.update)
|
||||
datetime.register(facility.ps, "date_time", datetime.set_value)
|
||||
ping.register(fac.ps, "sv_ping", ping.update)
|
||||
datetime.register(fac.ps, "date_time", datetime.set_value)
|
||||
|
||||
---@type Div, Div, Div, Div
|
||||
local uo_1, uo_2, uo_3, uo_4
|
||||
@@ -44,12 +44,12 @@ local function init(main)
|
||||
local row_1_height = 0
|
||||
|
||||
-- unit overviews
|
||||
if facility.num_units >= 1 then
|
||||
if fac.num_units >= 1 then
|
||||
uo_1 = unit_overview(main, 2, 3, units[1])
|
||||
row_1_height = uo_1.get_height()
|
||||
end
|
||||
|
||||
if facility.num_units >= 2 then
|
||||
if fac.num_units >= 2 then
|
||||
uo_2 = unit_overview(main, 84, 3, units[2])
|
||||
row_1_height = math.max(row_1_height, uo_2.get_height())
|
||||
end
|
||||
@@ -58,14 +58,14 @@ local function init(main)
|
||||
|
||||
util.nop()
|
||||
|
||||
if facility.num_units >= 3 then
|
||||
if fac.num_units >= 3 then
|
||||
-- base offset 3, spacing 1, max height of units 1 and 2
|
||||
local row_2_offset = cnc_y_start
|
||||
|
||||
uo_3 = unit_overview(main, 2, row_2_offset, units[3])
|
||||
cnc_y_start = row_2_offset + uo_3.get_height() + 1
|
||||
|
||||
if facility.num_units == 4 then
|
||||
if fac.num_units == 4 then
|
||||
uo_4 = unit_overview(main, 84, row_2_offset, units[4])
|
||||
cnc_y_start = math.max(cnc_y_start, row_2_offset + uo_4.get_height() + 1)
|
||||
end
|
||||
@@ -88,7 +88,7 @@ local function init(main)
|
||||
|
||||
util.nop()
|
||||
|
||||
imatrix(main, 131, cnc_bottom_align_start, facility.induction_ps_tbl[1])
|
||||
imatrix(main, 131, cnc_bottom_align_start, fac.induction_ps_tbl[1])
|
||||
end
|
||||
|
||||
return init
|
||||
|
||||
@@ -7,7 +7,7 @@ local flasher = require("graphics.flasher")
|
||||
|
||||
local core = {}
|
||||
|
||||
core.version = "2.4.9"
|
||||
core.version = "2.4.10"
|
||||
|
||||
core.flasher = flasher
|
||||
core.events = events
|
||||
|
||||
@@ -13,6 +13,7 @@ local element = require("graphics.element")
|
||||
---@field fractional_precision integer number of fractional digits
|
||||
---@field arrow_fg_bg cpair arrow foreground/background colors
|
||||
---@field arrow_disable? color color when disabled (default light gray)
|
||||
---@field callback? function function to call on touch
|
||||
---@field parent graphics_element
|
||||
---@field id? string element id
|
||||
---@field x? integer 1 if omitted
|
||||
@@ -140,6 +141,8 @@ return function (args)
|
||||
|
||||
update_value()
|
||||
show_num()
|
||||
|
||||
if type(args.callback) == "function" then args.callback(e.value) end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
-- Button Graphics Element
|
||||
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local core = require("graphics.core")
|
||||
local element = require("graphics.element")
|
||||
|
||||
---@class switch_button_args
|
||||
---@field text string button text
|
||||
---@field active_text? string button text when active (optional if active_fg_bg set)
|
||||
---@field callback function function to call on touch
|
||||
---@field default? boolean default state, defaults to off (false)
|
||||
---@field min_width? integer text length + 2 if omitted
|
||||
---@field active_fg_bg cpair foreground/background colors when pressed
|
||||
---@field active_fg_bg? cpair foreground/background colors when pressed (optional if active_text set)
|
||||
---@field dis_fg_bg? cpair foreground/background colors when disabled
|
||||
---@field parent graphics_element
|
||||
---@field id? string element id
|
||||
---@field x? integer 1 if omitted
|
||||
@@ -23,8 +27,8 @@ local element = require("graphics.element")
|
||||
return function (args)
|
||||
element.assert(type(args.text) == "string", "text is a required field")
|
||||
element.assert(type(args.callback) == "function", "callback is a required field")
|
||||
element.assert(type(args.active_fg_bg) == "table", "active_fg_bg is a required field")
|
||||
element.assert(type(args.min_width) == "nil" or (type(args.min_width) == "number" and args.min_width > 0), "min_width must be nil or a number > 0")
|
||||
element.assert((type(args.min_width) == "nil") or (type(args.min_width) == "number" and args.min_width > 0), "min_width must be nil or a number > 0")
|
||||
element.assert((type(args.active_text) == "string") or (type(args.active_fg_bg) == "table"), "active_text or active_fg_bg must be set")
|
||||
|
||||
local text_width = string.len(args.text)
|
||||
|
||||
@@ -42,17 +46,22 @@ return function (args)
|
||||
|
||||
-- show the button state
|
||||
function e.redraw()
|
||||
if e.value then
|
||||
e.w_set_fgd(args.active_fg_bg.fgd)
|
||||
e.w_set_bkg(args.active_fg_bg.bkg)
|
||||
else
|
||||
e.w_set_fgd(e.fg_bg.fgd)
|
||||
e.w_set_bkg(e.fg_bg.bkg)
|
||||
if e.enabled then
|
||||
if e.value and args.active_fg_bg then
|
||||
e.w_set_fgd(args.active_fg_bg.fgd)
|
||||
e.w_set_bkg(args.active_fg_bg.bkg)
|
||||
else
|
||||
e.w_set_fgd(e.fg_bg.fgd)
|
||||
e.w_set_bkg(e.fg_bg.bkg)
|
||||
end
|
||||
elseif args.dis_fg_bg ~= nil then
|
||||
e.w_set_fgd(args.dis_fg_bg.fgd)
|
||||
e.w_set_bkg(args.dis_fg_bg.bkg)
|
||||
end
|
||||
|
||||
e.window.clear()
|
||||
e.w_set_cur(h_pad, v_pad)
|
||||
e.w_write(args.text)
|
||||
e.w_write(util.trinary(e.value and args.active_text, args.active_text, args.text))
|
||||
end
|
||||
|
||||
-- handle mouse interaction
|
||||
@@ -68,8 +77,21 @@ return function (args)
|
||||
-- set the value (does not call the callback)
|
||||
---@param val boolean new value
|
||||
function e.set_value(val)
|
||||
e.value = val
|
||||
e.redraw()
|
||||
if e.value ~= val then
|
||||
e.value = val
|
||||
e.redraw()
|
||||
args.callback(e.value)
|
||||
end
|
||||
end
|
||||
|
||||
-- show butten as enabled
|
||||
function e.on_enabled()
|
||||
if args.dis_fg_bg ~= nil then e.redraw() end
|
||||
end
|
||||
|
||||
-- show button as disabled
|
||||
function e.on_disabled()
|
||||
if args.dis_fg_bg ~= nil then e.redraw() end
|
||||
end
|
||||
|
||||
---@class SwitchButton:graphics_element
|
||||
|
||||
@@ -19,6 +19,7 @@ local MOUSE_CLICK = core.events.MOUSE_CLICK
|
||||
---@field allow_negative? boolean true to allow negative numbers
|
||||
---@field align_right? boolean true to align right while unfocused
|
||||
---@field dis_fg_bg? cpair foreground/background colors when disabled
|
||||
---@field on_unfocus? function callback when the field becomes unfocused
|
||||
---@field parent graphics_element
|
||||
---@field id? string element id
|
||||
---@field x? integer 1 if omitted
|
||||
@@ -89,6 +90,59 @@ return function (args)
|
||||
-- make an interactive field manager
|
||||
local ifield = core.new_ifield(e, args.max_chars, args.fg_bg, args.dis_fg_bg, args.align_right)
|
||||
|
||||
-- parse provided input text and apply it
|
||||
local function _parse_input()
|
||||
local val, max, min = tonumber(e.value), tonumber(args.max), tonumber(args.min)
|
||||
|
||||
if val then
|
||||
if args.max_int_digits or args.max_frac_digits then
|
||||
local str = e.value
|
||||
local ceil = false
|
||||
|
||||
if string.find(str, "-") then str = string.sub(e.value, 2) end
|
||||
local parts = util.strtok(str, ".")
|
||||
|
||||
if parts[1] and args.max_int_digits then
|
||||
if string.len(parts[1]) > args.max_int_digits then
|
||||
parts[1] = string.rep("9", args.max_int_digits)
|
||||
ceil = true
|
||||
end
|
||||
end
|
||||
|
||||
if args.allow_decimal and args.max_frac_digits then
|
||||
if ceil then
|
||||
parts[2] = string.rep("9", args.max_frac_digits)
|
||||
elseif parts[2] and (string.len(parts[2]) > args.max_frac_digits) then
|
||||
-- add a half of the highest precision fractional value in order to round using floor
|
||||
local scaled = math.fmod(val, 1) * (10 ^ (args.max_frac_digits))
|
||||
local value = math.floor(scaled + 0.5)
|
||||
local unscaled = value * (10 ^ (-args.max_frac_digits))
|
||||
parts[2] = string.sub(tostring(unscaled), 3) -- remove starting "0."
|
||||
end
|
||||
end
|
||||
|
||||
if parts[2] then parts[2] = "." .. parts[2] else parts[2] = "" end
|
||||
|
||||
val = tonumber((parts[1] or "") .. parts[2]) or 0
|
||||
end
|
||||
|
||||
if max and val > max then
|
||||
_set_value(max)
|
||||
ifield.nav_start()
|
||||
elseif min and val < min then
|
||||
_set_value(min)
|
||||
ifield.nav_start()
|
||||
else
|
||||
_set_value(val)
|
||||
ifield.nav_end()
|
||||
end
|
||||
else
|
||||
e.value = ""
|
||||
end
|
||||
|
||||
ifield.show()
|
||||
end
|
||||
|
||||
-- handle mouse interaction
|
||||
---@param event mouse_interaction mouse event
|
||||
function e.handle_mouse(event)
|
||||
@@ -163,14 +217,14 @@ return function (args)
|
||||
---@param min integer minimum allowed value
|
||||
function e.set_min(min)
|
||||
args.min = min
|
||||
e.on_unfocused()
|
||||
_parse_input()
|
||||
end
|
||||
|
||||
-- set maximum input value
|
||||
---@param max integer maximum allowed value
|
||||
function e.set_max(max)
|
||||
args.max = max
|
||||
e.on_unfocused()
|
||||
_parse_input()
|
||||
end
|
||||
|
||||
-- replace text with pasted text if its a number
|
||||
@@ -185,55 +239,9 @@ return function (args)
|
||||
|
||||
-- handle unfocused
|
||||
function e.on_unfocused()
|
||||
local val, max, min = tonumber(e.value), tonumber(args.max), tonumber(args.min)
|
||||
_parse_input()
|
||||
|
||||
if val then
|
||||
if args.max_int_digits or args.max_frac_digits then
|
||||
local str = e.value
|
||||
local ceil = false
|
||||
|
||||
if string.find(str, "-") then str = string.sub(e.value, 2) end
|
||||
local parts = util.strtok(str, ".")
|
||||
|
||||
if parts[1] and args.max_int_digits then
|
||||
if string.len(parts[1]) > args.max_int_digits then
|
||||
parts[1] = string.rep("9", args.max_int_digits)
|
||||
ceil = true
|
||||
end
|
||||
end
|
||||
|
||||
if args.allow_decimal and args.max_frac_digits then
|
||||
if ceil then
|
||||
parts[2] = string.rep("9", args.max_frac_digits)
|
||||
elseif parts[2] and (string.len(parts[2]) > args.max_frac_digits) then
|
||||
-- add a half of the highest precision fractional value in order to round using floor
|
||||
local scaled = math.fmod(val, 1) * (10 ^ (args.max_frac_digits))
|
||||
local value = math.floor(scaled + 0.5)
|
||||
local unscaled = value * (10 ^ (-args.max_frac_digits))
|
||||
parts[2] = string.sub(tostring(unscaled), 3) -- remove starting "0."
|
||||
end
|
||||
end
|
||||
|
||||
if parts[2] then parts[2] = "." .. parts[2] else parts[2] = "" end
|
||||
|
||||
val = tonumber((parts[1] or "") .. parts[2]) or 0
|
||||
end
|
||||
|
||||
if max and val > max then
|
||||
_set_value(max)
|
||||
ifield.nav_start()
|
||||
elseif min and val < min then
|
||||
_set_value(min)
|
||||
ifield.nav_start()
|
||||
else
|
||||
_set_value(val)
|
||||
ifield.nav_end()
|
||||
end
|
||||
else
|
||||
e.value = ""
|
||||
end
|
||||
|
||||
ifield.show()
|
||||
if type(args.on_unfocus) == "function" then args.on_unfocus(tonumber(e.value)) end
|
||||
end
|
||||
|
||||
-- handle focus (not unfocus), enable, and redraw with show()
|
||||
|
||||
@@ -11,6 +11,7 @@ local MOUSE_CLICK = core.events.MOUSE_CLICK
|
||||
---@field max_len? integer maximum string length
|
||||
---@field censor? string character to replace text with when printing to screen
|
||||
---@field dis_fg_bg? cpair foreground/background colors when disabled
|
||||
---@field on_unfocus? function callback when the field becomes unfocused
|
||||
---@field parent graphics_element
|
||||
---@field id? string element id
|
||||
---@field x? integer 1 if omitted
|
||||
@@ -77,20 +78,20 @@ return function (args)
|
||||
end
|
||||
|
||||
-- set the value
|
||||
---@param val string string to set
|
||||
function e.set_value(val)
|
||||
ifield.set_value(val)
|
||||
end
|
||||
e.set_value = ifield.set_value
|
||||
|
||||
-- replace text with pasted text
|
||||
---@param text string string to set
|
||||
function e.handle_paste(text)
|
||||
ifield.set_value(text)
|
||||
e.handle_paste = ifield.set_value
|
||||
|
||||
-- handle unfocused
|
||||
function e.on_unfocused()
|
||||
ifield.show()
|
||||
|
||||
if type(args.on_unfocus) == "function" then args.on_unfocus(e.value) end
|
||||
end
|
||||
|
||||
-- handle focus, enable, and redraw with show()
|
||||
e.on_focused = ifield.show
|
||||
e.on_unfocused = ifield.show
|
||||
e.on_enabled = ifield.show
|
||||
e.on_disabled = ifield.show
|
||||
e.redraw = ifield.show
|
||||
|
||||
@@ -55,11 +55,11 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
local ui_c_1 = Div{parent=ui_cfg,x=2,y=4,width=24}
|
||||
local ui_c_2 = Div{parent=ui_cfg,x=2,y=4,width=24}
|
||||
|
||||
local ui_pane = MultiPane{parent=net_cfg,x=1,y=4,panes={ui_c_1,ui_c_2}}
|
||||
local ui_pane = MultiPane{parent=net_cfg,y=4,panes={ui_c_1,ui_c_2}}
|
||||
|
||||
TextBox{parent=ui_cfg,x=1,y=2,text=" Pocket UI",fg_bg=cpair(colors.black,colors.lime)}
|
||||
TextBox{parent=ui_cfg,y=2,text=" Pocket UI",fg_bg=cpair(colors.black,colors.lime)}
|
||||
|
||||
TextBox{parent=ui_c_1,x=1,y=1,height=3,text="You may customize UI options below."}
|
||||
TextBox{parent=ui_c_1,y=1,height=3,text="You may customize UI options below."}
|
||||
|
||||
TextBox{parent=ui_c_1,y=4,text="Po/Pu Pellet Color"}
|
||||
TextBox{parent=ui_c_1,x=20,y=4,text="new!",fg_bg=cpair(colors.red,colors._INHERIT)} ---@todo remove NEW tag on next revision
|
||||
@@ -72,16 +72,16 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
ui_pane.set_value(2)
|
||||
end
|
||||
|
||||
PushButton{parent=ui_c_1,x=1,y=15,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=ui_c_1,y=15,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=ui_c_1,x=19,y=15,text="Next \x1a",callback=submit_ui_opts,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=ui_c_2,x=1,y=1,height=3,text="You may customize units below."}
|
||||
TextBox{parent=ui_c_2,y=1,height=3,text="You may customize units below."}
|
||||
|
||||
TextBox{parent=ui_c_2,x=1,y=4,text="Temperature Scale"}
|
||||
local temp_scale = RadioButton{parent=ui_c_2,x=1,y=5,default=ini_cfg.TempScale,options=types.TEMP_SCALE_NAMES,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.lime}
|
||||
TextBox{parent=ui_c_2,y=4,text="Temperature Scale"}
|
||||
local temp_scale = RadioButton{parent=ui_c_2,y=5,default=ini_cfg.TempScale,options=types.TEMP_SCALE_NAMES,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.lime}
|
||||
|
||||
TextBox{parent=ui_c_2,x=1,y=10,text="Energy Scale"}
|
||||
local energy_scale = RadioButton{parent=ui_c_2,x=1,y=11,default=ini_cfg.EnergyScale,options=types.ENERGY_SCALE_NAMES,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.lime}
|
||||
TextBox{parent=ui_c_2,y=10,text="Energy Scale"}
|
||||
local energy_scale = RadioButton{parent=ui_c_2,y=11,default=ini_cfg.EnergyScale,options=types.ENERGY_SCALE_NAMES,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.lime}
|
||||
|
||||
local function submit_ui_units()
|
||||
tmp_cfg.TempScale = temp_scale.get_value()
|
||||
@@ -89,7 +89,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
main_pane.set_value(3)
|
||||
end
|
||||
|
||||
PushButton{parent=ui_c_2,x=1,y=15,text="\x1b Back",callback=function()ui_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=ui_c_2,y=15,text="\x1b Back",callback=function()ui_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=ui_c_2,x=19,y=15,text="Next \x1a",callback=submit_ui_units,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -101,26 +101,26 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
local net_c_3 = Div{parent=net_cfg,x=2,y=4,width=24}
|
||||
local net_c_4 = Div{parent=net_cfg,x=2,y=4,width=24}
|
||||
|
||||
local net_pane = MultiPane{parent=net_cfg,x=1,y=4,panes={net_c_1,net_c_2,net_c_3,net_c_4}}
|
||||
local net_pane = MultiPane{parent=net_cfg,y=4,panes={net_c_1,net_c_2,net_c_3,net_c_4}}
|
||||
|
||||
TextBox{parent=net_cfg,x=1,y=2,text=" Network Configuration",fg_bg=cpair(colors.black,colors.lightBlue)}
|
||||
TextBox{parent=net_cfg,y=2,text=" Network Configuration",fg_bg=cpair(colors.black,colors.lightBlue)}
|
||||
|
||||
TextBox{parent=net_c_1,x=1,y=1,text="Set network channels."}
|
||||
TextBox{parent=net_c_1,x=1,y=3,height=4,text="Each of the named channels must be the same within a particular SCADA network.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_1,y=1,text="Set network channels."}
|
||||
TextBox{parent=net_c_1,y=3,height=4,text="Each of the named channels must be the same within a particular SCADA network.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_1,x=1,y=8,width=18,text="Supervisor Channel"}
|
||||
local svr_chan = NumberField{parent=net_c_1,x=1,y=9,width=7,default=ini_cfg.SVR_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_1,y=8,width=18,text="Supervisor Channel"}
|
||||
local svr_chan = NumberField{parent=net_c_1,y=9,width=7,default=ini_cfg.SVR_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_1,x=9,y=9,height=4,text="[SVR_CHANNEL]",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_1,x=1,y=10,width=19,text="Coordinator Channel"}
|
||||
local crd_chan = NumberField{parent=net_c_1,x=1,y=11,width=7,default=ini_cfg.CRD_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_1,y=10,width=19,text="Coordinator Channel"}
|
||||
local crd_chan = NumberField{parent=net_c_1,y=11,width=7,default=ini_cfg.CRD_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_1,x=9,y=11,height=4,text="[CRD_CHANNEL]",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_1,x=1,y=12,width=14,text="Pocket Channel"}
|
||||
local pkt_chan = NumberField{parent=net_c_1,x=1,y=13,width=7,default=ini_cfg.PKT_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_1,y=12,width=14,text="Pocket Channel"}
|
||||
local pkt_chan = NumberField{parent=net_c_1,y=13,width=7,default=ini_cfg.PKT_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_1,x=9,y=13,height=4,text="[PKT_CHANNEL]",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local chan_err = TextBox{parent=net_c_1,x=1,y=14,width=24,text="Please set all channels.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
local chan_err = TextBox{parent=net_c_1,y=14,width=24,text="Please set all channels.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
|
||||
local function submit_channels()
|
||||
local svr_c, crd_c, pkt_c = tonumber(svr_chan.get_value()), tonumber(crd_chan.get_value()), tonumber(pkt_chan.get_value())
|
||||
@@ -131,18 +131,18 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
else chan_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_1,x=1,y=15,text="\x1b Back",callback=function()main_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_1,y=15,text="\x1b Back",callback=function()main_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_1,x=19,y=15,text="Next \x1a",callback=submit_channels,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_2,x=1,y=1,text="Set connection timeout."}
|
||||
TextBox{parent=net_c_2,x=1,y=3,height=7,text="You generally should not need to modify this. On slow servers, you can try to increase this to make the system wait longer before assuming a disconnection.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_2,y=1,text="Set connection timeout."}
|
||||
TextBox{parent=net_c_2,y=3,height=7,text="You generally should not need to modify this. On slow servers, you can try to increase this to make the system wait longer before assuming a disconnection.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_2,x=1,y=11,width=19,text="Connection Timeout"}
|
||||
local timeout = NumberField{parent=net_c_2,x=1,y=12,width=7,default=ini_cfg.ConnTimeout,min=2,max=25,max_chars=6,max_frac_digits=2,allow_decimal=true,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_2,y=11,width=19,text="Connection Timeout"}
|
||||
local timeout = NumberField{parent=net_c_2,y=12,width=7,default=ini_cfg.ConnTimeout,min=2,max=25,max_chars=6,max_frac_digits=2,allow_decimal=true,fg_bg=bw_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_2,x=9,y=12,height=2,text="seconds\n(default 5)",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local ct_err = TextBox{parent=net_c_2,x=1,y=14,width=24,text="Please set timeout.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
local ct_err = TextBox{parent=net_c_2,y=14,width=24,text="Please set timeout.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
|
||||
local function submit_timeouts()
|
||||
local timeout_val = tonumber(timeout.get_value())
|
||||
@@ -153,16 +153,16 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
else ct_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_2,x=1,y=15,text="\x1b Back",callback=function()net_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_2,y=15,text="\x1b Back",callback=function()net_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_2,x=19,y=15,text="Next \x1a",callback=submit_timeouts,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_3,x=1,y=1,text="Set the trusted range."}
|
||||
TextBox{parent=net_c_3,x=1,y=3,height=4,text="Setting this to a value larger than 0 prevents connections with devices that many blocks away.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_3,x=1,y=8,height=4,text="This is optional. You can disable this functionality by setting the value to 0.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_3,y=1,text="Set the trusted range."}
|
||||
TextBox{parent=net_c_3,y=3,height=4,text="Setting this to a value larger than 0 prevents connections with devices that many blocks away.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_3,y=8,height=4,text="This is optional. You can disable this functionality by setting the value to 0.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local range = NumberField{parent=net_c_3,x=1,y=13,width=10,default=ini_cfg.TrustedRange,min=0,max_chars=20,allow_decimal=true,fg_bg=bw_fg_bg}
|
||||
local range = NumberField{parent=net_c_3,y=13,width=10,default=ini_cfg.TrustedRange,min=0,max_chars=20,allow_decimal=true,fg_bg=bw_fg_bg}
|
||||
|
||||
local tr_err = TextBox{parent=net_c_3,x=1,y=14,width=24,text="Set the trusted range.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
local tr_err = TextBox{parent=net_c_3,y=14,width=24,text="Set the trusted range.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
|
||||
local function submit_tr()
|
||||
local range_val = tonumber(range.get_value())
|
||||
@@ -173,26 +173,26 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
else tr_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_3,x=1,y=15,text="\x1b Back",callback=function()net_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_3,y=15,text="\x1b Back",callback=function()net_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_3,x=19,y=15,text="Next \x1a",callback=submit_tr,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_4,x=1,y=1,height=4,text="Optionally, set the facility authentication key. Do NOT use one of your passwords."}
|
||||
TextBox{parent=net_c_4,x=1,y=6,height=6,text="This enables verifying that messages are authentic, so it is intended for security on multiplayer servers.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_4,y=1,height=4,text="Optionally, set the facility authentication key. Do NOT use one of your passwords."}
|
||||
TextBox{parent=net_c_4,y=6,height=6,text="This enables verifying that messages are authentic, so it is intended for security on multiplayer servers.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_4,x=1,y=12,text="Facility Auth Key"}
|
||||
local key, _ = TextField{parent=net_c_4,x=1,y=13,max_len=64,value=ini_cfg.AuthKey,width=24,height=1,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_4,y=12,text="Facility Auth Key"}
|
||||
local key, _ = TextField{parent=net_c_4,y=13,max_len=64,value=ini_cfg.AuthKey,width=24,height=1,fg_bg=bw_fg_bg}
|
||||
|
||||
local function censor_key(enable) key.censor(tri(enable, "*", nil)) end
|
||||
|
||||
-- declare back first so tabbing makes sense visually
|
||||
PushButton{parent=net_c_4,x=1,y=15,text="\x1b Back",callback=function()net_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_4,y=15,text="\x1b Back",callback=function()net_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
local hide_key = Checkbox{parent=net_c_4,x=8,y=15,label="Hide Key",box_fg_bg=cpair(colors.lightBlue,colors.black),callback=censor_key}
|
||||
|
||||
hide_key.set_value(true)
|
||||
censor_key(true)
|
||||
|
||||
local key_err = TextBox{parent=net_c_4,x=1,y=14,width=24,text="Length must be > 7.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
local key_err = TextBox{parent=net_c_4,y=14,width=24,text="Length must be > 7.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
|
||||
local function submit_auth()
|
||||
local v = key.get_value()
|
||||
@@ -211,20 +211,20 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
|
||||
local log_c_1 = Div{parent=log_cfg,x=2,y=4,width=24}
|
||||
|
||||
TextBox{parent=log_cfg,x=1,y=2,text=" Logging Configuration",fg_bg=cpair(colors.black,colors.pink)}
|
||||
TextBox{parent=log_cfg,y=2,text=" Logging Configuration",fg_bg=cpair(colors.black,colors.pink)}
|
||||
|
||||
TextBox{parent=log_c_1,x=1,y=1,text="Configure logging below."}
|
||||
TextBox{parent=log_c_1,y=1,text="Configure logging below."}
|
||||
|
||||
TextBox{parent=log_c_1,x=1,y=3,text="Log File Mode"}
|
||||
local mode = RadioButton{parent=log_c_1,x=1,y=4,default=ini_cfg.LogMode+1,options={"Append on Startup","Replace on Startup"},radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.pink}
|
||||
TextBox{parent=log_c_1,y=3,text="Log File Mode"}
|
||||
local mode = RadioButton{parent=log_c_1,y=4,default=ini_cfg.LogMode+1,options={"Append on Startup","Replace on Startup"},radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.pink}
|
||||
|
||||
TextBox{parent=log_c_1,x=1,y=7,text="Log File Path"}
|
||||
local path = TextField{parent=log_c_1,x=1,y=8,width=24,height=1,value=ini_cfg.LogPath,max_len=128,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=log_c_1,y=7,text="Log File Path"}
|
||||
local path = TextField{parent=log_c_1,y=8,width=24,height=1,value=ini_cfg.LogPath,max_len=128,fg_bg=bw_fg_bg}
|
||||
|
||||
local en_dbg = Checkbox{parent=log_c_1,x=1,y=10,default=ini_cfg.LogDebug,label="Enable Debug Messages",box_fg_bg=cpair(colors.pink,colors.black)}
|
||||
local en_dbg = Checkbox{parent=log_c_1,y=10,default=ini_cfg.LogDebug,label="Enable Debug Messages",box_fg_bg=cpair(colors.pink,colors.black)}
|
||||
TextBox{parent=log_c_1,x=3,y=11,height=4,text="This results in much larger log files. Use only as needed.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local path_err = TextBox{parent=log_c_1,x=1,y=14,width=24,text="Provide a log file path.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
local path_err = TextBox{parent=log_c_1,y=14,width=24,text="Provide a log file path.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
|
||||
local function submit_log()
|
||||
if path.get_value() ~= "" then
|
||||
@@ -240,7 +240,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
else path_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=log_c_1,x=1,y=15,text="\x1b Back",callback=function()main_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=log_c_1,y=15,text="\x1b Back",callback=function()main_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=log_c_1,x=19,y=15,text="Next \x1a",callback=submit_log,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -252,11 +252,11 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
local sum_c_3 = Div{parent=summary,x=2,y=4,width=24}
|
||||
local sum_c_4 = Div{parent=summary,x=2,y=4,width=24}
|
||||
|
||||
local sum_pane = MultiPane{parent=summary,x=1,y=4,panes={sum_c_1,sum_c_2,sum_c_3,sum_c_4}}
|
||||
local sum_pane = MultiPane{parent=summary,y=4,panes={sum_c_1,sum_c_2,sum_c_3,sum_c_4}}
|
||||
|
||||
TextBox{parent=summary,x=1,y=2,text=" Summary",fg_bg=cpair(colors.black,colors.green)}
|
||||
TextBox{parent=summary,y=2,text=" Summary",fg_bg=cpair(colors.black,colors.green)}
|
||||
|
||||
local setting_list = ListBox{parent=sum_c_1,x=1,y=1,height=11,width=24,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
local setting_list = ListBox{parent=sum_c_1,y=1,height=11,width=24,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
local function back_from_summary()
|
||||
if tool_ctl.viewing_config or self.importing_legacy then
|
||||
@@ -311,11 +311,11 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=sum_c_1,x=1,y=15,text="\x1b Back",callback=back_from_summary,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
self.show_key_btn = PushButton{parent=sum_c_1,x=1,y=13,min_width=17,text="Unhide Auth Key",callback=function()self.show_auth_key()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
PushButton{parent=sum_c_1,y=15,text="\x1b Back",callback=back_from_summary,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
self.show_key_btn = PushButton{parent=sum_c_1,y=13,min_width=17,text="Unhide Auth Key",callback=function()self.show_auth_key()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
tool_ctl.settings_apply = PushButton{parent=sum_c_1,x=18,y=15,min_width=7,text="Apply",callback=save_and_continue,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=sum_c_2,x=1,y=1,text="Settings saved!"}
|
||||
TextBox{parent=sum_c_2,y=1,text="Settings saved!"}
|
||||
|
||||
local function go_home()
|
||||
main_pane.set_value(1)
|
||||
@@ -323,21 +323,21 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
sum_pane.set_value(1)
|
||||
end
|
||||
|
||||
PushButton{parent=sum_c_2,x=1,y=15,min_width=6,text="Home",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_2,y=15,min_width=6,text="Home",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_2,x=19,y=15,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
|
||||
TextBox{parent=sum_c_3,x=1,y=1,height=4,text="The old config.lua file will now be deleted, then the configurator will exit."}
|
||||
TextBox{parent=sum_c_3,y=1,height=4,text="The old config.lua file will now be deleted, then the configurator will exit."}
|
||||
|
||||
local function delete_legacy()
|
||||
fs.delete("/pocket/config.lua")
|
||||
exit()
|
||||
end
|
||||
|
||||
PushButton{parent=sum_c_3,x=1,y=15,min_width=8,text="Cancel",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_3,y=15,min_width=8,text="Cancel",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_3,x=19,y=15,min_width=6,text="OK",callback=delete_legacy,fg_bg=cpair(colors.black,colors.green),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
|
||||
TextBox{parent=sum_c_4,x=1,y=1,height=8,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=sum_c_4,x=1,y=15,min_width=6,text="Home",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
TextBox{parent=sum_c_4,y=1,height=8,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=sum_c_4,y=15,min_width=6,text="Home",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_4,x=19,y=15,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
|
||||
--#endregion
|
||||
@@ -417,7 +417,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
|
||||
local textbox
|
||||
if height > 1 then
|
||||
textbox = TextBox{parent=line,x=1,y=2,text=val,height=height-1}
|
||||
textbox = TextBox{parent=line,y=2,text=val,height=height-1}
|
||||
else
|
||||
textbox = TextBox{parent=line,x=label_w+1,y=1,text=val,alignment=RIGHT}
|
||||
end
|
||||
|
||||
@@ -127,16 +127,16 @@ local function config_view(display)
|
||||
|
||||
TextBox{parent=display,y=1,text="Pocket Configurator",alignment=CENTER,fg_bg=style.header}
|
||||
|
||||
local root_pane_div = Div{parent=display,x=1,y=2}
|
||||
local root_pane_div = Div{parent=display,y=2}
|
||||
|
||||
local main_page = Div{parent=root_pane_div,x=1,y=1}
|
||||
local ui_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local net_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local log_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local summary = Div{parent=root_pane_div,x=1,y=1}
|
||||
local changelog = Div{parent=root_pane_div,x=1,y=1}
|
||||
local main_page = Div{parent=root_pane_div,y=1}
|
||||
local ui_cfg = Div{parent=root_pane_div,y=1}
|
||||
local net_cfg = Div{parent=root_pane_div,y=1}
|
||||
local log_cfg = Div{parent=root_pane_div,y=1}
|
||||
local summary = Div{parent=root_pane_div,y=1}
|
||||
local changelog = Div{parent=root_pane_div,y=1}
|
||||
|
||||
local main_pane = MultiPane{parent=root_pane_div,x=1,y=1,panes={main_page,ui_cfg,net_cfg,log_cfg,summary,changelog}}
|
||||
local main_pane = MultiPane{parent=root_pane_div,y=1,panes={main_page,ui_cfg,net_cfg,log_cfg,summary,changelog}}
|
||||
|
||||
--#region Main Page
|
||||
|
||||
@@ -192,20 +192,20 @@ local function config_view(display)
|
||||
|
||||
local cl = Div{parent=changelog,x=2,y=4,width=24}
|
||||
|
||||
TextBox{parent=changelog,x=1,y=2,text=" Config Change Log",fg_bg=bw_fg_bg}
|
||||
TextBox{parent=changelog,y=2,text=" Config Change Log",fg_bg=bw_fg_bg}
|
||||
|
||||
local c_log = ListBox{parent=cl,x=1,y=1,height=13,width=24,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
local c_log = ListBox{parent=cl,y=1,height=13,width=24,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
for _, change in ipairs(changes) do
|
||||
TextBox{parent=c_log,text=change[1],fg_bg=bw_fg_bg}
|
||||
for _, v in ipairs(change[2]) do
|
||||
local e = Div{parent=c_log,height=#util.strwrap(v,21)}
|
||||
TextBox{parent=e,y=1,x=1,text="- ",fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=e,y=1,text="- ",fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=e,y=1,x=3,text=v,height=e.get_height(),fg_bg=cpair(colors.gray,colors.white)}
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=cl,x=1,y=15,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=cl,y=15,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
end
|
||||
|
||||
@@ -20,7 +20,7 @@ local TEMP_UNITS = types.TEMP_SCALE_UNITS
|
||||
local WARN_TT = 40
|
||||
local HIGH_TT = 80
|
||||
|
||||
local iocontrol = {}
|
||||
local ioctl = {}
|
||||
|
||||
---@enum POCKET_LINK_STATE
|
||||
local LINK_STATE = {
|
||||
@@ -30,9 +30,9 @@ local LINK_STATE = {
|
||||
LINKED = 3
|
||||
}
|
||||
|
||||
iocontrol.LINK_STATE = LINK_STATE
|
||||
ioctl.LINK_STATE = LINK_STATE
|
||||
|
||||
---@class pocket_ioctl
|
||||
---@class pkt_io
|
||||
local io = {
|
||||
version = "unknown", -- pocket version
|
||||
ps = psil.create(), -- pocket PSIL
|
||||
@@ -46,11 +46,11 @@ local comms = nil ---@type pocket_comms
|
||||
---@param pkt_comms pocket_comms
|
||||
---@param nav pocket_nav
|
||||
---@param cfg pkt_config
|
||||
function iocontrol.init_core(pkt_comms, nav, cfg)
|
||||
function ioctl.init_core(pkt_comms, nav, cfg)
|
||||
comms = pkt_comms
|
||||
config = cfg
|
||||
|
||||
iocontrol.rx = iorx(io)
|
||||
ioctl.rx = iorx(io)
|
||||
|
||||
io.nav = nav
|
||||
|
||||
@@ -106,7 +106,7 @@ end
|
||||
|
||||
-- initialize facility-dependent components of pocket iocontrol
|
||||
---@param conf facility_conf facility configuration
|
||||
function iocontrol.init_fac(conf)
|
||||
function ioctl.init_fac(conf)
|
||||
local temp_scale, energy_scale = config.TempScale, config.EnergyScale
|
||||
io.temp_label = TEMP_UNITS[temp_scale]
|
||||
io.energy_label = ENERGY_UNITS[energy_scale]
|
||||
@@ -136,7 +136,7 @@ function iocontrol.init_fac(conf)
|
||||
end
|
||||
|
||||
-- facility data structure
|
||||
---@class pioctl_facility
|
||||
---@class pkt_io_facility
|
||||
io.facility = {
|
||||
num_units = conf.num_units,
|
||||
tank_mode = conf.cooling.fac_tank_mode,
|
||||
@@ -206,9 +206,9 @@ function iocontrol.init_fac(conf)
|
||||
end
|
||||
|
||||
-- create unit data structures
|
||||
io.units = {} ---@type pioctl_unit[]
|
||||
io.units = {} ---@type pkt_io_unit[]
|
||||
for i = 1, conf.num_units do
|
||||
---@class pioctl_unit
|
||||
---@class pkt_io_unit
|
||||
local entry = {
|
||||
unit_id = i,
|
||||
connected = false,
|
||||
@@ -310,7 +310,7 @@ end
|
||||
---@param state POCKET_LINK_STATE
|
||||
---@param sv_addr integer|false|nil supervisor address if linked, nil if unchanged, false if unlinked
|
||||
---@param api_addr integer|false|nil coordinator address if linked, nil if unchanged, false if unlinked
|
||||
function iocontrol.report_link_state(state, sv_addr, api_addr)
|
||||
function ioctl.report_link_state(state, sv_addr, api_addr)
|
||||
io.ps.publish("link_state", state)
|
||||
|
||||
if state == LINK_STATE.API_LINK_ONLY or state == LINK_STATE.UNLINKED then
|
||||
@@ -335,14 +335,14 @@ function iocontrol.report_link_state(state, sv_addr, api_addr)
|
||||
end
|
||||
|
||||
-- show the reason the supervisor connection isn't linking
|
||||
function iocontrol.report_svr_link_error(msg) io.ps.publish("svr_link_msg", msg) end
|
||||
function ioctl.report_svr_link_error(msg) io.ps.publish("svr_link_msg", msg) end
|
||||
|
||||
-- show the reason the coordinator api connection isn't linking
|
||||
function iocontrol.report_crd_link_error(msg) io.ps.publish("api_link_msg", msg) end
|
||||
function ioctl.report_crd_link_error(msg) io.ps.publish("api_link_msg", msg) end
|
||||
|
||||
-- determine supervisor connection quality (trip time)
|
||||
---@param trip_time integer
|
||||
function iocontrol.report_svr_tt(trip_time)
|
||||
function ioctl.report_svr_tt(trip_time)
|
||||
local state = 3
|
||||
if trip_time > HIGH_TT then
|
||||
state = 1
|
||||
@@ -355,7 +355,7 @@ end
|
||||
|
||||
-- determine coordinator connection quality (trip time)
|
||||
---@param trip_time integer
|
||||
function iocontrol.report_crd_tt(trip_time)
|
||||
function ioctl.report_crd_tt(trip_time)
|
||||
local state = 3
|
||||
if trip_time > HIGH_TT then
|
||||
state = 1
|
||||
@@ -367,6 +367,6 @@ function iocontrol.report_crd_tt(trip_time)
|
||||
end
|
||||
|
||||
-- get the IO controller database
|
||||
function iocontrol.get_db() return io end
|
||||
function ioctl.get_db() return io end
|
||||
|
||||
return iocontrol
|
||||
return ioctl
|
||||
190
pocket/iorx.lua
190
pocket/iorx.lua
@@ -18,7 +18,7 @@ local TNK_STATE = types.TANK_STATE
|
||||
local MTX_STATE = types.IMATRIX_STATE
|
||||
local SPS_STATE = types.SPS_STATE
|
||||
|
||||
local io ---@type pocket_ioctl
|
||||
local io ---@type pkt_io
|
||||
local iorx = {} ---@class iorx
|
||||
|
||||
-- populate facility data from API_GET_FAC
|
||||
@@ -72,6 +72,7 @@ end
|
||||
---@param data table
|
||||
function iorx.record_unit_data(data)
|
||||
local unit = io.units[data[1]]
|
||||
local u_ps = unit.unit_ps
|
||||
|
||||
unit.connected = data[2]
|
||||
local comp_statuses = data[3]
|
||||
@@ -80,8 +81,8 @@ function iorx.record_unit_data(data)
|
||||
|
||||
local next_c_stat = 1
|
||||
|
||||
unit.unit_ps.publish("auto_group_id", unit.a_group)
|
||||
unit.unit_ps.publish("auto_group", types.AUTO_GROUP_NAMES[unit.a_group + 1])
|
||||
u_ps.publish("auto_group_id", unit.a_group)
|
||||
u_ps.publish("auto_group", types.AUTO_GROUP_NAMES[unit.a_group + 1])
|
||||
|
||||
--#region Annunciator
|
||||
|
||||
@@ -106,7 +107,7 @@ function iorx.record_unit_data(data)
|
||||
|
||||
if not every then rcs_disconn = true end
|
||||
|
||||
unit.unit_ps.publish("U_" .. key, every)
|
||||
u_ps.publish("U_" .. key, every)
|
||||
elseif key == "HeatingRateLow" or key == "WaterLevelLow" then
|
||||
-- split up array for all boilers
|
||||
local any = false
|
||||
@@ -121,7 +122,7 @@ function iorx.record_unit_data(data)
|
||||
rcs_hazard = true
|
||||
end
|
||||
|
||||
unit.unit_ps.publish("U_" .. key, any)
|
||||
u_ps.publish("U_" .. key, any)
|
||||
elseif key == "SteamDumpOpen" or key == "TurbineOverSpeed" or key == "GeneratorTrip" or key == "TurbineTrip" then
|
||||
-- split up array for all turbines
|
||||
local any = false
|
||||
@@ -136,10 +137,10 @@ function iorx.record_unit_data(data)
|
||||
rcs_hazard = true
|
||||
end
|
||||
|
||||
unit.unit_ps.publish("U_" .. key, any)
|
||||
u_ps.publish("U_" .. key, any)
|
||||
else
|
||||
-- non-table fields
|
||||
unit.unit_ps.publish(key, val)
|
||||
u_ps.publish(key, val)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -157,7 +158,7 @@ function iorx.record_unit_data(data)
|
||||
rcs_status = 1
|
||||
end
|
||||
|
||||
unit.unit_ps.publish("U_RCS", rcs_status)
|
||||
u_ps.publish("U_RCS", rcs_status)
|
||||
|
||||
--#endregion
|
||||
|
||||
@@ -193,27 +194,27 @@ function iorx.record_unit_data(data)
|
||||
|
||||
for key, val in pairs(unit.reactor_data) do
|
||||
if key ~= "rps_status" and key ~= "mek_struct" and key ~= "mek_status" then
|
||||
unit.unit_ps.publish(key, val)
|
||||
u_ps.publish(key, val)
|
||||
end
|
||||
end
|
||||
|
||||
for key, val in pairs(unit.reactor_data.rps_status) do
|
||||
unit.unit_ps.publish(key, val)
|
||||
u_ps.publish(key, val)
|
||||
end
|
||||
|
||||
for key, val in pairs(unit.reactor_data.mek_struct) do
|
||||
unit.unit_ps.publish(key, val)
|
||||
u_ps.publish(key, val)
|
||||
end
|
||||
|
||||
for key, val in pairs(unit.reactor_data.mek_status) do
|
||||
unit.unit_ps.publish(key, val)
|
||||
u_ps.publish(key, val)
|
||||
end
|
||||
end
|
||||
|
||||
unit.unit_ps.publish("U_ControlStatus", control_status)
|
||||
unit.unit_ps.publish("U_ReactorStatus", reactor_status)
|
||||
unit.unit_ps.publish("U_ReactorStateStatus", comp_statuses[next_c_stat])
|
||||
unit.unit_ps.publish("U_RPS", rps_status)
|
||||
u_ps.publish("U_ControlStatus", control_status)
|
||||
u_ps.publish("U_ReactorStatus", reactor_status)
|
||||
u_ps.publish("U_ReactorStateStatus", comp_statuses[next_c_stat])
|
||||
u_ps.publish("U_RPS", rps_status)
|
||||
|
||||
next_c_stat = next_c_stat + 1
|
||||
|
||||
@@ -493,7 +494,7 @@ function iorx.record_unit_data(data)
|
||||
table.insert(ecam, { color = colors.green, text = "TURBINE" .. plural .. util.trinary(unit.turbine_flow_stable, " STABLE", " STABILIZING"), items = {}})
|
||||
end
|
||||
|
||||
unit.unit_ps.publish("U_ECAM", textutils.serialize(ecam))
|
||||
u_ps.publish("U_ECAM", textutils.serialize(ecam))
|
||||
|
||||
--#endregion
|
||||
end
|
||||
@@ -503,43 +504,45 @@ end
|
||||
function iorx.record_control_data(data)
|
||||
for u_id = 1, #data do
|
||||
local unit = io.units[u_id]
|
||||
local u_ps = unit.unit_ps
|
||||
local u_data = data[u_id]
|
||||
local rct = unit.reactor_data
|
||||
|
||||
unit.connected = u_data[1]
|
||||
|
||||
unit.reactor_data.rps_tripped = u_data[2]
|
||||
unit.unit_ps.publish("rps_tripped", u_data[2])
|
||||
unit.reactor_data.mek_status.status = u_data[3]
|
||||
unit.unit_ps.publish("status", u_data[3])
|
||||
unit.reactor_data.mek_status.temp = u_data[4]
|
||||
unit.unit_ps.publish("temp", u_data[4])
|
||||
unit.reactor_data.mek_status.burn_rate = u_data[5]
|
||||
unit.unit_ps.publish("burn_rate", u_data[5])
|
||||
unit.reactor_data.mek_status.act_burn_rate = u_data[6]
|
||||
unit.unit_ps.publish("act_burn_rate", u_data[6])
|
||||
unit.reactor_data.mek_struct.max_burn = u_data[7]
|
||||
unit.unit_ps.publish("max_burn", u_data[7])
|
||||
rct.rps_tripped = u_data[2]
|
||||
u_ps.publish("rps_tripped", u_data[2])
|
||||
rct.mek_status.status = u_data[3]
|
||||
u_ps.publish("status", u_data[3])
|
||||
rct.mek_status.temp = u_data[4]
|
||||
u_ps.publish("temp", u_data[4])
|
||||
rct.mek_status.burn_rate = u_data[5]
|
||||
u_ps.publish("burn_rate", u_data[5])
|
||||
rct.mek_status.act_burn_rate = u_data[6]
|
||||
u_ps.publish("act_burn_rate", u_data[6])
|
||||
rct.mek_struct.max_burn = u_data[7]
|
||||
u_ps.publish("max_burn", u_data[7])
|
||||
|
||||
unit.annunciator.AutoControl = u_data[8]
|
||||
unit.unit_ps.publish("AutoControl", u_data[8])
|
||||
u_ps.publish("AutoControl", u_data[8])
|
||||
|
||||
unit.a_group = u_data[9]
|
||||
unit.unit_ps.publish("auto_group_id", unit.a_group)
|
||||
unit.unit_ps.publish("auto_group", types.AUTO_GROUP_NAMES[unit.a_group + 1])
|
||||
u_ps.publish("auto_group_id", unit.a_group)
|
||||
u_ps.publish("auto_group", types.AUTO_GROUP_NAMES[unit.a_group + 1])
|
||||
|
||||
local control_status = 1
|
||||
|
||||
if unit.connected then
|
||||
if unit.reactor_data.rps_tripped then
|
||||
if rct.rps_tripped then
|
||||
control_status = 2
|
||||
end
|
||||
|
||||
if unit.reactor_data.mek_status.status then
|
||||
if rct.mek_status.status then
|
||||
control_status = util.trinary(unit.annunciator.AutoControl, 4, 3)
|
||||
end
|
||||
end
|
||||
|
||||
unit.unit_ps.publish("U_ControlStatus", control_status)
|
||||
u_ps.publish("U_ControlStatus", control_status)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -549,6 +552,7 @@ function iorx.record_process_data(data)
|
||||
-- get unit data
|
||||
for u_id = 1, #io.units do
|
||||
local unit = io.units[u_id]
|
||||
local u_ps = unit.unit_ps
|
||||
local u_data = data[u_id]
|
||||
|
||||
unit.reactor_data.mek_status.status = u_data[1]
|
||||
@@ -556,18 +560,19 @@ function iorx.record_process_data(data)
|
||||
unit.annunciator.AutoControl = u_data[6]
|
||||
unit.a_group = u_data[7]
|
||||
|
||||
unit.unit_ps.publish("status", u_data[1])
|
||||
unit.unit_ps.publish("max_burn", u_data[2])
|
||||
unit.unit_ps.publish("burn_limit", u_data[3])
|
||||
unit.unit_ps.publish("U_AutoReady", u_data[4])
|
||||
unit.unit_ps.publish("U_AutoDegraded", u_data[5])
|
||||
unit.unit_ps.publish("AutoControl", u_data[6])
|
||||
unit.unit_ps.publish("auto_group_id", unit.a_group)
|
||||
unit.unit_ps.publish("auto_group", types.AUTO_GROUP_NAMES[unit.a_group + 1])
|
||||
u_ps.publish("status", u_data[1])
|
||||
u_ps.publish("max_burn", u_data[2])
|
||||
u_ps.publish("burn_limit", u_data[3])
|
||||
u_ps.publish("U_AutoReady", u_data[4])
|
||||
u_ps.publish("U_AutoDegraded", u_data[5])
|
||||
u_ps.publish("AutoControl", u_data[6])
|
||||
u_ps.publish("auto_group_id", unit.a_group)
|
||||
u_ps.publish("auto_group", types.AUTO_GROUP_NAMES[unit.a_group + 1])
|
||||
end
|
||||
|
||||
-- get facility data
|
||||
local fac = io.facility
|
||||
local f_ps = fac.ps
|
||||
local f_data = data[#io.units + 1]
|
||||
|
||||
fac.status_lines = f_data[1]
|
||||
@@ -580,25 +585,27 @@ function iorx.record_process_data(data)
|
||||
fac.auto_scram = f_data[3]
|
||||
fac.ascram_status = f_data[4]
|
||||
|
||||
fac.ps.publish("status_line_1", fac.status_lines[1])
|
||||
fac.ps.publish("status_line_2", fac.status_lines[2])
|
||||
f_ps.publish("status_line_1", fac.status_lines[1])
|
||||
f_ps.publish("status_line_2", fac.status_lines[2])
|
||||
|
||||
fac.ps.publish("auto_ready", fac.auto_ready)
|
||||
fac.ps.publish("auto_active", fac.auto_active)
|
||||
fac.ps.publish("auto_ramping", fac.auto_ramping)
|
||||
fac.ps.publish("auto_saturated", fac.auto_saturated)
|
||||
f_ps.publish("auto_ready", fac.auto_ready)
|
||||
f_ps.publish("auto_active", fac.auto_active)
|
||||
f_ps.publish("auto_ramping", fac.auto_ramping)
|
||||
f_ps.publish("auto_saturated", fac.auto_saturated)
|
||||
|
||||
fac.ps.publish("auto_scram", fac.auto_scram)
|
||||
fac.ps.publish("as_matrix_fault", fac.ascram_status.matrix_fault)
|
||||
fac.ps.publish("as_matrix_fill", fac.ascram_status.matrix_fill)
|
||||
fac.ps.publish("as_crit_alarm", fac.ascram_status.crit_alarm)
|
||||
fac.ps.publish("as_radiation", fac.ascram_status.radiation)
|
||||
fac.ps.publish("as_gen_fault", fac.ascram_status.gen_fault)
|
||||
f_ps.publish("auto_scram", fac.auto_scram)
|
||||
f_ps.publish("as_matrix_fault", fac.ascram_status.matrix_fault)
|
||||
f_ps.publish("as_matrix_fill", fac.ascram_status.matrix_fill)
|
||||
f_ps.publish("as_crit_alarm", fac.ascram_status.crit_alarm)
|
||||
f_ps.publish("as_radiation", fac.ascram_status.radiation)
|
||||
f_ps.publish("as_gen_fault", fac.ascram_status.gen_fault)
|
||||
|
||||
fac.ps.publish("process_mode", f_data[5][1])
|
||||
fac.ps.publish("process_burn_target", f_data[5][2])
|
||||
fac.ps.publish("process_charge_target", f_data[5][3])
|
||||
fac.ps.publish("process_gen_target", f_data[5][4])
|
||||
f_ps.publish("process_mode", f_data[5][1])
|
||||
f_ps.publish("process_burn_target", f_data[5][2])
|
||||
f_ps.publish("process_range_start", f_data[5][3])
|
||||
f_ps.publish("process_range_stop", f_data[5][4])
|
||||
f_ps.publish("process_charge_target", f_data[5][5])
|
||||
f_ps.publish("process_gen_target", f_data[5][6])
|
||||
end
|
||||
|
||||
-- update waste app with unit data from API_GET_WASTE
|
||||
@@ -607,6 +614,7 @@ function iorx.record_waste_data(data)
|
||||
-- get unit data
|
||||
for u_id = 1, #io.units do
|
||||
local unit = io.units[u_id]
|
||||
local u_ps = unit.unit_ps
|
||||
local u_data = data[u_id]
|
||||
|
||||
unit.waste_mode = u_data[1]
|
||||
@@ -617,53 +625,55 @@ function iorx.record_waste_data(data)
|
||||
unit.sna_out_rate = u_data[6]
|
||||
unit.waste_stats = u_data[7]
|
||||
|
||||
unit.unit_ps.publish("U_AutoWaste", unit.waste_mode == types.WASTE_MODE.AUTO)
|
||||
unit.unit_ps.publish("U_WasteMode", unit.waste_mode)
|
||||
unit.unit_ps.publish("U_WasteProduct", unit.waste_product)
|
||||
u_ps.publish("U_AutoWaste", unit.waste_mode == types.WASTE_MODE.AUTO)
|
||||
u_ps.publish("U_WasteMode", unit.waste_mode)
|
||||
u_ps.publish("U_WasteProduct", unit.waste_product)
|
||||
|
||||
unit.unit_ps.publish("sna_count", unit.num_snas)
|
||||
unit.unit_ps.publish("sna_peak_rate", unit.sna_peak_rate)
|
||||
unit.unit_ps.publish("sna_max_rate", unit.sna_max_rate)
|
||||
unit.unit_ps.publish("sna_out_rate", unit.sna_out_rate)
|
||||
u_ps.publish("sna_count", unit.num_snas)
|
||||
u_ps.publish("sna_peak_rate", unit.sna_peak_rate)
|
||||
u_ps.publish("sna_max_rate", unit.sna_max_rate)
|
||||
u_ps.publish("sna_out_rate", unit.sna_out_rate)
|
||||
|
||||
unit.unit_ps.publish("pu_rate", unit.waste_stats[1])
|
||||
unit.unit_ps.publish("po_rate", unit.waste_stats[2])
|
||||
unit.unit_ps.publish("po_pl_rate", unit.waste_stats[3])
|
||||
u_ps.publish("pu_rate", unit.waste_stats[1])
|
||||
u_ps.publish("po_rate", unit.waste_stats[2])
|
||||
u_ps.publish("po_pl_rate", unit.waste_stats[3])
|
||||
end
|
||||
|
||||
-- get facility data
|
||||
local fac = io.facility
|
||||
local f_ps = fac.ps
|
||||
local f_data = data[#io.units + 1]
|
||||
|
||||
fac.auto_current_waste_product = f_data[1]
|
||||
fac.auto_pu_fallback_active = f_data[2]
|
||||
fac.auto_sps_disabled = f_data[3]
|
||||
|
||||
fac.ps.publish("current_waste_product", fac.auto_current_waste_product)
|
||||
fac.ps.publish("pu_fallback_active", fac.auto_pu_fallback_active)
|
||||
fac.ps.publish("sps_disabled_low_power", fac.auto_sps_disabled)
|
||||
f_ps.publish("current_waste_product", fac.auto_current_waste_product)
|
||||
f_ps.publish("pu_fallback_active", fac.auto_pu_fallback_active)
|
||||
f_ps.publish("sps_disabled_low_power", fac.auto_sps_disabled)
|
||||
|
||||
fac.ps.publish("process_waste_product", f_data[4])
|
||||
fac.ps.publish("process_pu_fallback", f_data[5])
|
||||
fac.ps.publish("process_sps_low_power", f_data[6])
|
||||
f_ps.publish("process_waste_product", f_data[4])
|
||||
f_ps.publish("process_pu_fallback", f_data[5])
|
||||
f_ps.publish("process_sps_low_power", f_data[6])
|
||||
|
||||
fac.waste_stats = f_data[7]
|
||||
|
||||
fac.ps.publish("burn_sum", fac.waste_stats[1])
|
||||
fac.ps.publish("pu_rate", fac.waste_stats[2])
|
||||
fac.ps.publish("po_rate", fac.waste_stats[3])
|
||||
fac.ps.publish("po_pl_rate", fac.waste_stats[4])
|
||||
fac.ps.publish("po_am_rate", fac.waste_stats[5])
|
||||
fac.ps.publish("spent_waste_rate", fac.waste_stats[6])
|
||||
f_ps.publish("burn_sum", fac.waste_stats[1])
|
||||
f_ps.publish("pu_rate", fac.waste_stats[2])
|
||||
f_ps.publish("po_rate", fac.waste_stats[3])
|
||||
f_ps.publish("po_pl_rate", fac.waste_stats[4])
|
||||
f_ps.publish("po_am_rate", fac.waste_stats[5])
|
||||
f_ps.publish("spent_waste_rate", fac.waste_stats[6])
|
||||
|
||||
fac.sps_ps_tbl[1].publish("SPSStateStatus", f_data[8])
|
||||
fac.ps.publish("sps_process_rate", f_data[9])
|
||||
f_ps.publish("sps_process_rate", f_data[9])
|
||||
end
|
||||
|
||||
-- update facility app with facility and unit data from API_GET_FAC_DTL
|
||||
---@param data table
|
||||
function iorx.record_fac_detail_data(data)
|
||||
local fac = io.facility
|
||||
local f_ps = fac.ps
|
||||
|
||||
local tank_statuses = data[5]
|
||||
local next_t_stat = 1
|
||||
@@ -675,14 +685,14 @@ function iorx.record_fac_detail_data(data)
|
||||
fac.auto_scram = data[3]
|
||||
fac.ascram_status = data[4]
|
||||
|
||||
fac.ps.publish("all_sys_ok", fac.all_sys_ok)
|
||||
fac.ps.publish("rtu_count", fac.rtu_count)
|
||||
fac.ps.publish("auto_scram", fac.auto_scram)
|
||||
fac.ps.publish("as_matrix_fault", fac.ascram_status.matrix_fault)
|
||||
fac.ps.publish("as_matrix_fill", fac.ascram_status.matrix_fill)
|
||||
fac.ps.publish("as_crit_alarm", fac.ascram_status.crit_alarm)
|
||||
fac.ps.publish("as_radiation", fac.ascram_status.radiation)
|
||||
fac.ps.publish("as_gen_fault", fac.ascram_status.gen_fault)
|
||||
f_ps.publish("all_sys_ok", fac.all_sys_ok)
|
||||
f_ps.publish("rtu_count", fac.rtu_count)
|
||||
f_ps.publish("auto_scram", fac.auto_scram)
|
||||
f_ps.publish("as_matrix_fault", fac.ascram_status.matrix_fault)
|
||||
f_ps.publish("as_matrix_fill", fac.ascram_status.matrix_fill)
|
||||
f_ps.publish("as_crit_alarm", fac.ascram_status.crit_alarm)
|
||||
f_ps.publish("as_radiation", fac.ascram_status.radiation)
|
||||
f_ps.publish("as_gen_fault", fac.ascram_status.gen_fault)
|
||||
|
||||
-- unit data
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
local comms = require("scada-common.comms")
|
||||
local log = require("scada-common.log")
|
||||
local util = require("scada-common.util")
|
||||
local comms = require("scada-common.comms")
|
||||
local log = require("scada-common.log")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
|
||||
local PROTOCOL = comms.PROTOCOL
|
||||
local DEVICE_TYPE = comms.DEVICE_TYPE
|
||||
@@ -12,7 +12,7 @@ local CRDN_TYPE = comms.CRDN_TYPE
|
||||
local UNIT_COMMAND = comms.UNIT_COMMAND
|
||||
local FAC_COMMAND = comms.FAC_COMMAND
|
||||
|
||||
local LINK_STATE = iocontrol.LINK_STATE
|
||||
local LINK_STATE = ioctl.LINK_STATE
|
||||
|
||||
local pocket = {}
|
||||
|
||||
@@ -276,8 +276,8 @@ function pocket.init_nav(smem)
|
||||
|
||||
if (req_sv and not p_comms.is_sv_linked()) or (req_api and not p_comms.is_api_linked()) then
|
||||
-- report required connction(s)
|
||||
iocontrol.get_db().loader_require = { sv = req_sv, api = req_api }
|
||||
iocontrol.get_db().ps.toggle("loader_reqs")
|
||||
ioctl.get_db().loader_require = { sv = req_sv, api = req_api }
|
||||
ioctl.get_db().ps.toggle("loader_reqs")
|
||||
|
||||
-- bring up the app loader
|
||||
self.loader_return = app_id
|
||||
@@ -489,13 +489,13 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
||||
sv_watchdog.cancel()
|
||||
nav.unload_sv()
|
||||
|
||||
self.sv.r_seq_num = nil
|
||||
self.sv.addr = comms.BROADCAST
|
||||
|
||||
if self.sv.linked then
|
||||
self.sv.linked = false
|
||||
_send_sv(MGMT_TYPE.CLOSE, {})
|
||||
end
|
||||
|
||||
self.sv.r_seq_num = nil
|
||||
self.sv.addr = comms.BROADCAST
|
||||
end
|
||||
|
||||
-- close connection to coordinator API server
|
||||
@@ -503,13 +503,13 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
||||
api_watchdog.cancel()
|
||||
nav.unload_api()
|
||||
|
||||
self.api.r_seq_num = nil
|
||||
self.api.addr = comms.BROADCAST
|
||||
|
||||
if self.api.linked then
|
||||
self.api.linked = false
|
||||
_send_crd(MGMT_TYPE.CLOSE, {})
|
||||
end
|
||||
|
||||
self.api.r_seq_num = nil
|
||||
self.api.addr = comms.BROADCAST
|
||||
end
|
||||
|
||||
-- close the connections to the servers
|
||||
@@ -522,11 +522,11 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
||||
function public.link_update()
|
||||
if not (self.sv.linked and self.api.linked) then
|
||||
if self.api.linked then
|
||||
iocontrol.report_link_state(LINK_STATE.API_LINK_ONLY, false, nil)
|
||||
ioctl.report_link_state(LINK_STATE.API_LINK_ONLY, false, nil)
|
||||
elseif self.sv.linked then
|
||||
iocontrol.report_link_state(LINK_STATE.SV_LINK_ONLY, nil, false)
|
||||
ioctl.report_link_state(LINK_STATE.SV_LINK_ONLY, nil, false)
|
||||
else
|
||||
iocontrol.report_link_state(LINK_STATE.UNLINKED, false, false)
|
||||
ioctl.report_link_state(LINK_STATE.UNLINKED, false, false)
|
||||
end
|
||||
|
||||
if self.establish_delay_counter <= 0 then
|
||||
@@ -601,7 +601,7 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
||||
end
|
||||
|
||||
-- send the auto process control configuration with a start command
|
||||
---@param auto_cfg [ PROCESS, number, number, number, number[] ]
|
||||
---@param auto_cfg auto_ctl_cfg
|
||||
function public.send_auto_start(auto_cfg)
|
||||
_send_api(CRDN_TYPE.FAC_CMD, { FAC_COMMAND.START, table.unpack(auto_cfg) })
|
||||
end
|
||||
@@ -660,8 +660,8 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
||||
-- handle a packet
|
||||
---@param packet mgmt_packet|crdn_packet|nil
|
||||
function public.handle_packet(packet)
|
||||
local diag = iocontrol.get_db().diag
|
||||
local ps = iocontrol.get_db().ps
|
||||
local diag = ioctl.get_db().diag
|
||||
local ps = ioctl.get_db().ps
|
||||
|
||||
if packet ~= nil then
|
||||
local l_chan = packet.scada_frame.local_channel()
|
||||
@@ -699,13 +699,13 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
||||
local ack = packet.data[2] == true
|
||||
|
||||
if cmd == FAC_COMMAND.SCRAM_ALL then
|
||||
iocontrol.get_db().facility.scram_ack(ack)
|
||||
ioctl.get_db().facility.scram_ack(ack)
|
||||
elseif cmd == FAC_COMMAND.STOP then
|
||||
iocontrol.get_db().facility.stop_ack(ack)
|
||||
ioctl.get_db().facility.stop_ack(ack)
|
||||
elseif cmd == FAC_COMMAND.START then
|
||||
iocontrol.get_db().facility.start_ack(ack)
|
||||
ioctl.get_db().facility.start_ack(ack)
|
||||
elseif cmd == FAC_COMMAND.ACK_ALL_ALARMS then
|
||||
iocontrol.get_db().facility.ack_alarms_ack(ack)
|
||||
ioctl.get_db().facility.ack_alarms_ack(ack)
|
||||
elseif cmd == FAC_COMMAND.SET_WASTE_MODE then
|
||||
elseif cmd == FAC_COMMAND.SET_PU_FB then
|
||||
elseif cmd == FAC_COMMAND.SET_SPS_LP then
|
||||
@@ -722,7 +722,7 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
||||
local unit_id = packet.data[2]
|
||||
local ack = packet.data[3] == true
|
||||
|
||||
local unit = iocontrol.get_db().units[unit_id] ---@type pioctl_unit
|
||||
local unit = ioctl.get_db().units[unit_id] ---@type pkt_io_unit
|
||||
|
||||
if unit ~= nil then
|
||||
if cmd == UNIT_COMMAND.SCRAM then
|
||||
@@ -740,31 +740,31 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
||||
end
|
||||
elseif packet.type == CRDN_TYPE.API_GET_FAC then
|
||||
if _check_length(packet, 11) then
|
||||
iocontrol.rx.record_facility_data(packet.data)
|
||||
ioctl.rx.record_facility_data(packet.data)
|
||||
end
|
||||
elseif packet.type == CRDN_TYPE.API_GET_FAC_DTL then
|
||||
if _check_length(packet, 12) then
|
||||
iocontrol.rx.record_fac_detail_data(packet.data)
|
||||
ioctl.rx.record_fac_detail_data(packet.data)
|
||||
end
|
||||
elseif packet.type == CRDN_TYPE.API_GET_UNIT then
|
||||
if _check_length(packet, 12) and type(packet.data[1]) == "number" and iocontrol.get_db().units[packet.data[1]] then
|
||||
iocontrol.rx.record_unit_data(packet.data)
|
||||
if _check_length(packet, 12) and type(packet.data[1]) == "number" and ioctl.get_db().units[packet.data[1]] then
|
||||
ioctl.rx.record_unit_data(packet.data)
|
||||
end
|
||||
elseif packet.type == CRDN_TYPE.API_GET_CTRL then
|
||||
if _check_length(packet, #iocontrol.get_db().units) then
|
||||
iocontrol.rx.record_control_data(packet.data)
|
||||
if _check_length(packet, #ioctl.get_db().units) then
|
||||
ioctl.rx.record_control_data(packet.data)
|
||||
end
|
||||
elseif packet.type == CRDN_TYPE.API_GET_PROC then
|
||||
if _check_length(packet, #iocontrol.get_db().units + 1) then
|
||||
iocontrol.rx.record_process_data(packet.data)
|
||||
if _check_length(packet, #ioctl.get_db().units + 1) then
|
||||
ioctl.rx.record_process_data(packet.data)
|
||||
end
|
||||
elseif packet.type == CRDN_TYPE.API_GET_WASTE then
|
||||
if _check_length(packet, #iocontrol.get_db().units + 1) then
|
||||
iocontrol.rx.record_waste_data(packet.data)
|
||||
if _check_length(packet, #ioctl.get_db().units + 1) then
|
||||
ioctl.rx.record_waste_data(packet.data)
|
||||
end
|
||||
elseif packet.type == CRDN_TYPE.API_GET_RAD then
|
||||
if _check_length(packet, #iocontrol.get_db().units + 1) then
|
||||
iocontrol.rx.record_radiation_data(packet.data)
|
||||
if _check_length(packet, #ioctl.get_db().units + 1) then
|
||||
ioctl.rx.record_radiation_data(packet.data)
|
||||
end
|
||||
else _fail_type(packet) end
|
||||
else
|
||||
@@ -787,7 +787,7 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
||||
|
||||
_send_api_keep_alive_ack(timestamp)
|
||||
|
||||
iocontrol.report_crd_tt(trip_time)
|
||||
ioctl.report_crd_tt(trip_time)
|
||||
end
|
||||
elseif packet.type == MGMT_TYPE.CLOSE then
|
||||
-- handle session close
|
||||
@@ -811,19 +811,19 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
||||
-- get configuration
|
||||
local conf = { num_units = fac_config[1], cooling = fac_config[2] }
|
||||
|
||||
iocontrol.init_fac(conf)
|
||||
ioctl.init_fac(conf)
|
||||
|
||||
log.info("coordinator connection established")
|
||||
self.establish_delay_counter = 0
|
||||
self.api.linked = true
|
||||
self.api.addr = src_addr
|
||||
|
||||
iocontrol.report_crd_link_error("")
|
||||
ioctl.report_crd_link_error("")
|
||||
|
||||
if self.sv.linked then
|
||||
iocontrol.report_link_state(LINK_STATE.LINKED, nil, self.api.addr)
|
||||
ioctl.report_link_state(LINK_STATE.LINKED, nil, self.api.addr)
|
||||
else
|
||||
iocontrol.report_link_state(LINK_STATE.API_LINK_ONLY, nil, self.api.addr)
|
||||
ioctl.report_link_state(LINK_STATE.API_LINK_ONLY, nil, self.api.addr)
|
||||
end
|
||||
else
|
||||
log.debug("invalid facility configuration table received from coordinator, establish failed")
|
||||
@@ -835,19 +835,19 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
||||
if self.api.last_est_ack ~= est_ack then
|
||||
if est_ack == ESTABLISH_ACK.DENY then
|
||||
log.info("coordinator connection denied")
|
||||
iocontrol.report_crd_link_error("denied")
|
||||
ioctl.report_crd_link_error("denied")
|
||||
elseif est_ack == ESTABLISH_ACK.COLLISION then
|
||||
log.info("coordinator connection denied due to collision")
|
||||
iocontrol.report_crd_link_error("collision")
|
||||
ioctl.report_crd_link_error("collision")
|
||||
elseif est_ack == ESTABLISH_ACK.BAD_VERSION then
|
||||
log.info("coordinator comms version mismatch")
|
||||
iocontrol.report_crd_link_error("comms version mismatch")
|
||||
ioctl.report_crd_link_error("comms version mismatch")
|
||||
elseif est_ack == ESTABLISH_ACK.BAD_API_VERSION then
|
||||
log.info("coordinator api version mismatch")
|
||||
iocontrol.report_crd_link_error("API version mismatch")
|
||||
ioctl.report_crd_link_error("API version mismatch")
|
||||
else
|
||||
log.debug("coordinator SCADA_MGMT establish packet reply unsupported")
|
||||
iocontrol.report_crd_link_error("unknown reply")
|
||||
ioctl.report_crd_link_error("unknown reply")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -900,7 +900,7 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
||||
|
||||
_send_sv_keep_alive_ack(timestamp)
|
||||
|
||||
iocontrol.report_svr_tt(trip_time)
|
||||
ioctl.report_svr_tt(trip_time)
|
||||
end
|
||||
elseif packet.type == MGMT_TYPE.CLOSE then
|
||||
-- handle session close
|
||||
@@ -954,7 +954,7 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
||||
log.debug("supervisor SCADA diag alarm set packet length/type mismatch")
|
||||
end
|
||||
elseif packet.type == MGMT_TYPE.INFO_LIST_CMP then
|
||||
iocontrol.rx.record_network_data(packet.data)
|
||||
ioctl.rx.record_network_data(packet.data)
|
||||
else _fail_type(packet) end
|
||||
elseif packet.type == MGMT_TYPE.ESTABLISH then
|
||||
-- connection with supervisor established
|
||||
@@ -967,27 +967,27 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
||||
self.sv.linked = true
|
||||
self.sv.addr = src_addr
|
||||
|
||||
iocontrol.report_svr_link_error("")
|
||||
ioctl.report_svr_link_error("")
|
||||
|
||||
if self.api.linked then
|
||||
iocontrol.report_link_state(LINK_STATE.LINKED, self.sv.addr, nil)
|
||||
ioctl.report_link_state(LINK_STATE.LINKED, self.sv.addr, nil)
|
||||
else
|
||||
iocontrol.report_link_state(LINK_STATE.SV_LINK_ONLY, self.sv.addr, nil)
|
||||
ioctl.report_link_state(LINK_STATE.SV_LINK_ONLY, self.sv.addr, nil)
|
||||
end
|
||||
else
|
||||
if self.sv.last_est_ack ~= est_ack then
|
||||
if est_ack == ESTABLISH_ACK.DENY then
|
||||
log.info("supervisor connection denied")
|
||||
iocontrol.report_svr_link_error("denied")
|
||||
ioctl.report_svr_link_error("denied")
|
||||
elseif est_ack == ESTABLISH_ACK.COLLISION then
|
||||
log.info("supervisor connection denied due to collision")
|
||||
iocontrol.report_svr_link_error("collision")
|
||||
ioctl.report_svr_link_error("collision")
|
||||
elseif est_ack == ESTABLISH_ACK.BAD_VERSION then
|
||||
log.info("supervisor comms version mismatch")
|
||||
iocontrol.report_svr_link_error("comms version mismatch")
|
||||
ioctl.report_svr_link_error("comms version mismatch")
|
||||
else
|
||||
log.debug("supervisor SCADA_MGMT establish packet reply unsupported")
|
||||
iocontrol.report_svr_link_error("unknown reply")
|
||||
ioctl.report_svr_link_error("unknown reply")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -13,15 +13,15 @@ local U_CMD = comms.UNIT_COMMAND
|
||||
local process = {}
|
||||
|
||||
local self = {
|
||||
io = nil, ---@type ioctl
|
||||
io = nil, ---@type crd_io
|
||||
comms = nil ---@type pocket_comms
|
||||
}
|
||||
|
||||
-- initialize the process controller
|
||||
---@param iocontrol pocket_ioctl iocontrl system
|
||||
---@param ioctl pkt_io iocontrol system
|
||||
---@param pocket_comms pocket_comms pocket communications
|
||||
function process.init(iocontrol, pocket_comms)
|
||||
self.io = iocontrol
|
||||
function process.init(ioctl, pocket_comms)
|
||||
self.io = ioctl
|
||||
self.comms = pocket_comms
|
||||
end
|
||||
|
||||
@@ -125,11 +125,13 @@ end
|
||||
-- process start command
|
||||
---@param mode PROCESS process control mode
|
||||
---@param burn_target number burn rate target
|
||||
---@param range_start integer range control activation threshold
|
||||
---@param range_stop integer range control deactivation threshold
|
||||
---@param charge_target number charge level target
|
||||
---@param gen_target number generation rate target
|
||||
---@param limits number[] unit burn rate limits
|
||||
function process.process_start(mode, burn_target, charge_target, gen_target, limits)
|
||||
self.comms.send_auto_start({ mode, burn_target, charge_target, gen_target, limits })
|
||||
function process.process_start(mode, burn_target, range_start, range_stop, charge_target, gen_target, limits)
|
||||
self.comms.send_auto_start({ mode, burn_target, range_start, range_stop, charge_target, gen_target, limits })
|
||||
log.debug("PROCESS: START AUTO CTRL")
|
||||
end
|
||||
|
||||
|
||||
@@ -17,12 +17,12 @@ local ppm = require("scada-common.ppm")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local configure = require("pocket.configure")
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
local pocket = require("pocket.pocket")
|
||||
local renderer = require("pocket.renderer")
|
||||
local threads = require("pocket.threads")
|
||||
|
||||
local POCKET_VERSION = "v1.0.7"
|
||||
local POCKET_VERSION = "v1.1.0"
|
||||
|
||||
local println = util.println
|
||||
local println_ts = util.println_ts
|
||||
@@ -79,7 +79,7 @@ local function main()
|
||||
ppm.mount_all()
|
||||
|
||||
-- record version for GUI
|
||||
iocontrol.get_db().version = POCKET_VERSION
|
||||
ioctl.get_db().version = POCKET_VERSION
|
||||
|
||||
----------------------------------------
|
||||
-- memory allocation
|
||||
@@ -132,7 +132,7 @@ local function main()
|
||||
network.init_mac(config.AuthKey)
|
||||
end
|
||||
|
||||
iocontrol.report_link_state(iocontrol.LINK_STATE.UNLINKED)
|
||||
ioctl.report_link_state(ioctl.LINK_STATE.UNLINKED)
|
||||
|
||||
-- get the communications modem
|
||||
if smem_dev.modem == nil then
|
||||
@@ -154,7 +154,7 @@ local function main()
|
||||
log.debug("startup> comms init")
|
||||
|
||||
-- init I/O control
|
||||
iocontrol.init_core(smem_sys.pocket_comms, smem_sys.nav, config)
|
||||
ioctl.init_core(smem_sys.pocket_comms, smem_sys.nav, config)
|
||||
|
||||
----------------------------------------
|
||||
-- start the UI
|
||||
|
||||
@@ -40,6 +40,24 @@ function threads.thread__main(smem)
|
||||
local nav = smem.pkt_sys.nav
|
||||
local nic = smem.pkt_sys.nic
|
||||
|
||||
-- main loop periodic tasks
|
||||
local function loop_tick()
|
||||
-- relink if necessary
|
||||
pocket_comms.link_update()
|
||||
|
||||
-- update any tasks for the active page
|
||||
if nav.get_current_page() then
|
||||
local page_tasks = nav.get_current_page().tasks
|
||||
for i = 1, #page_tasks do page_tasks[i]() end
|
||||
end
|
||||
|
||||
-- NIC periodic link-layer tasks
|
||||
nic.periodic()
|
||||
|
||||
-- start next clock timer
|
||||
loop_clock.start()
|
||||
end
|
||||
|
||||
-- start connection watchdogs
|
||||
sv_wd.feed()
|
||||
api_wd.feed()
|
||||
@@ -50,41 +68,27 @@ function threads.thread__main(smem)
|
||||
local event, param1, param2, param3, param4, param5 = util.pull_event()
|
||||
|
||||
-- handle event
|
||||
if event == "timer" then
|
||||
if loop_clock.is_clock(param1) then
|
||||
-- main loop tick
|
||||
|
||||
-- relink if necessary
|
||||
pocket_comms.link_update()
|
||||
|
||||
-- update any tasks for the active page
|
||||
if nav.get_current_page() then
|
||||
local page_tasks = nav.get_current_page().tasks
|
||||
for i = 1, #page_tasks do page_tasks[i]() end
|
||||
end
|
||||
|
||||
-- NIC periodic link-layer tasks
|
||||
nic.periodic()
|
||||
|
||||
-- start next clock timer
|
||||
loop_clock.start()
|
||||
elseif sv_wd.is_timer(param1) then
|
||||
-- supervisor watchdog timeout
|
||||
log.info("supervisor server timeout")
|
||||
pocket_comms.close_sv()
|
||||
elseif api_wd.is_timer(param1) then
|
||||
-- coordinator watchdog timeout
|
||||
log.info("coordinator api server timeout")
|
||||
pocket_comms.close_api()
|
||||
else
|
||||
-- a non-clock/main watchdog timer event
|
||||
-- notify timer callback dispatcher
|
||||
tcd.handle(param1)
|
||||
end
|
||||
elseif event == "modem_message" then
|
||||
if event == "modem_message" then
|
||||
-- got a packet
|
||||
local packet = pocket_comms.parse_packet(param1, param2, param3, param4, param5)
|
||||
pocket_comms.handle_packet(packet)
|
||||
elseif event == "timer" then
|
||||
-- pass this timer event onto the right handler
|
||||
if loop_clock.is_clock(param1) then
|
||||
-- main loop tick
|
||||
loop_tick()
|
||||
elseif sv_wd.is_timer(param1) then
|
||||
-- supervisor connection timed out
|
||||
log.info("supervisor server timeout")
|
||||
pocket_comms.close_sv()
|
||||
elseif api_wd.is_timer(param1) then
|
||||
-- coordinator connection timed out
|
||||
log.info("coordinator api server timeout")
|
||||
pocket_comms.close_api()
|
||||
else
|
||||
-- notify timer callback dispatcher, no other handler claimed this event
|
||||
tcd.handle(param1)
|
||||
end
|
||||
elseif event == "mouse_click" or event == "mouse_up" or event == "mouse_drag" or event == "mouse_scroll" or
|
||||
event == "double_click" then
|
||||
-- handle a mouse event
|
||||
|
||||
@@ -7,7 +7,7 @@ local util = require("scada-common.util")
|
||||
|
||||
local lockbox = require("lockbox")
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
local pocket = require("pocket.pocket")
|
||||
|
||||
local core = require("graphics.core")
|
||||
@@ -27,9 +27,9 @@ local APP_ID = pocket.APP_ID
|
||||
-- create about page view
|
||||
---@param root Container parent
|
||||
local function create_pages(root)
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local frame = Div{parent=root,x=1,y=1}
|
||||
local frame = Div{parent=root,y=1}
|
||||
|
||||
local app = db.nav.register_app(APP_ID.ABOUT, frame)
|
||||
|
||||
@@ -38,7 +38,7 @@ local function create_pages(root)
|
||||
local fw_page = app.new_page(about_page, 3)
|
||||
local hw_page = app.new_page(about_page, 4)
|
||||
|
||||
local about = Div{parent=frame,x=1,y=2}
|
||||
local about = Div{parent=frame,y=2}
|
||||
|
||||
TextBox{parent=about,y=1,text="System Information",alignment=ALIGN.CENTER}
|
||||
|
||||
@@ -54,7 +54,7 @@ local function create_pages(root)
|
||||
|
||||
local config = pocket.config
|
||||
|
||||
local nt_div = Div{parent=frame,x=1,y=2}
|
||||
local nt_div = Div{parent=frame,y=2}
|
||||
TextBox{parent=nt_div,y=1,text="Network Details",alignment=ALIGN.CENTER}
|
||||
|
||||
PushButton{parent=nt_div,x=2,y=1,text="<",fg_bg=btn_fg_bg,active_fg_bg=btn_active,callback=about_page.nav_to}
|
||||
@@ -83,14 +83,14 @@ local function create_pages(root)
|
||||
|
||||
--#region Firmware Versions
|
||||
|
||||
local fw_div = Div{parent=frame,x=1,y=2}
|
||||
local fw_div = Div{parent=frame,y=2}
|
||||
TextBox{parent=fw_div,y=1,text="Firmware Versions",alignment=ALIGN.CENTER}
|
||||
|
||||
PushButton{parent=fw_div,x=2,y=1,text="<",fg_bg=btn_fg_bg,active_fg_bg=btn_active,callback=about_page.nav_to}
|
||||
|
||||
local fw_list_box = ListBox{parent=fw_div,x=1,y=3,scroll_height=100,nav_fg_bg=cpair(colors.lightGray,colors.gray),nav_active=cpair(colors.white,colors.gray)}
|
||||
local fw_list_box = ListBox{parent=fw_div,y=3,scroll_height=100,nav_fg_bg=cpair(colors.lightGray,colors.gray),nav_active=cpair(colors.white,colors.gray)}
|
||||
|
||||
local fw_list = Div{parent=fw_list_box,x=1,y=2,height=18}
|
||||
local fw_list = Div{parent=fw_list_box,y=2,height=18}
|
||||
|
||||
TextBox{parent=fw_list,x=2,text="Pocket Version",fg_bg=label}
|
||||
TextBox{parent=fw_list,x=2,text=db.version}
|
||||
@@ -119,7 +119,7 @@ local function create_pages(root)
|
||||
|
||||
--#region Host Versions
|
||||
|
||||
local hw_div = Div{parent=frame,x=1,y=2}
|
||||
local hw_div = Div{parent=frame,y=2}
|
||||
TextBox{parent=hw_div,y=1,text="Host Versions",alignment=ALIGN.CENTER}
|
||||
|
||||
PushButton{parent=hw_div,x=2,y=1,text="<",fg_bg=btn_fg_bg,active_fg_bg=btn_active,callback=about_page.nav_to}
|
||||
@@ -134,7 +134,7 @@ local function create_pages(root)
|
||||
|
||||
--#endregion
|
||||
|
||||
local root_pane = MultiPane{parent=frame,x=1,y=1,panes={about,nt_div,fw_div,hw_div}}
|
||||
local root_pane = MultiPane{parent=frame,y=1,panes={about,nt_div,fw_div,hw_div}}
|
||||
|
||||
app.set_root_pane(root_pane)
|
||||
end
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
-- Alarm Test App
|
||||
--
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
local pocket = require("pocket.pocket")
|
||||
|
||||
local core = require("graphics.core")
|
||||
@@ -30,15 +30,15 @@ local c_blue_gray = cpair(colors.blue, colors.gray)
|
||||
-- create alarm test page view
|
||||
---@param root Container parent
|
||||
local function new_view(root)
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
local ps = db.ps
|
||||
local ttest = db.diag.tone_test
|
||||
|
||||
local frame = Div{parent=root,x=1,y=1}
|
||||
local frame = Div{parent=root,y=1}
|
||||
|
||||
local app = db.nav.register_app(APP_ID.ALARMS, frame, nil, true)
|
||||
|
||||
local main = Div{parent=frame,x=1,y=1}
|
||||
local main = Div{parent=frame,y=1}
|
||||
local page_div = Div{parent=main,y=2,width=main.get_width()}
|
||||
|
||||
--#region alarm testing
|
||||
@@ -168,7 +168,7 @@ local function new_view(root)
|
||||
--#endregion
|
||||
|
||||
-- setup multipane
|
||||
local u_pane = MultiPane{parent=page_div,x=1,y=1,panes={alarms_div,tones_div,info_div}}
|
||||
local u_pane = MultiPane{parent=page_div,y=1,panes={alarms_div,tones_div,info_div}}
|
||||
app.set_root_pane(u_pane)
|
||||
|
||||
local list = {
|
||||
|
||||
@@ -6,7 +6,7 @@ local comms = require("scada-common.comms")
|
||||
local const = require("scada-common.constants")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
local pocket = require("pocket.pocket")
|
||||
|
||||
local style = require("pocket.ui.style")
|
||||
@@ -37,19 +37,19 @@ local box_label = cpair(colors.lightGray, colors.gray)
|
||||
-- new computer list page view
|
||||
---@param root Container parent
|
||||
local function new_view(root)
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local frame = Div{parent=root,x=1,y=1}
|
||||
local frame = Div{parent=root,y=1}
|
||||
|
||||
local app = db.nav.register_app(APP_ID.COMPS, frame, nil, true, false)
|
||||
|
||||
local load_div = Div{parent=frame,x=1,y=1}
|
||||
local main = Div{parent=frame,x=1,y=1}
|
||||
local load_div = Div{parent=frame,y=1}
|
||||
local main = Div{parent=frame,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.orange,colors._INHERIT)}
|
||||
|
||||
local load_pane = MultiPane{parent=main,x=1,y=1,panes={load_div,main}}
|
||||
local load_pane = MultiPane{parent=main,y=1,panes={load_div,main}}
|
||||
|
||||
app.set_sidebar({ { label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = db.nav.go_home } })
|
||||
|
||||
@@ -251,7 +251,7 @@ local function new_view(root)
|
||||
--#endregion
|
||||
|
||||
-- setup multipane
|
||||
local u_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes}
|
||||
local u_pane = MultiPane{parent=page_div,y=1,panes=panes}
|
||||
app.set_root_pane(u_pane)
|
||||
|
||||
-- setup sidebar
|
||||
@@ -285,7 +285,7 @@ local function new_view(root)
|
||||
load_pane.set_value(1)
|
||||
|
||||
-- clear the list of connected computers so that connections re-appear on reload of this app
|
||||
iocontrol.rx.clear_comp_record()
|
||||
ioctl.rx.clear_comp_record()
|
||||
end
|
||||
|
||||
app.set_load(load)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
local types = require("scada-common.types")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
local pocket = require("pocket.pocket")
|
||||
local process = require("pocket.process")
|
||||
|
||||
@@ -49,19 +49,19 @@ local hzd_dis_colors = style.hzd_dis_colors
|
||||
local function new_view(root)
|
||||
local btn_fg_bg = cpair(colors.green, colors.black)
|
||||
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local frame = Div{parent=root,x=1,y=1}
|
||||
local frame = Div{parent=root,y=1}
|
||||
|
||||
local app = db.nav.register_app(APP_ID.CONTROL, frame, nil, false, true)
|
||||
|
||||
local load_div = Div{parent=frame,x=1,y=1}
|
||||
local main = Div{parent=frame,x=1,y=1}
|
||||
local load_div = Div{parent=frame,y=1}
|
||||
local main = Div{parent=frame,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.green,colors._INHERIT)}
|
||||
|
||||
local load_pane = MultiPane{parent=main,x=1,y=1,panes={load_div,main}}
|
||||
local load_pane = MultiPane{parent=main,y=1,panes={load_div,main}}
|
||||
|
||||
app.set_sidebar({ { label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = db.nav.go_home } })
|
||||
|
||||
@@ -126,13 +126,13 @@ local function new_view(root)
|
||||
u_page.tasks = { update }
|
||||
|
||||
TextBox{parent=u_div,y=1,text="Reactor Unit #"..i,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,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 rate = DataIndicator{parent=u_div,y=3,lu_colors=lu_col,label="Burn",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=db.temp_label,format="%10.2f",value=0,commas=true,width=26,fg_bg=text_fg}
|
||||
|
||||
local ctrl = IconIndicator{parent=u_div,x=1,y=6,label="Control State",states=mode_states}
|
||||
local ctrl = IconIndicator{parent=u_div,y=6,label="Control State",states=mode_states}
|
||||
|
||||
rate.register(u_ps, "act_burn_rate", rate.update)
|
||||
temp.register(u_ps, "temp", function (t) temp.update(db.temp_convert(t)) end)
|
||||
@@ -201,7 +201,7 @@ local function new_view(root)
|
||||
db.facility.ack_alarms_ack = ack_a.on_response
|
||||
|
||||
-- setup multipane
|
||||
local u_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes}
|
||||
local u_pane = MultiPane{parent=page_div,y=1,panes=panes}
|
||||
app.set_root_pane(u_pane)
|
||||
|
||||
set_sidebar()
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
local pocket = require("pocket.pocket")
|
||||
|
||||
local style = require("pocket.ui.style")
|
||||
@@ -41,19 +41,19 @@ local grn_ind_s = style.icon_states.grn_ind_s
|
||||
-- new unit page view
|
||||
---@param root Container parent
|
||||
local function new_view(root)
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local frame = Div{parent=root,x=1,y=1}
|
||||
local frame = Div{parent=root,y=1}
|
||||
|
||||
local app = db.nav.register_app(APP_ID.FACILITY, frame, nil, false, true)
|
||||
|
||||
local load_div = Div{parent=frame,x=1,y=1}
|
||||
local main = Div{parent=frame,x=1,y=1}
|
||||
local load_div = Div{parent=frame,y=1}
|
||||
local main = Div{parent=frame,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.orange,colors._INHERIT)}
|
||||
|
||||
local load_pane = MultiPane{parent=main,x=1,y=1,panes={load_div,main}}
|
||||
local load_pane = MultiPane{parent=main,y=1,panes={load_div,main}}
|
||||
|
||||
app.set_sidebar({ { label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = db.nav.go_home } })
|
||||
|
||||
@@ -100,7 +100,7 @@ local function new_view(root)
|
||||
|
||||
TextBox{parent=f_div,y=8,text="Induction Matrix",alignment=ALIGN.CENTER}
|
||||
|
||||
local eta = TextBox{parent=f_div,x=1,y=10,text="ETA Unknown",alignment=ALIGN.CENTER,fg_bg=cpair(colors.white,colors.gray)}
|
||||
local eta = TextBox{parent=f_div,y=10,text="ETA Unknown",alignment=ALIGN.CENTER,fg_bg=cpair(colors.white,colors.gray)}
|
||||
eta.register(fac.induction_ps_tbl[1], "eta_string", eta.set_value)
|
||||
|
||||
TextBox{parent=f_div,y=12,text="Unit Statuses",alignment=ALIGN.CENTER}
|
||||
@@ -179,7 +179,7 @@ local function new_view(root)
|
||||
if fac.tank_list[t] == 1 then
|
||||
t_div.line_break()
|
||||
|
||||
local tank = IconIndicator{parent=t_div,x=1,label="Unit Tank "..t.." (U-"..t..")",states=basic_states}
|
||||
local tank = IconIndicator{parent=t_div,label="Unit Tank "..t.." (U-"..t..")",states=basic_states}
|
||||
tank.register(db.units[t].tank_ps_tbl[1], "DynamicTankStatus", tank.update)
|
||||
|
||||
TextBox{parent=t_div,x=5,text="\x07 Unit "..t,fg_bg=label_fg_bg}
|
||||
@@ -188,7 +188,7 @@ local function new_view(root)
|
||||
|
||||
t_div.line_break()
|
||||
|
||||
local tank = IconIndicator{parent=t_div,x=1,label="Fac. Tank "..f_tank_id.." (F-"..f_tank_id..")",states=basic_states}
|
||||
local tank = IconIndicator{parent=t_div,label="Fac. Tank "..f_tank_id.." (F-"..f_tank_id..")",states=basic_states}
|
||||
tank.register(fac.tank_ps_tbl[f_tank_id], "DynamicTankStatus", tank.update)
|
||||
|
||||
local connections = ""
|
||||
@@ -211,7 +211,7 @@ local function new_view(root)
|
||||
--#endregion
|
||||
|
||||
-- setup multipane
|
||||
local f_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes}
|
||||
local f_pane = MultiPane{parent=page_div,y=1,panes=panes}
|
||||
app.set_root_pane(f_pane)
|
||||
|
||||
-- setup sidebar
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
local util = require("scada-common.util")
|
||||
local log = require("scada-common.log")
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
local pocket = require("pocket.pocket")
|
||||
|
||||
local docs = require("pocket.ui.docs")
|
||||
@@ -33,14 +33,14 @@ local APP_ID = pocket.APP_ID
|
||||
-- new system guide view
|
||||
---@param root Container parent
|
||||
local function new_view(root)
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local frame = Div{parent=root,x=1,y=1}
|
||||
local frame = Div{parent=root,y=1}
|
||||
|
||||
local app = db.nav.register_app(APP_ID.GUIDE, frame)
|
||||
|
||||
local load_div = Div{parent=frame,x=1,y=1}
|
||||
local main = Div{parent=frame,x=1,y=1}
|
||||
local load_div = Div{parent=frame,y=1}
|
||||
local main = Div{parent=frame,y=1}
|
||||
|
||||
WaitingAnim{parent=load_div,x=math.floor(main.get_width()/2)-1,y=8,fg_bg=cpair(colors.cyan,colors._INHERIT)}
|
||||
TextBox{parent=load_div,y=12,text="Loading...",alignment=ALIGN.CENTER}
|
||||
@@ -53,7 +53,7 @@ local function new_view(root)
|
||||
load_text_2.set_value(b or "")
|
||||
end
|
||||
|
||||
local load_pane = MultiPane{parent=main,x=1,y=1,panes={load_div,main}}
|
||||
local load_pane = MultiPane{parent=main,y=1,panes={load_div,main}}
|
||||
|
||||
local btn_fg_bg = cpair(colors.cyan, colors.black)
|
||||
local btn_active = cpair(colors.white, colors.black)
|
||||
@@ -110,13 +110,13 @@ local function new_view(root)
|
||||
|
||||
TextBox{parent=search,y=1,text="Search",alignment=ALIGN.CENTER}
|
||||
|
||||
local query_field = TextField{parent=search,x=1,y=3,width=18,fg_bg=cpair(colors.white,colors.gray)}
|
||||
local query_field = TextField{parent=search,y=3,width=18,fg_bg=cpair(colors.white,colors.gray)}
|
||||
|
||||
local func_ref = {}
|
||||
|
||||
PushButton{parent=search,x=20,y=3,text="GO",fg_bg=btn_fg_bg,active_fg_bg=btn_active,callback=function()func_ref.run_search()end}
|
||||
|
||||
local search_results = ListBox{parent=search,x=1,y=5,scroll_height=200,nav_fg_bg=cpair(colors.lightGray,colors.gray),nav_active=cpair(colors.white,colors.gray)}
|
||||
local search_results = ListBox{parent=search,y=5,scroll_height=200,nav_fg_bg=cpair(colors.lightGray,colors.gray),nav_active=cpair(colors.white,colors.gray)}
|
||||
|
||||
function func_ref.run_search()
|
||||
local query = string.lower(query_field.get_value())
|
||||
@@ -239,7 +239,7 @@ local function new_view(root)
|
||||
PushButton{parent=coord_div,x=2,y=1,text="<",fg_bg=btn_fg_bg,active_fg_bg=btn_active,callback=uis_page.nav_to}
|
||||
|
||||
load_text(false, "Main Display")
|
||||
local main_disp_page = guide_section(sect_construct_data, coord_page, "Main Display", docs.c_ui.main, 300)
|
||||
local main_disp_page = guide_section(sect_construct_data, coord_page, "Main Display", docs.c_ui.main, 310)
|
||||
load_text(false, "Flow Display")
|
||||
local flow_disp_page = guide_section(sect_construct_data, coord_page, "Flow Display", docs.c_ui.flow, 210)
|
||||
load_text(false, "Unit Displays")
|
||||
@@ -255,7 +255,7 @@ local function new_view(root)
|
||||
PushButton{parent=fps,x=2,y=1,text="<",fg_bg=btn_fg_bg,active_fg_bg=btn_active,callback=main_page.nav_to}
|
||||
|
||||
load_text(false, "Common Items")
|
||||
local fp_common_page = guide_section(sect_construct_data, fps_page, "Common Items", docs.fp.common, 100)
|
||||
local fp_common_page = guide_section(sect_construct_data, fps_page, "Common Items", docs.fp.common, 130)
|
||||
load_text(false, "Reactor PLC")
|
||||
local fp_rplc_page = guide_section(sect_construct_data, fps_page, "Reactor PLC", docs.fp.r_plc, 190)
|
||||
load_text(false, "RTU Gateway")
|
||||
@@ -285,7 +285,7 @@ local function new_view(root)
|
||||
load_text("Links")
|
||||
|
||||
TextBox{parent=lnk,y=1,text="Wiki and Discord",alignment=ALIGN.CENTER}
|
||||
PushButton{parent=lnk,x=1,y=1,text="<",fg_bg=btn_fg_bg,active_fg_bg=btn_active,callback=main_page.nav_to}
|
||||
PushButton{parent=lnk,y=1,text="<",fg_bg=btn_fg_bg,active_fg_bg=btn_active,callback=main_page.nav_to}
|
||||
|
||||
lnk.line_break()
|
||||
TextBox{parent=lnk,text="GitHub",fg_bg=cpair(colors.lightGray,colors.black)}
|
||||
@@ -298,7 +298,7 @@ local function new_view(root)
|
||||
TextBox{parent=lnk,text="discord.gg/R9NSCkhcwt"}
|
||||
|
||||
-- setup multipane
|
||||
local u_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes}
|
||||
local u_pane = MultiPane{parent=page_div,y=1,panes=panes}
|
||||
app.set_root_pane(u_pane)
|
||||
|
||||
-- link help resources
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
-- Loading Screen App
|
||||
--
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
local pocket = require("pocket.pocket")
|
||||
|
||||
local conn_waiting = require("pocket.ui.components.conn_waiting")
|
||||
@@ -15,22 +15,22 @@ local TextBox = require("graphics.elements.TextBox")
|
||||
|
||||
local APP_ID = pocket.APP_ID
|
||||
|
||||
local LINK_STATE = iocontrol.LINK_STATE
|
||||
local LINK_STATE = ioctl.LINK_STATE
|
||||
|
||||
-- create the connecting to SV & API page
|
||||
---@param root Container parent
|
||||
local function create_pages(root)
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local main = Div{parent=root,x=1,y=1}
|
||||
local main = Div{parent=root,y=1}
|
||||
|
||||
db.nav.register_app(APP_ID.LOADER, main).new_page(nil, function () end)
|
||||
|
||||
local conn_sv_wait = conn_waiting(main, 6, false)
|
||||
local conn_api_wait = conn_waiting(main, 6, true)
|
||||
local main_pane = Div{parent=main,x=1,y=2}
|
||||
local main_pane = Div{parent=main,y=2}
|
||||
|
||||
local root_pane = MultiPane{parent=main,x=1,y=1,panes={conn_sv_wait,conn_api_wait,main_pane}}
|
||||
local root_pane = MultiPane{parent=main,y=1,panes={conn_sv_wait,conn_api_wait,main_pane}}
|
||||
|
||||
local function update()
|
||||
local state = db.ps.get("link_state")
|
||||
@@ -56,7 +56,7 @@ local function create_pages(root)
|
||||
root_pane.register(db.ps, "link_state", update)
|
||||
root_pane.register(db.ps, "loader_reqs", update)
|
||||
|
||||
TextBox{parent=main_pane,text="Connected!",x=1,y=6,alignment=core.ALIGN.CENTER}
|
||||
TextBox{parent=main_pane,text="Connected!",y=6,alignment=core.ALIGN.CENTER}
|
||||
end
|
||||
|
||||
return create_pages
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
local types = require("scada-common.types")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
local pocket = require("pocket.pocket")
|
||||
local process = require("pocket.process")
|
||||
|
||||
@@ -27,6 +27,8 @@ local NumberField = require("graphics.elements.form.NumberField")
|
||||
|
||||
local IconIndicator = require("graphics.elements.indicators.IconIndicator")
|
||||
|
||||
local PROCESS = types.PROCESS
|
||||
|
||||
local ALIGN = core.ALIGN
|
||||
local cpair = core.cpair
|
||||
local border = core.border
|
||||
@@ -50,19 +52,19 @@ local dis_colors = cpair(colors.white, colors.lightGray)
|
||||
-- new process control page view
|
||||
---@param root Container parent
|
||||
local function new_view(root)
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local frame = Div{parent=root,x=1,y=1}
|
||||
local frame = Div{parent=root,y=1}
|
||||
|
||||
local app = db.nav.register_app(APP_ID.PROCESS, frame, nil, false, true)
|
||||
|
||||
local load_div = Div{parent=frame,x=1,y=1}
|
||||
local main = Div{parent=frame,x=1,y=1}
|
||||
local load_div = Div{parent=frame,y=1}
|
||||
local main = Div{parent=frame,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.purple,colors._INHERIT)}
|
||||
|
||||
local load_pane = MultiPane{parent=main,x=1,y=1,panes={load_div,main}}
|
||||
local load_pane = MultiPane{parent=main,y=1,panes={load_div,main}}
|
||||
|
||||
app.set_sidebar({ { label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = db.nav.go_home } })
|
||||
|
||||
@@ -77,7 +79,7 @@ local function new_view(root)
|
||||
local panes = {} ---@type Div[]
|
||||
|
||||
-- create all page divs
|
||||
for _ = 1, db.facility.num_units + 3 do
|
||||
for _ = 1, db.facility.num_units + 4 do
|
||||
local div = Div{parent=page_div}
|
||||
table.insert(panes, div)
|
||||
end
|
||||
@@ -107,7 +109,7 @@ local function new_view(root)
|
||||
TextBox{parent=u_div,y=1,text="Reactor Unit #"..i,alignment=ALIGN.CENTER}
|
||||
|
||||
TextBox{parent=u_div,y=3,text="Auto Rate Limit",fg_bg=label_fg_bg}
|
||||
rate_limits[i] = NumberField{parent=u_div,x=1,y=4,width=16,default=0.01,min=0.01,max_frac_digits=2,max_chars=8,allow_decimal=true,align_right=true,fg_bg=field_fg_bg,dis_fg_bg=field_dis_fg_bg}
|
||||
rate_limits[i] = NumberField{parent=u_div,y=4,width=16,default=0.01,min=0.01,max_frac_digits=2,max_chars=8,allow_decimal=true,align_right=true,fg_bg=field_fg_bg,dis_fg_bg=field_dis_fg_bg}
|
||||
TextBox{parent=u_div,x=18,y=4,text="mB/t",width=4,fg_bg=label_fg_bg}
|
||||
|
||||
rate_limits[i].register(unit.unit_ps, "max_burn", rate_limits[i].set_max)
|
||||
@@ -151,36 +153,82 @@ local function new_view(root)
|
||||
|
||||
--#endregion
|
||||
|
||||
--#region process control options page
|
||||
--#region process control mode 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 m_pane = panes[db.facility.num_units + 3]
|
||||
local m_div = Div{parent=m_pane,x=2,width=main.get_width()-2}
|
||||
|
||||
local opt_page = app.new_page(nil, db.facility.num_units + 2)
|
||||
opt_page.tasks = { update }
|
||||
local mode_page = app.new_page(nil, db.facility.num_units + 3)
|
||||
mode_page.tasks = { update }
|
||||
|
||||
TextBox{parent=o_div,y=1,text="Process Options",alignment=ALIGN.CENTER}
|
||||
TextBox{parent=m_div,y=1,text="Process Mode",alignment=ALIGN.CENTER}
|
||||
|
||||
local ctl_opts = { "Monitored Max Burn", "Combined Burn Rate", "Charge Level", "Generation Rate" }
|
||||
local mode = RadioButton{parent=o_div,x=1,y=3,options=ctl_opts,radio_colors=cpair(colors.lightGray,colors.gray),select_color=colors.purple,dis_fg_bg=style.btn_disable}
|
||||
local desc = TextBox{parent=m_div,y=9,height=9,text="",fg_bg=label_fg_bg}
|
||||
|
||||
local function _set_desc(m)
|
||||
if m == PROCESS.MAX_BURN then
|
||||
desc.set_value("This mode runs all assigned reactors at their configured unit auto rate limits.")
|
||||
elseif m == PROCESS.BURN_RATE then
|
||||
desc.set_value("This mode runs assigned reactors by priority group to meet the requested burn rate. Primary ones are used, then secondary if they can't keep up, etc.")
|
||||
elseif m == PROCESS.CHARGE then
|
||||
desc.set_value("This mode runs assigned reactors by priority group to meet the requested induction matrix charge level. Primary ones are used, then secondary if they can't keep up, etc.")
|
||||
elseif m == PROCESS.GEN_RATE then
|
||||
desc.set_value("This mode runs assigned reactors by priority group to meet the requested energy generation rate. Primary ones are used, then secondary if they can't keep up, etc.")
|
||||
elseif m == PROCESS.RANGE_CONTROL then
|
||||
desc.set_value("This mode runs all assigned reactors at their configured unit auto rate limits once charge drops below the start percentage until it meets the stop percentage.")
|
||||
else
|
||||
desc.set_value("Unknown mode selected.")
|
||||
end
|
||||
end
|
||||
|
||||
local ctl_opts = { "Monitored Max Burn", "Combined Burn Rate", "Charge Level", "Generation Rate", "Charge Range" }
|
||||
local mode = RadioButton{parent=m_div,y=3,options=ctl_opts,radio_colors=cpair(colors.lightGray,colors.gray),select_color=colors.purple,callback=_set_desc,dis_fg_bg=style.btn_disable}
|
||||
|
||||
mode.register(f_ps, "process_mode", mode.set_value)
|
||||
desc.register(f_ps, "process_mode", _set_desc)
|
||||
|
||||
TextBox{parent=o_div,y=9,text="Burn Rate Target",fg_bg=label_fg_bg}
|
||||
local b_target = NumberField{parent=o_div,x=1,y=10,width=15,default=0.01,min=0.01,max_frac_digits=2,max_chars=8,allow_decimal=true,align_right=true,fg_bg=field_fg_bg,dis_fg_bg=field_dis_fg_bg}
|
||||
TextBox{parent=o_div,x=17,y=10,text="mB/t",fg_bg=label_fg_bg}
|
||||
--#endregion
|
||||
|
||||
TextBox{parent=o_div,y=12,text="Charge Level Target",fg_bg=label_fg_bg}
|
||||
local c_target = NumberField{parent=o_div,x=1,y=13,width=15,default=0,min=0,max_chars=16,align_right=true,fg_bg=field_fg_bg,dis_fg_bg=field_dis_fg_bg}
|
||||
TextBox{parent=o_div,x=17,y=13,text="M"..db.energy_label,fg_bg=label_fg_bg}
|
||||
--#region process control setpoints page
|
||||
|
||||
TextBox{parent=o_div,y=15,text="Generation Target",fg_bg=label_fg_bg}
|
||||
local g_target = NumberField{parent=o_div,x=1,y=16,width=15,default=0,min=0,max_chars=16,align_right=true,fg_bg=field_fg_bg,dis_fg_bg=field_dis_fg_bg}
|
||||
TextBox{parent=o_div,x=17,y=16,text="k"..db.energy_label.."/t",fg_bg=label_fg_bg}
|
||||
local s_pane = panes[db.facility.num_units + 4]
|
||||
local s_div = Div{parent=s_pane,x=2,width=main.get_width()-2}
|
||||
|
||||
local sp_page = app.new_page(nil, db.facility.num_units + 4)
|
||||
sp_page.tasks = { update }
|
||||
|
||||
TextBox{parent=s_div,y=1,text="Process Setpoints",alignment=ALIGN.CENTER}
|
||||
|
||||
TextBox{parent=s_div,y=3,text="Burn Rate Target",fg_bg=label_fg_bg}
|
||||
local b_target = NumberField{parent=s_div,y=4,width=15,default=0.01,min=0.01,max_frac_digits=2,max_chars=8,allow_decimal=true,align_right=true,fg_bg=field_fg_bg,dis_fg_bg=field_dis_fg_bg}
|
||||
TextBox{parent=s_div,x=17,y=4,text="mB/t",fg_bg=label_fg_bg}
|
||||
|
||||
TextBox{parent=s_div,y=6,text="Charge Level Target",fg_bg=label_fg_bg}
|
||||
local c_target = NumberField{parent=s_div,y=7,width=15,default=0,min=0,max_chars=16,align_right=true,fg_bg=field_fg_bg,dis_fg_bg=field_dis_fg_bg}
|
||||
TextBox{parent=s_div,x=17,y=7,text="M"..db.energy_label,fg_bg=label_fg_bg}
|
||||
|
||||
TextBox{parent=s_div,y=9,text="Generation Target",fg_bg=label_fg_bg}
|
||||
local g_target = NumberField{parent=s_div,y=10,width=15,default=0,min=0,max_chars=16,align_right=true,fg_bg=field_fg_bg,dis_fg_bg=field_dis_fg_bg}
|
||||
TextBox{parent=s_div,x=17,y=10,text="k"..db.energy_label.."/t",fg_bg=label_fg_bg}
|
||||
|
||||
local range_start, range_stop ---@type NumberField, NumberField
|
||||
|
||||
local function _update_start_val(value) range_start.set_value(math.min(range_start.get_value(), value - 1)) end
|
||||
local function _update_stop_val(value) range_stop.set_value(math.max(range_stop.get_value(), value + 1)) end
|
||||
|
||||
TextBox{parent=s_div,y=12,text="Charge Range - Start",fg_bg=label_fg_bg}
|
||||
range_start = NumberField{parent=s_div,y=13,width=15,default=0,min=0,max=99,align_right=true,on_unfocus=_update_stop_val,fg_bg=field_fg_bg,dis_fg_bg=field_dis_fg_bg}
|
||||
TextBox{parent=s_div,x=17,y=13,text="%",fg_bg=label_fg_bg}
|
||||
|
||||
TextBox{parent=s_div,y=15,text="Charge Range - Stop",fg_bg=label_fg_bg}
|
||||
range_stop = NumberField{parent=s_div,y=16,width=15,default=0,min=1,max=100,align_right=true,on_unfocus=_update_start_val,fg_bg=field_fg_bg,dis_fg_bg=field_dis_fg_bg}
|
||||
TextBox{parent=s_div,x=17,y=16,text="%",fg_bg=label_fg_bg}
|
||||
|
||||
b_target.register(f_ps, "process_burn_target", b_target.set_value)
|
||||
c_target.register(f_ps, "process_charge_target", c_target.set_value)
|
||||
g_target.register(f_ps, "process_gen_target", g_target.set_value)
|
||||
range_start.register(f_ps, "process_range_start", range_start.set_value)
|
||||
range_stop.register(f_ps, "process_range_stop", range_stop.set_value)
|
||||
|
||||
--#endregion
|
||||
|
||||
@@ -194,9 +242,9 @@ local function new_view(root)
|
||||
|
||||
TextBox{parent=c_div,y=1,text="Process Control",alignment=ALIGN.CENTER}
|
||||
|
||||
local u_stat = Rectangle{parent=c_div,border=border(1,colors.gray,true),thin=true,width=21,height=5,x=1,y=3,fg_bg=cpair(colors.black,colors.lightGray)}
|
||||
local stat_line_1 = TextBox{parent=u_stat,x=1,y=1,text="UNKNOWN",alignment=ALIGN.CENTER}
|
||||
local stat_line_2 = TextBox{parent=u_stat,x=1,y=2,text="awaiting data...",height=2,alignment=ALIGN.CENTER,trim_whitespace=true,fg_bg=cpair(colors.gray,colors.lightGray)}
|
||||
local u_stat = Rectangle{parent=c_div,border=border(1,colors.gray,true),thin=true,width=21,height=5,y=3,fg_bg=cpair(colors.black,colors.lightGray)}
|
||||
local stat_line_1 = TextBox{parent=u_stat,y=1,text="UNKNOWN",alignment=ALIGN.CENTER}
|
||||
local stat_line_2 = TextBox{parent=u_stat,y=2,text="awaiting data...",height=2,alignment=ALIGN.CENTER,trim_whitespace=true,fg_bg=cpair(colors.gray,colors.lightGray)}
|
||||
|
||||
stat_line_1.register(f_ps, "status_line_1", stat_line_1.set_value)
|
||||
stat_line_2.register(f_ps, "status_line_2", stat_line_2.set_value)
|
||||
@@ -205,8 +253,13 @@ local function new_view(root)
|
||||
local limits = {}
|
||||
for i = 1, #rate_limits do limits[i] = rate_limits[i].get_numeric() end
|
||||
|
||||
process.process_start(mode.get_value(), b_target.get_numeric(), db.energy_convert_to_fe(c_target.get_numeric()),
|
||||
db.energy_convert_to_fe(g_target.get_numeric()), limits)
|
||||
-- make sure stop is always above start (start maxes at 99 and stop maxes at 100 so this always works)
|
||||
if range_stop.get_value() <= range_start.get_value() then
|
||||
range_stop.set_value(range_start.get_value() + 1)
|
||||
end
|
||||
|
||||
process.process_start(mode.get_value(), b_target.get_numeric(), range_start.get_numeric(), range_stop.get_numeric(),
|
||||
db.energy_convert_to_fe(c_target.get_numeric()), db.energy_convert_to_fe(g_target.get_numeric()), limits)
|
||||
end
|
||||
|
||||
local start = HazardButton{parent=c_div,x=2,y=9,text="START",accent=colors.lightBlue,callback=_start_auto,timeout=3,fg_bg=hzd_fg_bg,dis_colors=dis_colors}
|
||||
@@ -237,6 +290,8 @@ local function new_view(root)
|
||||
b_target.disable()
|
||||
c_target.disable()
|
||||
g_target.disable()
|
||||
range_start.disable()
|
||||
range_stop.disable()
|
||||
|
||||
mode.disable()
|
||||
start.disable()
|
||||
@@ -246,6 +301,8 @@ local function new_view(root)
|
||||
b_target.enable()
|
||||
c_target.enable()
|
||||
g_target.enable()
|
||||
range_start.enable()
|
||||
range_stop.enable()
|
||||
|
||||
mode.enable()
|
||||
if db.facility.auto_ready then start.enable() end
|
||||
@@ -258,10 +315,10 @@ local function new_view(root)
|
||||
|
||||
--#region auto-SCRAM annunciator page
|
||||
|
||||
local a_pane = panes[db.facility.num_units + 3]
|
||||
local a_pane = panes[db.facility.num_units + 2]
|
||||
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)
|
||||
local annunc_page = app.new_page(nil, db.facility.num_units + 2)
|
||||
annunc_page.tasks = { update }
|
||||
|
||||
TextBox{parent=a_div,y=1,text="Automatic SCRAM",alignment=ALIGN.CENTER}
|
||||
@@ -291,7 +348,7 @@ local function new_view(root)
|
||||
--#endregion
|
||||
|
||||
-- setup multipane
|
||||
local u_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes}
|
||||
local u_pane = MultiPane{parent=page_div,y=1,panes=panes}
|
||||
app.set_root_pane(u_pane)
|
||||
|
||||
-- setup sidebar
|
||||
@@ -300,7 +357,8 @@ local function new_view(root)
|
||||
{ label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = db.nav.go_home },
|
||||
{ label = " \x17 ", color = core.cpair(colors.black, colors.purple), callback = proc_ctrl.nav_to },
|
||||
{ label = " \x13 ", color = core.cpair(colors.black, colors.red), callback = annunc_page.nav_to },
|
||||
{ label = "OPT", color = core.cpair(colors.black, colors.yellow), callback = opt_page.nav_to }
|
||||
{ label = " \x07 ", color = core.cpair(colors.black, colors.yellow), callback = mode_page.nav_to },
|
||||
{ label = " \x12 ", color = core.cpair(colors.black, colors.lightBlue), callback = sp_page.nav_to }
|
||||
}
|
||||
|
||||
for i = 1, db.facility.num_units do
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
local pocket = require("pocket.pocket")
|
||||
|
||||
local style = require("pocket.ui.style")
|
||||
@@ -33,19 +33,19 @@ local lu_col = style.label_unit_pair
|
||||
-- new radiation monitor page view
|
||||
---@param root Container parent
|
||||
local function new_view(root)
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local frame = Div{parent=root,x=1,y=1}
|
||||
local frame = Div{parent=root,y=1}
|
||||
|
||||
local app = db.nav.register_app(APP_ID.RADMON, frame, nil, false, true)
|
||||
|
||||
local load_div = Div{parent=frame,x=1,y=1}
|
||||
local main = Div{parent=frame,x=1,y=1}
|
||||
local load_div = Div{parent=frame,y=1}
|
||||
local main = Div{parent=frame,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.yellow,colors._INHERIT)}
|
||||
|
||||
local load_pane = MultiPane{parent=main,x=1,y=1,panes={load_div,main}}
|
||||
local load_pane = MultiPane{parent=main,y=1,panes={load_div,main}}
|
||||
|
||||
app.set_sidebar({ { label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = db.nav.go_home } })
|
||||
|
||||
@@ -174,7 +174,7 @@ local function new_view(root)
|
||||
--#endregion
|
||||
|
||||
-- setup multipane
|
||||
local u_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes}
|
||||
local u_pane = MultiPane{parent=page_div,y=1,panes=panes}
|
||||
app.set_root_pane(u_pane)
|
||||
|
||||
-- setup sidebar
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
local pocket = require("pocket.pocket")
|
||||
|
||||
local style = require("pocket.ui.style")
|
||||
@@ -49,19 +49,19 @@ local emc_ind_s = {
|
||||
-- new unit page view
|
||||
---@param root Container parent
|
||||
local function new_view(root)
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local frame = Div{parent=root,x=1,y=1}
|
||||
local frame = Div{parent=root,y=1}
|
||||
|
||||
local app = db.nav.register_app(APP_ID.UNITS, frame, nil, false, true)
|
||||
|
||||
local load_div = Div{parent=frame,x=1,y=1}
|
||||
local main = Div{parent=frame,x=1,y=1}
|
||||
local load_div = Div{parent=frame,y=1}
|
||||
local main = Div{parent=frame,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.yellow,colors._INHERIT)}
|
||||
|
||||
local load_pane = MultiPane{parent=main,x=1,y=1,panes={load_div,main}}
|
||||
local load_pane = MultiPane{parent=main,y=1,panes={load_div,main}}
|
||||
|
||||
app.set_sidebar({ { label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = db.nav.go_home } })
|
||||
|
||||
@@ -149,7 +149,7 @@ local function new_view(root)
|
||||
u_page.tasks = { update }
|
||||
|
||||
TextBox{parent=u_div,y=1,text="Reactor Unit #"..i,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,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")
|
||||
@@ -158,7 +158,7 @@ local function new_view(root)
|
||||
local rate = DataIndicator{parent=u_div,y=5,lu_colors=lu_col,label="Burn",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=db.temp_label,format="%10.2f",value=0,commas=true,width=26,fg_bg=text_fg}
|
||||
|
||||
local ctrl = IconIndicator{parent=u_div,x=1,y=8,label="Control State",states=mode_states}
|
||||
local ctrl = IconIndicator{parent=u_div,y=8,label="Control State",states=mode_states}
|
||||
|
||||
rate.register(u_ps, "act_burn_rate", rate.update)
|
||||
temp.register(u_ps, "temp", function (t) temp.update(db.temp_convert(t)) end)
|
||||
@@ -166,24 +166,24 @@ local function new_view(root)
|
||||
|
||||
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}
|
||||
local rct = IconIndicator{parent=u_div,label="Fission Reactor",states=basic_states}
|
||||
local rps = IconIndicator{parent=u_div,label="Protection System",states=basic_states}
|
||||
|
||||
rct.register(u_ps, "U_ReactorStatus", rct.update)
|
||||
rps.register(u_ps, "U_RPS", rps.update)
|
||||
|
||||
u_div.line_break()
|
||||
|
||||
local rcs = IconIndicator{parent=u_div,x=1,label="Coolant System",states=basic_states}
|
||||
local rcs = IconIndicator{parent=u_div,label="Coolant System",states=basic_states}
|
||||
rcs.register(u_ps, "U_RCS", rcs.update)
|
||||
|
||||
for b = 1, unit.num_boilers do
|
||||
local blr = IconIndicator{parent=u_div,x=1,label="Boiler "..b,states=basic_states}
|
||||
local blr = IconIndicator{parent=u_div,label="Boiler "..b,states=basic_states}
|
||||
blr.register(unit.boiler_ps_tbl[b], "BoilerStatus", blr.update)
|
||||
end
|
||||
|
||||
for t = 1, unit.num_turbines do
|
||||
local tbn = IconIndicator{parent=u_div,x=1,label="Turbine "..t,states=basic_states}
|
||||
local tbn = IconIndicator{parent=u_div,label="Turbine "..t,states=basic_states}
|
||||
tbn.register(unit.turbine_ps_tbl[t], "TurbineStatus", tbn.update)
|
||||
end
|
||||
|
||||
@@ -377,7 +377,7 @@ local function new_view(root)
|
||||
end
|
||||
|
||||
-- setup multipane
|
||||
local u_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes}
|
||||
local u_pane = MultiPane{parent=page_div,y=1,panes=panes}
|
||||
app.set_root_pane(u_pane)
|
||||
|
||||
set_sidebar(active_unit)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
local pocket = require("pocket.pocket")
|
||||
local process = require("pocket.process")
|
||||
|
||||
@@ -40,19 +40,19 @@ local wht_ind_s = style.icon_states.wht_ind_s
|
||||
-- new waste control page view
|
||||
---@param root Container parent
|
||||
local function new_view(root)
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local frame = Div{parent=root,x=1,y=1}
|
||||
local frame = Div{parent=root,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}
|
||||
local load_div = Div{parent=frame,y=1}
|
||||
local main = Div{parent=frame,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}}
|
||||
local load_pane = MultiPane{parent=main,y=1,panes={load_div,main}}
|
||||
|
||||
app.set_sidebar({ { label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = db.nav.go_home } })
|
||||
|
||||
@@ -262,7 +262,7 @@ local function new_view(root)
|
||||
--#endregion
|
||||
|
||||
-- setup multipane
|
||||
local w_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes}
|
||||
local w_pane = MultiPane{parent=page_div,y=1,panes=panes}
|
||||
app.set_root_pane(w_pane)
|
||||
|
||||
-- setup sidebar
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
-- Connection Waiting Spinner
|
||||
--
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
|
||||
local style = require("pocket.ui.style")
|
||||
|
||||
@@ -22,10 +22,10 @@ local cpair = core.cpair
|
||||
---@param y integer y offset
|
||||
local function init(parent, y, is_api)
|
||||
-- root div
|
||||
local root = Div{parent=parent,x=1,y=1}
|
||||
local root = Div{parent=parent,y=1}
|
||||
|
||||
-- bounding box div
|
||||
local box = Div{parent=root,x=1,y=y,height=12}
|
||||
local box = Div{parent=root,y=y,height=12}
|
||||
|
||||
local waiting_x = math.floor(parent.get_width() / 2) - 1
|
||||
|
||||
@@ -34,11 +34,11 @@ local function init(parent, y, is_api)
|
||||
if is_api then
|
||||
WaitingAnim{parent=box,x=waiting_x,y=1,fg_bg=cpair(colors.blue,style.root.bkg)}
|
||||
TextBox{parent=box,y=5,text="Connecting to API",alignment=ALIGN.CENTER,fg_bg=cpair(colors.white,style.root.bkg),trim_whitespace=true}
|
||||
msg.register(iocontrol.get_db().ps, "api_link_msg", msg.set_value)
|
||||
msg.register(ioctl.get_db().ps, "api_link_msg", msg.set_value)
|
||||
else
|
||||
WaitingAnim{parent=box,x=waiting_x,y=1,fg_bg=cpair(colors.green,style.root.bkg)}
|
||||
TextBox{parent=box,y=5,text="Connecting to Supervisor",alignment=ALIGN.CENTER,fg_bg=cpair(colors.white,style.root.bkg),trim_whitespace=true}
|
||||
msg.register(iocontrol.get_db().ps, "svr_link_msg", msg.set_value)
|
||||
msg.register(ioctl.get_db().ps, "svr_link_msg", msg.set_value)
|
||||
end
|
||||
|
||||
return root
|
||||
|
||||
@@ -95,7 +95,7 @@ text("A wired modem is only connected to the block when you right click it and i
|
||||
tip("Do not connect all peripherals in the system on the same network cable, since Reactor PLCs will grab the first reactor they find and you may accidentally duplicate RTUs.")
|
||||
sect("Computer Conns")
|
||||
tip("It helps to be familiar with how ComputerCraft manages peripherals before using this system, though it is not necessary.")
|
||||
doc("usage_conn_network", "Network", "All computers in the system communicate with each other via wireless or ender modems. Ender modems are preferred due to the unlimited range.")
|
||||
doc("usage_conn_network", "Network", "All computers in the system communicate with each other via wired, wireless, and/or Ender modems. Ender modems are preferred over wireless due to the unlimited range.")
|
||||
text("Five different network channels are used and must have the same value for each name across all devices.")
|
||||
text("For example, the supervisor channel SVR_CHANNEL must be set to the same channel for all devices in your system. Two different named channels should not share the same value (such as SVR_CHANNEL vs CRD_CHANNEL).")
|
||||
doc("usage_conn_peri", "Peripherals", "ComputerCraft peripherals like monitors and speakers need to touch the computer or be connected via wired modems.")
|
||||
@@ -167,10 +167,11 @@ doc("usage_auto_setpoints", "Setpoints", "Three setpoint spinner inputs are avai
|
||||
doc("usage_auto_limits", "Unit Limits", "Each unit can be limited to a maximum auto control burn rate to prevent exceeding any safe levels that you know of.")
|
||||
doc("usage_auto_states", "Unit States", "Any assigned units must be shown as Ready and not Degraded to use auto control. See Operator UIs > Coordinator > Main Display for more.")
|
||||
sect("Operation Modes")
|
||||
text("Four auto control modes are available that function based on configurations set on the main display. All modes except Monitored Max Burn will try to only use the primary group until it can't keep up, then the secondary, etc.")
|
||||
text("Five auto control modes are available that function based on configurations set on the main display. All modes except Monitored Max Burn and Charge Range will try to only use the primary group until it can't keep up, then the secondary, etc.")
|
||||
note("No units will be set to a burn rate higher than their limit.")
|
||||
doc("usage_op_mon_max", "Monitored Max Burn", "This mode runs all units assigned to auto control at their unit limit burn rate regardless of priority group.")
|
||||
doc("usage_op_com_rate", "Combined Burn Rate", "Assigned units will be commanded to meet the Burn Target setpoint.")
|
||||
doc("usage_op_chg_range", "Charge Range", "This mode runs all units assigned to auto control at their unit limit burn rate regardless of priority group if the charge percentage drops to the start threshold until it reaches the stop threshold, keeping it within that range.")
|
||||
doc("usage_op_chg_level", "Charge Level", "Assigned units will be commanded to bring the induction matrix up to the requested Charge Target.")
|
||||
doc("usage_op_gen_rate", "Generation Rate", "Assigned units will be commanded to maintain the requested Generation Target.")
|
||||
note("The rate used is the input rate into the induction matrix, so using other power generation sources may disrupt this control mode.")
|
||||
@@ -324,7 +325,9 @@ doc("ui_fac_rad", "Radiation", "The facility radiation, which is the current max
|
||||
doc("ui_fac_linked", "Linked RTUs", "The number of RTU Gateways connected.")
|
||||
sect("Automatic Control")
|
||||
text("This interface is used for managing automatic facility control, which only applies to units set via the unit display to be under auto control. This includes setpoints, status, configuration, and control.")
|
||||
doc("ui_fac_auto_alt", "\x12T/\x12R", "This selector next to Charge Target/Range lets you toggle between charge target and charge range control.")
|
||||
doc("ui_fac_auto_bt", "Burn Target", "When set to Combined Burn Rate mode, assigned units will ramp up to meet this combined target.")
|
||||
doc("ui_fac_auto_cr", "Charge Range", "When set to Charge Range mode, assigned units will run once the induction matrix charge percentage falls to the start threshold until it reaches the stop threshold, keeping it within the range.")
|
||||
doc("ui_fac_auto_ct", "Charge Target", "When set to Charge Level mode, assigned units will run to reach and maintain this induction matrix charge level.")
|
||||
doc("ui_fac_auto_gt", "Gen. Target", "When set to Generation Rate mode, assigned units will run to reach and maintain this continuous power output, using the induction matrix input rate.")
|
||||
doc("ui_fac_save", "SAVE", "This saves your configuration without starting control.")
|
||||
@@ -427,15 +430,21 @@ sect("Core Status")
|
||||
doc("fp_status", "STATUS", "This is always lit, except on the Reactor PLC (see Reactor PLC section).")
|
||||
doc("fp_heartbeat", "HEARTBEAT", "This alternates between lit and unlit as the main loop on the device runs. If this freezes, something is wrong and the logs will indicate why.")
|
||||
sect("Hardware & Network")
|
||||
doc("fp_modem", "MODEM", "This lights up if the wireless/ender modem is connected. In parentheses is the unique computer ID of this device, which will show up in places such as the Supervisor's connection lists.")
|
||||
doc("fp_modem", "NETWORK", "This is present when in standard color modes and indicates the network status using multiple colors.")
|
||||
doc("fp_modem", "MODEM", "This indicates the status of the comms modem, if you only have one. If you have two, they will be named WD/WL MODEM.")
|
||||
list(DOC_LIST_TYPE.LED, { "disconnected", "link down", "link up" }, { colors.gray, colors.yellow, colors.green })
|
||||
doc("fp_modem", "WD MODEM", "This indicates the status of the wired comms modem.")
|
||||
list(DOC_LIST_TYPE.LED, { "disconnected", "link down", "link up" }, { colors.gray, colors.yellow, colors.green })
|
||||
doc("fp_modem", "WL MODEM", "This indicates the status of the wireless/Ender comms modem.")
|
||||
list(DOC_LIST_TYPE.LED, { "disconnected", "link down", "link up" }, { colors.gray, colors.yellow, colors.green })
|
||||
doc("fp_network", "NETWORK", "This is present when in standard color modes and indicates the network status using multiple colors.")
|
||||
list(DOC_LIST_TYPE.LED, { "not linked", "linked", "link denied", "bad comms version", "duplicate PLC" }, { colors.gray, colors.green, colors.red, colors.orange, colors.yellow })
|
||||
text("You can fix \"bad comms version\" by ensuring all devices are up-to-date, as this indicates a communications protocol version mismatch. Note that yellow is Reactor PLC-specific, indicating duplicate unit IDs in use.")
|
||||
doc("fp_nt_linked", "NT LINKED", "(color accessibility modes only)", "This indicates the device is linked to the Supervisor.")
|
||||
doc("fp_nt_version", "NT VERSION", "(color accessibility modes only)", "This indicates the communications versions of the Supervisor and this device do not match. Make sure everything is up-to-date.")
|
||||
sect("Versions")
|
||||
sect("Hardware Labels")
|
||||
doc("fp_fw", "FW", "Firmware application version of this device.")
|
||||
doc("fp_nt", "NT", "Network (comms) version this device has. These must match between devices in order for them to connect.")
|
||||
doc("fp_sn", "SN", "Device \"serial number\", made up of the Computer ID (shown on the Supervisor, Coordinator, and Pocket connection lists) and the device type.")
|
||||
|
||||
target = docs.fp.r_plc
|
||||
sect("Overview")
|
||||
@@ -518,10 +527,12 @@ text("This tab includes information about the Coordinator, partially covered by
|
||||
doc("fp_crd_rt_main", "RT MAIN", "This indicates that the device's main loop co-routine is running.")
|
||||
doc("fp_crd_rt_render", "RT RENDER", "This indicates that the Coordinator graphics renderer co-routine is running.")
|
||||
doc("fp_crd_spkr", "SPEAKER", "This indicates if the speaker is connected.")
|
||||
list(DOC_LIST_TYPE.LED, { "Disconnected", "Display View Unloaded", "Display View Loaded" }, { colors.gray, colors.red, colors.green })
|
||||
doc("fp_crd_mon_main", "MAIN DISPLAY", "The connection status of the main display monitor.")
|
||||
doc("fp_crd_mon_flow", "FLOW DISPLAY", "The connection status of the coolant and waste flow display monitor.")
|
||||
doc("fp_crd_mon_unit", "UNIT X DISPLAY", "The connection status of the monitor associated with a given unit.")
|
||||
doc("fp_crd_mon_main", "MAIN DISPLAY", "The status of the main display monitor.")
|
||||
list(DOC_LIST_TYPE.LED, { "disconnected", "view unloaded", "view loaded" }, { colors.gray, colors.red, colors.green })
|
||||
doc("fp_crd_mon_flow", "FLOW DISPLAY", "The status of the coolant and waste flow display monitor.")
|
||||
list(DOC_LIST_TYPE.LED, { "disconnected", "view unloaded", "view loaded" }, { colors.gray, colors.red, colors.green })
|
||||
doc("fp_crd_mon_unit", "UNIT X DISPLAY", "The status of the monitor associated with a given unit.")
|
||||
list(DOC_LIST_TYPE.LED, { "disconnected", "view unloaded", "view loaded" }, { colors.gray, colors.red, colors.green })
|
||||
sect("API Tab")
|
||||
text("This tab lists connected pocket computers. Refer to the Supervisor PKT tab documentation for details on fields.")
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
local pocket = require("pocket.pocket")
|
||||
|
||||
local about_app = require("pocket.ui.apps.about")
|
||||
@@ -44,7 +44,7 @@ local APP_ID = pocket.APP_ID
|
||||
-- create new main view
|
||||
---@param main DisplayBox main displaybox
|
||||
local function init(main)
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
-- window header message and connection status
|
||||
TextBox{parent=main,y=1,text=" S C ",fg_bg=style.header}
|
||||
@@ -54,13 +54,13 @@ local function init(main)
|
||||
db.ps.subscribe("svr_conn_quality", svr_conn.set_value)
|
||||
db.ps.subscribe("crd_conn_quality", crd_conn.set_value)
|
||||
|
||||
local start_pane = Div{parent=main,x=1,y=2}
|
||||
local main_pane = Div{parent=main,x=1,y=2}
|
||||
local start_pane = Div{parent=main,y=2}
|
||||
local main_pane = Div{parent=main,y=2}
|
||||
|
||||
WaitingAnim{parent=start_pane,x=12,y=7,fg_bg=cpair(colors.lightBlue,style.root.bkg)}
|
||||
TextBox{parent=start_pane,y=11,text="starting up...",alignment=ALIGN.CENTER,fg_bg=cpair(colors.lightGray,style.root.bkg)}
|
||||
|
||||
local root_pane = MultiPane{parent=main,x=1,y=2,panes={start_pane,main_pane}}
|
||||
local root_pane = MultiPane{parent=main,y=2,panes={start_pane,main_pane}}
|
||||
|
||||
local page_div = Div{parent=main_pane,x=4,y=1}
|
||||
|
||||
@@ -81,10 +81,10 @@ local function init(main)
|
||||
-- verify all apps were created
|
||||
assert(util.table_len(db.nav.get_containers()) == APP_ID.NUM_APPS, "app IDs were not sequential or some apps weren't registered")
|
||||
|
||||
db.nav.set_pane(MultiPane{parent=page_div,x=1,y=1,panes=db.nav.get_containers()})
|
||||
db.nav.set_sidebar(Sidebar{parent=main_pane,x=1,y=1,height=18,fg_bg=cpair(colors.white,colors.gray)})
|
||||
db.nav.set_pane(MultiPane{parent=page_div,y=1,panes=db.nav.get_containers()})
|
||||
db.nav.set_sidebar(Sidebar{parent=main_pane,y=1,height=18,fg_bg=cpair(colors.white,colors.gray)})
|
||||
|
||||
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,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.go_home()
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
local types = require("scada-common.types")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
|
||||
local style = require("pocket.ui.style")
|
||||
|
||||
@@ -43,7 +43,7 @@ local mode_ind_s = {
|
||||
---@param ps psil
|
||||
---@param update function
|
||||
return function (app, page, panes, tank_pane, tank_id, ps, update)
|
||||
local fac = iocontrol.get_db().facility
|
||||
local fac = ioctl.get_db().facility
|
||||
|
||||
local tank_div = Div{parent=tank_pane,x=2,width=tank_pane.get_width()-2}
|
||||
table.insert(panes, tank_div)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
-- Induction Matrix View
|
||||
--
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
|
||||
local style = require("pocket.ui.style")
|
||||
|
||||
@@ -36,7 +36,7 @@ local wht_ind_s = style.icon_states.wht_ind_s
|
||||
---@param ps psil
|
||||
---@param update function
|
||||
return function (app, panes, matrix_pane, ps, update)
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
local fac = db.facility
|
||||
|
||||
local mtx_div = Div{parent=matrix_pane,x=2,width=matrix_pane.get_width()-2}
|
||||
@@ -95,7 +95,7 @@ return function (app, panes, matrix_pane, ps, update)
|
||||
local chging = IconIndicator{parent=mtx_ext_div,y=3,label="Charging",states=wht_ind_s}
|
||||
local dischg = IconIndicator{parent=mtx_ext_div,y=4,label="Discharging",states=wht_ind_s}
|
||||
|
||||
TextBox{parent=mtx_ext_div,text="Energy Fill",x=1,y=6,width=13,fg_bg=label}
|
||||
TextBox{parent=mtx_ext_div,text="Energy Fill",y=6,width=13,fg_bg=label}
|
||||
local fill = DataIndicator{parent=mtx_ext_div,x=14,y=6,lu_colors=lu_col,label="",unit="%",format="%6.2f",value=0,width=8,fg_bg=text_fg}
|
||||
|
||||
chging.register(ps, "is_charging", chging.update)
|
||||
@@ -104,18 +104,18 @@ return function (app, panes, matrix_pane, ps, update)
|
||||
|
||||
local max_io = IconIndicator{parent=mtx_ext_div,y=8,label="Max I/O Rate",states=yel_ind_s}
|
||||
|
||||
TextBox{parent=mtx_ext_div,text="Input Util.",x=1,y=10,width=13,fg_bg=label}
|
||||
TextBox{parent=mtx_ext_div,text="Input Util.",y=10,width=13,fg_bg=label}
|
||||
local in_util = DataIndicator{parent=mtx_ext_div,x=14,y=10,lu_colors=lu_col,label="",unit="%",format="%6.2f",value=0,width=8,fg_bg=text_fg}
|
||||
TextBox{parent=mtx_ext_div,text="Output Util.",x=1,y=11,width=13,fg_bg=label}
|
||||
TextBox{parent=mtx_ext_div,text="Output Util.",y=11,width=13,fg_bg=label}
|
||||
local out_util = DataIndicator{parent=mtx_ext_div,x=14,y=11,lu_colors=lu_col,label="",unit="%",format="%6.2f",value=0,width=8,fg_bg=text_fg}
|
||||
|
||||
max_io.register(ps, "at_max_io", max_io.update)
|
||||
in_util.register(ps, "last_input", function (x) in_util.update(calc_saturation(x) * 100) end)
|
||||
out_util.register(ps, "last_output", function (x) out_util.update(calc_saturation(x) * 100) end)
|
||||
|
||||
TextBox{parent=mtx_ext_div,text="Capacity ("..db.energy_label..")",x=1,y=13,fg_bg=label}
|
||||
TextBox{parent=mtx_ext_div,text="Capacity ("..db.energy_label..")",y=13,fg_bg=label}
|
||||
local capacity = DataIndicator{parent=mtx_ext_div,y=14,lu_colors=lu_col,label="",unit="",format="%21d",value=0,width=21,fg_bg=text_fg}
|
||||
TextBox{parent=mtx_ext_div,text="Max In/Out ("..db.energy_label.."/t)",x=1,y=15,fg_bg=label}
|
||||
TextBox{parent=mtx_ext_div,text="Max In/Out ("..db.energy_label.."/t)",y=15,fg_bg=label}
|
||||
local trans_cap = DataIndicator{parent=mtx_ext_div,y=16,lu_colors=lu_col,label="",unit="",format="%21d",rate=true,value=0,width=21,fg_bg=text_fg}
|
||||
|
||||
capacity.register(ps, "max_energy", function (val) capacity.update(db.energy_convert(val)) end)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
-- SPS View
|
||||
--
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
|
||||
local style = require("pocket.ui.style")
|
||||
|
||||
@@ -31,7 +31,7 @@ local text_fg = style.text_fg
|
||||
---@param ps psil
|
||||
---@param update function
|
||||
return function (app, panes, sps_pane, ps, update)
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local sps_div = Div{parent=sps_pane,x=2,width=sps_pane.get_width()-2}
|
||||
table.insert(panes, sps_div)
|
||||
@@ -70,16 +70,16 @@ return function (app, panes, sps_pane, ps, update)
|
||||
|
||||
TextBox{parent=sps_ext_div,y=1,text="More SPS Info",alignment=ALIGN.CENTER}
|
||||
|
||||
TextBox{parent=sps_ext_div,text="Polonium",x=1,y=3,width=13,fg_bg=label}
|
||||
TextBox{parent=sps_ext_div,text="Polonium",y=3,width=13,fg_bg=label}
|
||||
local input_p = DataIndicator{parent=sps_ext_div,x=14,y=3,lu_colors=lu_col,label="",unit="%",format="%6.2f",value=0,width=8,fg_bg=text_fg}
|
||||
local input_amnt = DataIndicator{parent=sps_ext_div,x=1,y=4,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
local input_amnt = DataIndicator{parent=sps_ext_div,y=4,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
|
||||
input_p.register(ps, "input_fill", function (x) input_p.update(x * 100) end)
|
||||
input_amnt.register(ps, "input", function (x) input_amnt.update(x.amount) end)
|
||||
|
||||
TextBox{parent=sps_ext_div,text="Antimatter",x=1,y=6,width=15,fg_bg=label}
|
||||
TextBox{parent=sps_ext_div,text="Antimatter",y=6,width=15,fg_bg=label}
|
||||
local output_p = DataIndicator{parent=sps_ext_div,x=14,y=6,lu_colors=lu_col,label="",unit="%",format="%6.2f",value=0,width=8,fg_bg=text_fg}
|
||||
local output_amnt = DataIndicator{parent=sps_ext_div,x=1,y=7,lu_colors=lu_col,label="",unit="\xb5B",format="%18.3f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
local output_amnt = DataIndicator{parent=sps_ext_div,y=7,lu_colors=lu_col,label="",unit="\xb5B",format="%18.3f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
|
||||
output_p.register(ps, "output_fill", function (x) output_p.update(x * 100) end)
|
||||
output_amnt.register(ps, "output", function (x) output_amnt.update(x.amount) end)
|
||||
|
||||
@@ -46,8 +46,8 @@ return function (data, base_page, title, items, scroll_height)
|
||||
TextBox{parent=section_view_div,y=1,text=title,alignment=ALIGN.CENTER}
|
||||
PushButton{parent=section_view_div,x=2,y=1,text="<",fg_bg=btn_fg_bg,active_fg_bg=btn_active,callback=section_page.nav_to}
|
||||
|
||||
local name_list = ListBox{parent=section_div,x=1,y=3,scroll_height=60,nav_fg_bg=cpair(colors.lightGray,colors.gray),nav_active=cpair(colors.white,colors.gray)}
|
||||
local def_list = ListBox{parent=section_view_div,x=1,y=3,scroll_height=scroll_height,nav_fg_bg=cpair(colors.lightGray,colors.gray),nav_active=cpair(colors.white,colors.gray)}
|
||||
local name_list = ListBox{parent=section_div,y=3,scroll_height=60,nav_fg_bg=cpair(colors.lightGray,colors.gray),nav_active=cpair(colors.white,colors.gray)}
|
||||
local def_list = ListBox{parent=section_view_div,y=3,scroll_height=scroll_height,nav_fg_bg=cpair(colors.lightGray,colors.gray),nav_active=cpair(colors.white,colors.gray)}
|
||||
|
||||
local sect_id = 1
|
||||
local page_end
|
||||
@@ -62,7 +62,7 @@ return function (data, base_page, title, items, scroll_height)
|
||||
local title_offs = string.len(title_text) + 2
|
||||
|
||||
local sect_title = Div{parent=def_list,height=1}
|
||||
TextBox{parent=sect_title,x=1,text=title_text,fg_bg=cpair(colors.lightGray,colors.black)}
|
||||
TextBox{parent=sect_title,text=title_text,fg_bg=cpair(colors.lightGray,colors.black)}
|
||||
local anchor = TextBox{parent=sect_title,x=title_offs,y=1,text=item.name,anchor=true,fg_bg=cpair(colors.green,colors.black)}
|
||||
|
||||
page_end = Div{parent=def_list,height=1,can_focus=true}
|
||||
@@ -80,7 +80,7 @@ return function (data, base_page, title, items, scroll_height)
|
||||
table.insert(search_db, { string.lower(item.name), item.name, title, view })
|
||||
|
||||
local name_title = Div{parent=name_list,height=1}
|
||||
TextBox{parent=name_title,x=1,text=title_text,fg_bg=cpair(colors.lightGray,colors.black)}
|
||||
TextBox{parent=name_title,text=title_text,fg_bg=cpair(colors.lightGray,colors.black)}
|
||||
PushButton{parent=name_title,x=title_offs,y=1,text=item.name,alignment=ALIGN.LEFT,fg_bg=cpair(colors.green,colors.black),active_fg_bg=btn_active,callback=view}
|
||||
|
||||
sect_id = sect_id + 1
|
||||
@@ -107,7 +107,7 @@ return function (data, base_page, title, items, scroll_height)
|
||||
table.insert(search_db, { string.lower(item.name), item.name, title, view })
|
||||
|
||||
local name_entry = Div{parent=name_list,height=#util.strwrap(item.name,name_list.get_width()-3)}
|
||||
TextBox{parent=name_entry,x=1,text="\x10",fg_bg=cpair(colors.gray,colors.black)}
|
||||
TextBox{parent=name_entry,text="\x10",fg_bg=cpair(colors.gray,colors.black)}
|
||||
PushButton{parent=name_entry,x=3,y=1,text=item.name,alignment=ALIGN.LEFT,fg_bg=cpair(colors.blue,colors.black),active_fg_bg=btn_active,callback=view}
|
||||
elseif item.type == DOC_TYPE.TEXT then
|
||||
---@cast item pocket_doc_text
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
-- Main Home Page
|
||||
--
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
local pocket = require("pocket.pocket")
|
||||
|
||||
local core = require("graphics.core")
|
||||
@@ -19,18 +19,18 @@ local APP_ID = pocket.APP_ID
|
||||
-- new home page view
|
||||
---@param root Container parent
|
||||
local function new_view(root)
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local main = Div{parent=root,x=1,y=1,height=19}
|
||||
local main = Div{parent=root,y=1,height=19}
|
||||
|
||||
local app = db.nav.register_app(APP_ID.ROOT, main)
|
||||
|
||||
local apps_1 = Div{parent=main,x=1,y=1,height=15}
|
||||
local apps_2 = Div{parent=main,x=1,y=1,height=15}
|
||||
local apps_1 = Div{parent=main,y=1,height=15}
|
||||
local apps_2 = Div{parent=main,y=1,height=15}
|
||||
|
||||
local panes = { apps_1, apps_2 }
|
||||
|
||||
local app_pane = AppMultiPane{parent=main,x=1,y=1,height=18,panes=panes,active_color=colors.lightGray,nav_colors=cpair(colors.lightGray,colors.gray),scroll_nav=true,drag_nav=true,callback=app.switcher}
|
||||
local app_pane = AppMultiPane{parent=main,y=1,height=18,panes=panes,active_color=colors.lightGray,nav_colors=cpair(colors.lightGray,colors.gray),scroll_nav=true,drag_nav=true,callback=app.switcher}
|
||||
|
||||
app.set_root_pane(app_pane)
|
||||
app.new_page(app.new_page(nil, 1), 2)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
local types = require("scada-common.types")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
|
||||
local style = require("pocket.ui.style")
|
||||
|
||||
@@ -39,7 +39,7 @@ local yel_ind_s = style.icon_states.yel_ind_s
|
||||
---@param ps psil
|
||||
---@param update function
|
||||
return function (app, u_page, panes, blr_pane, b_id, ps, update)
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local blr_div = Div{parent=blr_pane,x=2,width=blr_pane.get_width()-2}
|
||||
table.insert(panes, blr_div)
|
||||
@@ -51,12 +51,12 @@ return function (app, u_page, panes, blr_pane, b_id, ps, update)
|
||||
local status = StateIndicator{parent=blr_div,x=10,y=1,states=style.boiler.states,value=1,min_width=12}
|
||||
status.register(ps, "BoilerStateStatus", status.update)
|
||||
|
||||
local hcool = VerticalBar{parent=blr_div,x=1,y=4,fg_bg=cpair(colors.orange,colors.gray),height=5,width=1}
|
||||
local hcool = VerticalBar{parent=blr_div,y=4,fg_bg=cpair(colors.orange,colors.gray),height=5,width=1}
|
||||
local water = VerticalBar{parent=blr_div,x=3,y=4,fg_bg=cpair(colors.blue,colors.gray),height=5,width=1}
|
||||
local steam = VerticalBar{parent=blr_div,x=19,y=4,fg_bg=cpair(colors.white,colors.gray),height=5,width=1}
|
||||
local ccool = VerticalBar{parent=blr_div,x=21,y=4,fg_bg=cpair(colors.lightBlue,colors.gray),height=5,width=1}
|
||||
|
||||
TextBox{parent=blr_div,text="H",x=1,y=3,width=1,fg_bg=label}
|
||||
TextBox{parent=blr_div,text="H",y=3,width=1,fg_bg=label}
|
||||
TextBox{parent=blr_div,text="W",x=3,y=3,width=1,fg_bg=label}
|
||||
TextBox{parent=blr_div,text="S",x=19,y=3,width=1,fg_bg=label}
|
||||
TextBox{parent=blr_div,text="C",x=21,y=3,width=1,fg_bg=label}
|
||||
@@ -78,7 +78,7 @@ return function (app, u_page, panes, blr_pane, b_id, ps, update)
|
||||
b_wll.register(ps, "WaterLevelLow", b_wll.update)
|
||||
b_hr.register(ps, "HeatingRateLow", b_hr.update)
|
||||
|
||||
TextBox{parent=blr_div,text="Boil Rate",x=1,y=13,width=12,fg_bg=label}
|
||||
TextBox{parent=blr_div,text="Boil Rate",y=13,width=12,fg_bg=label}
|
||||
local boil_r = DataIndicator{parent=blr_div,x=6,y=14,lu_colors=lu_col,label="",unit="mB/t",format="%11.0f",value=0,commas=true,width=16,fg_bg=text_fg}
|
||||
|
||||
boil_r.register(ps, "boil_rate", boil_r.update)
|
||||
@@ -98,35 +98,35 @@ return function (app, u_page, panes, blr_pane, b_id, ps, update)
|
||||
return function (x) indicator.update(x.amount) end
|
||||
end
|
||||
|
||||
TextBox{parent=blr_ext_div,text="Hot Coolant",x=1,y=3,width=12,fg_bg=label}
|
||||
TextBox{parent=blr_ext_div,text="Hot Coolant",y=3,width=12,fg_bg=label}
|
||||
local heated_p = DataIndicator{parent=blr_ext_div,x=14,y=3,lu_colors=lu_col,label="",unit="%",format="%6.2f",value=0,width=8,fg_bg=text_fg}
|
||||
local hcool_amnt = DataIndicator{parent=blr_ext_div,x=1,y=4,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
local hcool_amnt = DataIndicator{parent=blr_ext_div,y=4,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
|
||||
heated_p.register(ps, "hcool_fill", function (x) heated_p.update(x * 100) end)
|
||||
hcool_amnt.register(ps, "hcool", update_amount(hcool_amnt))
|
||||
|
||||
TextBox{parent=blr_ext_div,text="Water Tank",x=1,y=6,width=9,fg_bg=label}
|
||||
TextBox{parent=blr_ext_div,text="Water Tank",y=6,width=9,fg_bg=label}
|
||||
local fuel_p = DataIndicator{parent=blr_ext_div,x=14,y=6,lu_colors=lu_col,label="",unit="%",format="%6.2f",value=0,width=8,fg_bg=text_fg}
|
||||
local fuel_amnt = DataIndicator{parent=blr_ext_div,x=1,y=7,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
local fuel_amnt = DataIndicator{parent=blr_ext_div,y=7,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
|
||||
fuel_p.register(ps, "water_fill", function (x) fuel_p.update(x * 100) end)
|
||||
fuel_amnt.register(ps, "water", update_amount(fuel_amnt))
|
||||
|
||||
TextBox{parent=blr_ext_div,text="Steam Tank",x=1,y=9,width=10,fg_bg=label}
|
||||
TextBox{parent=blr_ext_div,text="Steam Tank",y=9,width=10,fg_bg=label}
|
||||
local steam_p = DataIndicator{parent=blr_ext_div,x=14,y=9,lu_colors=lu_col,label="",unit="%",format="%6.2f",value=0,width=8,fg_bg=text_fg}
|
||||
local steam_amnt = DataIndicator{parent=blr_ext_div,x=1,y=10,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
local steam_amnt = DataIndicator{parent=blr_ext_div,y=10,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
|
||||
steam_p.register(ps, "steam_fill", function (x) steam_p.update(x * 100) end)
|
||||
steam_amnt.register(ps, "steam", update_amount(steam_amnt))
|
||||
|
||||
TextBox{parent=blr_ext_div,text="Cool Coolant",x=1,y=12,width=12,fg_bg=label}
|
||||
TextBox{parent=blr_ext_div,text="Cool Coolant",y=12,width=12,fg_bg=label}
|
||||
local cooled_p = DataIndicator{parent=blr_ext_div,x=14,y=12,lu_colors=lu_col,label="",unit="%",format="%6.2f",value=0,width=8,fg_bg=text_fg}
|
||||
local ccool_amnt = DataIndicator{parent=blr_ext_div,x=1,y=13,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
local ccool_amnt = DataIndicator{parent=blr_ext_div,y=13,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
|
||||
cooled_p.register(ps, "ccool_fill", function (x) cooled_p.update(x * 100) end)
|
||||
ccool_amnt.register(ps, "ccool", update_amount(ccool_amnt))
|
||||
|
||||
TextBox{parent=blr_ext_div,text="Env. Loss",x=1,y=15,width=9,fg_bg=label}
|
||||
TextBox{parent=blr_ext_div,text="Env. Loss",y=15,width=9,fg_bg=label}
|
||||
local env_loss = DataIndicator{parent=blr_ext_div,x=11,y=15,lu_colors=lu_col,label="",unit="",format="%11.8f",value=0,width=11,fg_bg=text_fg}
|
||||
|
||||
env_loss.register(ps, "env_loss", env_loss.update)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
local types = require("scada-common.types")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
|
||||
local style = require("pocket.ui.style")
|
||||
|
||||
@@ -38,7 +38,7 @@ local yel_ind_s = style.icon_states.yel_ind_s
|
||||
---@param u_ps psil
|
||||
---@param update function
|
||||
return function (app, u_page, panes, page_div, u_ps, update)
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local rct_pane = Div{parent=page_div}
|
||||
local rct_div = Div{parent=rct_pane,x=2,width=page_div.get_width()-2}
|
||||
@@ -51,12 +51,12 @@ return function (app, u_page, panes, page_div, u_ps, update)
|
||||
local status = StateIndicator{parent=rct_div,x=10,y=1,states=style.reactor.states,value=1,min_width=12}
|
||||
status.register(u_ps, "U_ReactorStateStatus", status.update)
|
||||
|
||||
local fuel = VerticalBar{parent=rct_div,x=1,y=4,fg_bg=cpair(colors.lightGray,colors.gray),height=5,width=1}
|
||||
local fuel = VerticalBar{parent=rct_div,y=4,fg_bg=cpair(colors.lightGray,colors.gray),height=5,width=1}
|
||||
local ccool = VerticalBar{parent=rct_div,x=3,y=4,fg_bg=cpair(colors.blue,colors.gray),height=5,width=1}
|
||||
local hcool = VerticalBar{parent=rct_div,x=19,y=4,fg_bg=cpair(colors.white,colors.gray),height=5,width=1}
|
||||
local waste = VerticalBar{parent=rct_div,x=21,y=4,fg_bg=cpair(colors.brown,colors.gray),height=5,width=1}
|
||||
|
||||
TextBox{parent=rct_div,text="F",x=1,y=3,width=1,fg_bg=label}
|
||||
TextBox{parent=rct_div,text="F",y=3,width=1,fg_bg=label}
|
||||
TextBox{parent=rct_div,text="C",x=3,y=3,width=1,fg_bg=label}
|
||||
TextBox{parent=rct_div,text="H",x=19,y=3,width=1,fg_bg=label}
|
||||
TextBox{parent=rct_div,text="W",x=21,y=3,width=1,fg_bg=label}
|
||||
@@ -103,9 +103,9 @@ return function (app, u_page, panes, page_div, u_ps, update)
|
||||
r_wloc.register(u_ps, "WasteLineOcclusion", r_wloc.update)
|
||||
r_hsrt.register(u_ps, "HighStartupRate", r_hsrt.update)
|
||||
|
||||
TextBox{parent=rct_div,text="HR",x=1,y=16,width=4,fg_bg=label}
|
||||
TextBox{parent=rct_div,text="HR",y=16,width=4,fg_bg=label}
|
||||
local heating_r = DataIndicator{parent=rct_div,x=6,y=16,lu_colors=lu_col,label="",unit="mB/t",format="%11.0f",value=0,commas=true,width=16,fg_bg=text_fg}
|
||||
TextBox{parent=rct_div,text="DMG",x=1,y=17,width=4,fg_bg=label}
|
||||
TextBox{parent=rct_div,text="DMG",y=17,width=4,fg_bg=label}
|
||||
local damage_p = DataIndicator{parent=rct_div,x=6,y=17,lu_colors=lu_col,label="",unit="%",format="%11.2f",value=0,width=16,fg_bg=text_fg}
|
||||
|
||||
heating_r.register(u_ps, "heating_rate", heating_r.update)
|
||||
@@ -122,36 +122,36 @@ return function (app, u_page, panes, page_div, u_ps, update)
|
||||
|
||||
TextBox{parent=rct_ext_div,y=1,text="More Reactor Info",alignment=ALIGN.CENTER}
|
||||
|
||||
TextBox{parent=rct_ext_div,text="Fuel Tank",x=1,y=3,width=9,fg_bg=label}
|
||||
TextBox{parent=rct_ext_div,text="Fuel Tank",y=3,width=9,fg_bg=label}
|
||||
local fuel_p = DataIndicator{parent=rct_ext_div,x=14,y=3,lu_colors=lu_col,label="",unit="%",format="%6.2f",value=0,width=8,fg_bg=text_fg}
|
||||
local fuel_amnt = DataIndicator{parent=rct_ext_div,x=1,y=4,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
local fuel_amnt = DataIndicator{parent=rct_ext_div,y=4,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
|
||||
fuel_p.register(u_ps, "fuel_fill", function (x) fuel_p.update(x * 100) end)
|
||||
fuel_amnt.register(u_ps, "fuel", fuel_amnt.update)
|
||||
|
||||
TextBox{parent=rct_ext_div,text="Cool Coolant",x=1,y=6,width=12,fg_bg=label}
|
||||
TextBox{parent=rct_ext_div,text="Cool Coolant",y=6,width=12,fg_bg=label}
|
||||
local cooled_p = DataIndicator{parent=rct_ext_div,x=14,y=6,lu_colors=lu_col,label="",unit="%",format="%6.2f",value=0,width=8,fg_bg=text_fg}
|
||||
local ccool_amnt = DataIndicator{parent=rct_ext_div,x=1,y=7,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
local ccool_amnt = DataIndicator{parent=rct_ext_div,y=7,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
|
||||
cooled_p.register(u_ps, "ccool_fill", function (x) cooled_p.update(x * 100) end)
|
||||
ccool_amnt.register(u_ps, "ccool_amnt", ccool_amnt.update)
|
||||
|
||||
TextBox{parent=rct_ext_div,text="Hot Coolant",x=1,y=9,width=12,fg_bg=label}
|
||||
TextBox{parent=rct_ext_div,text="Hot Coolant",y=9,width=12,fg_bg=label}
|
||||
local heated_p = DataIndicator{parent=rct_ext_div,x=14,y=9,lu_colors=lu_col,label="",unit="%",format="%6.2f",value=0,width=8,fg_bg=text_fg}
|
||||
local hcool_amnt = DataIndicator{parent=rct_ext_div,x=1,y=10,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
local hcool_amnt = DataIndicator{parent=rct_ext_div,y=10,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
|
||||
heated_p.register(u_ps, "hcool_fill", function (x) heated_p.update(x * 100) end)
|
||||
hcool_amnt.register(u_ps, "hcool_amnt", hcool_amnt.update)
|
||||
|
||||
TextBox{parent=rct_ext_div,text="Waste Tank",x=1,y=12,width=10,fg_bg=label}
|
||||
TextBox{parent=rct_ext_div,text="Waste Tank",y=12,width=10,fg_bg=label}
|
||||
local waste_p = DataIndicator{parent=rct_ext_div,x=14,y=12,lu_colors=lu_col,label="",unit="%",format="%6.2f",value=0,width=8,fg_bg=text_fg}
|
||||
local waste_amnt = DataIndicator{parent=rct_ext_div,x=1,y=13,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
local waste_amnt = DataIndicator{parent=rct_ext_div,y=13,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
|
||||
waste_p.register(u_ps, "waste_fill", function (x) waste_p.update(x * 100) end)
|
||||
waste_amnt.register(u_ps, "waste", waste_amnt.update)
|
||||
|
||||
TextBox{parent=rct_ext_div,text="Boil Eff.",x=1,y=15,width=9,fg_bg=label}
|
||||
TextBox{parent=rct_ext_div,text="Env. Loss",x=1,y=16,width=9,fg_bg=label}
|
||||
TextBox{parent=rct_ext_div,text="Boil Eff.",y=15,width=9,fg_bg=label}
|
||||
TextBox{parent=rct_ext_div,text="Env. Loss",y=16,width=9,fg_bg=label}
|
||||
local boil_eff = DataIndicator{parent=rct_ext_div,x=11,y=15,lu_colors=lu_col,label="",unit="%",format="%9.2f",value=0,width=11,fg_bg=text_fg}
|
||||
local env_loss = DataIndicator{parent=rct_ext_div,x=11,y=16,lu_colors=lu_col,label="",unit="",format="%11.8f",value=0,width=11,fg_bg=text_fg}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("pocket.iocontrol")
|
||||
local ioctl = require("pocket.ioctl")
|
||||
|
||||
local style = require("pocket.ui.style")
|
||||
|
||||
@@ -41,7 +41,7 @@ local yel_ind_s = style.icon_states.yel_ind_s
|
||||
---@param ps psil
|
||||
---@param update function
|
||||
return function (app, u_page, panes, tbn_pane, u_id, t_id, ps, update)
|
||||
local db = iocontrol.get_db()
|
||||
local db = ioctl.get_db()
|
||||
|
||||
local tbn_div = Div{parent=tbn_pane,x=2,width=tbn_pane.get_width()-2}
|
||||
table.insert(panes, tbn_div)
|
||||
@@ -53,10 +53,10 @@ return function (app, u_page, panes, tbn_pane, u_id, t_id, ps, update)
|
||||
local status = StateIndicator{parent=tbn_div,x=10,y=1,states=style.turbine.states,value=1,min_width=12}
|
||||
status.register(ps, "TurbineStateStatus", status.update)
|
||||
|
||||
local steam = VerticalBar{parent=tbn_div,x=1,y=4,fg_bg=cpair(colors.white,colors.gray),height=5,width=1}
|
||||
local steam = VerticalBar{parent=tbn_div,y=4,fg_bg=cpair(colors.white,colors.gray),height=5,width=1}
|
||||
local ccool = VerticalBar{parent=tbn_div,x=21,y=4,fg_bg=cpair(colors.green,colors.gray),height=5,width=1}
|
||||
|
||||
TextBox{parent=tbn_div,text="S",x=1,y=3,width=1,fg_bg=label}
|
||||
TextBox{parent=tbn_div,text="S",y=3,width=1,fg_bg=label}
|
||||
TextBox{parent=tbn_div,text="E",x=21,y=3,width=1,fg_bg=label}
|
||||
|
||||
steam.register(ps, "steam_fill", steam.update)
|
||||
@@ -94,22 +94,22 @@ return function (app, u_page, panes, tbn_pane, u_id, t_id, ps, update)
|
||||
|
||||
TextBox{parent=tbn_ext_div,y=1,text="More Turbine Info",alignment=ALIGN.CENTER}
|
||||
|
||||
TextBox{parent=tbn_ext_div,text="Steam Tank",x=1,y=3,width=10,fg_bg=label}
|
||||
TextBox{parent=tbn_ext_div,text="Steam Tank",y=3,width=10,fg_bg=label}
|
||||
local steam_p = DataIndicator{parent=tbn_ext_div,x=14,y=3,lu_colors=lu_col,label="",unit="%",format="%6.2f",value=0,width=8,fg_bg=text_fg}
|
||||
local steam_amnt = DataIndicator{parent=tbn_ext_div,x=1,y=4,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
local steam_amnt = DataIndicator{parent=tbn_ext_div,y=4,lu_colors=lu_col,label="",unit="mB",format="%18.0f",value=0,commas=true,width=21,fg_bg=text_fg}
|
||||
|
||||
steam_p.register(ps, "steam_fill", function (x) steam_p.update(x * 100) end)
|
||||
steam_amnt.register(ps, "steam", function (x) steam_amnt.update(x.amount) end)
|
||||
|
||||
TextBox{parent=tbn_ext_div,text="Energy Fill",x=1,y=6,width=12,fg_bg=label}
|
||||
TextBox{parent=tbn_ext_div,text="Energy Fill",y=6,width=12,fg_bg=label}
|
||||
local charge_p = DataIndicator{parent=tbn_ext_div,x=14,y=6,lu_colors=lu_col,label="",unit="%",format="%6.2f",value=0,width=8,fg_bg=text_fg}
|
||||
local charge_amnt = PowerIndicator{parent=tbn_ext_div,x=1,y=7,lu_colors=lu_col,label="",unit=db.energy_label,format="%17.4f",value=0,width=21,fg_bg=text_fg}
|
||||
local charge_amnt = PowerIndicator{parent=tbn_ext_div,y=7,lu_colors=lu_col,label="",unit=db.energy_label,format="%17.4f",value=0,width=21,fg_bg=text_fg}
|
||||
|
||||
charge_p.register(ps, "energy_fill", function (x) charge_p.update(x * 100) end)
|
||||
charge_amnt.register(ps, "energy", function (val) charge_amnt.update(db.energy_convert(val)) end)
|
||||
|
||||
TextBox{parent=tbn_ext_div,text="Rotation Rate",x=1,y=9,width=13,fg_bg=label}
|
||||
local rotation = DataIndicator{parent=tbn_ext_div,x=1,y=10,lu_colors=lu_col,label="",unit="",format="%21.12f",value=0,width=21,fg_bg=text_fg}
|
||||
TextBox{parent=tbn_ext_div,text="Rotation Rate",y=9,width=13,fg_bg=label}
|
||||
local rotation = DataIndicator{parent=tbn_ext_div,y=10,lu_colors=lu_col,label="",unit="",format="%21.12f",value=0,width=21,fg_bg=text_fg}
|
||||
|
||||
rotation.register(ps, "steam", function ()
|
||||
local ok, result = pcall(function () return util.turbine_rotation(db.units[u_id].turbine_data_tbl[t_id]) end)
|
||||
|
||||
@@ -196,8 +196,6 @@ function backplane.attach(iface, type, device, print_no_fp)
|
||||
state.degraded = false
|
||||
end
|
||||
|
||||
_bp.smem.q.mq_rps.push_command(MQ__RPS_CMD.SCRAM)
|
||||
|
||||
sys.rps.reconnect_reactor(dev.reactor)
|
||||
if networked then
|
||||
sys.plc_comms.reconnect_reactor(dev.reactor)
|
||||
|
||||
@@ -209,9 +209,9 @@ function check.create(main_pane, settings_cfg, check_sys, style)
|
||||
|
||||
local sc = Div{parent=check_sys,x=2,y=4,width=49}
|
||||
|
||||
TextBox{parent=check_sys,x=1,y=2,text=" Reactor PLC Self-Check",fg_bg=bw_fg_bg}
|
||||
TextBox{parent=check_sys,y=2,text=" Reactor PLC Self-Check",fg_bg=bw_fg_bg}
|
||||
|
||||
self.sc_log = ListBox{parent=sc,x=1,y=1,height=12,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
self.sc_log = ListBox{parent=sc,y=1,height=12,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
local last_check = { nil, nil }
|
||||
|
||||
@@ -234,7 +234,7 @@ function check.create(main_pane, settings_cfg, check_sys, style)
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=sc,x=1,y=14,text="\x1b Back",callback=function()exit_self_check(main_pane)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sc,y=14,text="\x1b Back",callback=function()exit_self_check(main_pane)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
self.run_test_btn = PushButton{parent=sc,x=40,y=14,min_width=10,text="Run Test",callback=function()self_check()end,fg_bg=cpair(colors.black,colors.blue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
end
|
||||
|
||||
|
||||
@@ -90,28 +90,30 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
local plc_c_3 = Div{parent=plc_cfg,x=2,y=4,width=49}
|
||||
local plc_c_4 = Div{parent=plc_cfg,x=2,y=4,width=49}
|
||||
local plc_c_5 = Div{parent=plc_cfg,x=2,y=4,width=49}
|
||||
local plc_c_6 = Div{parent=plc_cfg,x=2,y=4,width=49}
|
||||
local plc_c_7 = Div{parent=plc_cfg,x=2,y=4,width=49}
|
||||
|
||||
local plc_pane = MultiPane{parent=plc_cfg,x=1,y=4,panes={plc_c_1,plc_c_2,plc_c_3,plc_c_4,plc_c_5}}
|
||||
local plc_pane = MultiPane{parent=plc_cfg,y=4,panes={plc_c_1,plc_c_2,plc_c_3,plc_c_4,plc_c_5,plc_c_6,plc_c_7}}
|
||||
|
||||
TextBox{parent=plc_cfg,x=1,y=2,text=" PLC Configuration",fg_bg=cpair(colors.black,colors.orange)}
|
||||
TextBox{parent=plc_cfg,y=2,text=" PLC Configuration",fg_bg=cpair(colors.black,colors.orange)}
|
||||
|
||||
TextBox{parent=plc_c_1,x=1,y=1,text="Would you like to set this PLC as networked?"}
|
||||
TextBox{parent=plc_c_1,x=1,y=3,height=4,text="If you have a supervisor, select the box. You will later be prompted to select the network configuration. If you instead want to use this as a standalone safety system, don't select the box.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=plc_c_1,y=1,text="Would you like to set this PLC as networked?"}
|
||||
TextBox{parent=plc_c_1,y=3,height=4,text="If you have a supervisor, select the box. You will later be prompted to select the network configuration. If you instead want to use this as a standalone safety system, don't select the box.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local networked = Checkbox{parent=plc_c_1,x=1,y=8,label="Networked",default=ini_cfg.Networked,box_fg_bg=cpair(colors.orange,colors.black)}
|
||||
local networked = Checkbox{parent=plc_c_1,y=8,label="Networked",default=ini_cfg.Networked,box_fg_bg=cpair(colors.orange,colors.black)}
|
||||
|
||||
local function submit_networked()
|
||||
self.set_networked(networked.get_value())
|
||||
plc_pane.set_value(2)
|
||||
end
|
||||
|
||||
PushButton{parent=plc_c_1,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=plc_c_1,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=plc_c_1,x=44,y=14,text="Next \x1a",callback=submit_networked,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=plc_c_2,x=1,y=1,text="Please enter the reactor unit ID for this PLC."}
|
||||
TextBox{parent=plc_c_2,x=1,y=3,height=3,text="If this is a networked PLC, currently only IDs 1 through 4 are acceptable.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=plc_c_2,y=1,text="Please enter the reactor unit ID for this PLC."}
|
||||
TextBox{parent=plc_c_2,y=3,height=3,text="If this is a networked PLC, currently only IDs 1 through 4 are acceptable.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=plc_c_2,x=1,y=6,text="Unit #"}
|
||||
TextBox{parent=plc_c_2,y=6,text="Unit #"}
|
||||
local u_id = NumberField{parent=plc_c_2,x=7,y=6,width=5,max_chars=3,default=ini_cfg.UnitID,min=1,fg_bg=bw_fg_bg}
|
||||
|
||||
local u_id_err = TextBox{parent=plc_c_2,x=8,y=14,width=35,text="Please set a unit ID.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
@@ -130,13 +132,13 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
else u_id_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=plc_c_2,x=1,y=14,text="\x1b Back",callback=function()plc_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=plc_c_2,y=14,text="\x1b Back",callback=function()plc_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=plc_c_2,x=44,y=14,text="Next \x1a",callback=submit_id,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=plc_c_3,x=1,y=1,height=4,text="When networked, the supervisor takes care of emergency coolant via RTUs. However, you can configure independent emergency coolant via the PLC."}
|
||||
TextBox{parent=plc_c_3,x=1,y=6,height=5,text="This independent control can be used with or without a supervisor. To configure, you would next select the interface of the redstone output connected to one or more mekanism pipes.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=plc_c_3,y=1,height=4,text="When networked, the supervisor takes care of emergency coolant via RTUs. However, you can configure independent emergency coolant via the PLC."}
|
||||
TextBox{parent=plc_c_3,y=6,height=5,text="This independent control can be used with or without a supervisor. To configure, you would next select the interface of the redstone output connected to one or more mekanism pipes.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local en_em_cool = Checkbox{parent=plc_c_3,x=1,y=11,label="Enable PLC Emergency Coolant Control",default=ini_cfg.EmerCoolEnable,box_fg_bg=cpair(colors.orange,colors.black)}
|
||||
local en_em_cool = Checkbox{parent=plc_c_3,y=11,label="Enable PLC Emergency Coolant Control",default=ini_cfg.EmerCoolEnable,box_fg_bg=cpair(colors.orange,colors.black)}
|
||||
|
||||
local function next_from_plc()
|
||||
if tmp_cfg.Networked then main_pane.set_value(3) else main_pane.set_value(4) end
|
||||
@@ -147,34 +149,65 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
if tmp_cfg.EmerCoolEnable then plc_pane.set_value(4) else next_from_plc() end
|
||||
end
|
||||
|
||||
PushButton{parent=plc_c_3,x=1,y=14,text="\x1b Back",callback=function()plc_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=plc_c_3,y=14,text="\x1b Back",callback=function()plc_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=plc_c_3,x=44,y=14,text="Next \x1a",callback=submit_en_emcool,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=plc_c_4,x=1,y=1,text="Emergency Coolant Redstone Output Side"}
|
||||
local side = Radio2D{parent=plc_c_4,x=1,y=2,rows=2,columns=3,default=side_to_idx(ini_cfg.EmerCoolSide),options=side_options,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.orange}
|
||||
TextBox{parent=plc_c_4,y=1,text="Emergency Coolant Redstone Output Side"}
|
||||
local side = Radio2D{parent=plc_c_4,y=2,rows=2,columns=3,default=side_to_idx(ini_cfg.EmerCoolSide),options=side_options,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.orange}
|
||||
|
||||
TextBox{parent=plc_c_4,x=1,y=5,text="Bundled Redstone Configuration"}
|
||||
local bundled = Checkbox{parent=plc_c_4,x=1,y=6,label="Is Bundled?",default=ini_cfg.EmerCoolColor~=nil,box_fg_bg=cpair(colors.orange,colors.black),callback=function(v)self.bundled_emcool(v)end}
|
||||
local color = Radio2D{parent=plc_c_4,x=1,y=8,rows=4,columns=4,default=color_to_idx(ini_cfg.EmerCoolColor),options=color_options,radio_colors=cpair(colors.lightGray,colors.black),color_map=color_options_map,disable_color=colors.gray,disable_fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=plc_c_4,y=5,text="Bundled Redstone Configuration"}
|
||||
local bundled = Checkbox{parent=plc_c_4,y=6,label="Is Bundled?",default=ini_cfg.EmerCoolColor~=nil,box_fg_bg=cpair(colors.orange,colors.black),callback=function(v)self.bundled_emcool(v)end}
|
||||
local color = Radio2D{parent=plc_c_4,y=8,rows=4,columns=4,default=color_to_idx(ini_cfg.EmerCoolColor),options=color_options,radio_colors=cpair(colors.lightGray,colors.black),color_map=color_options_map,disable_color=colors.gray,disable_fg_bg=g_lg_fg_bg}
|
||||
if ini_cfg.EmerCoolColor == nil then color.disable() end
|
||||
|
||||
function self.bundled_emcool(en) if en then color.enable() else color.disable() end end
|
||||
|
||||
TextBox{parent=plc_c_5,x=1,y=1,height=5,text="Advanced Options"}
|
||||
local invert = Checkbox{parent=plc_c_5,x=1,y=3,label="Invert",default=ini_cfg.EmerCoolInvert,box_fg_bg=cpair(colors.orange,colors.black)}
|
||||
TextBox{parent=plc_c_5,y=1,height=5,text="Advanced Options"}
|
||||
local invert = Checkbox{parent=plc_c_5,y=3,label="Invert",default=ini_cfg.EmerCoolInvert,box_fg_bg=cpair(colors.orange,colors.black)}
|
||||
TextBox{parent=plc_c_5,x=3,y=4,height=4,text="Digital I/O is already inverted (or not) based on intended use. If you have a non-standard setup, you can use this option to avoid needing a redstone inverter.",fg_bg=cpair(colors.gray,colors.lightGray)}
|
||||
PushButton{parent=plc_c_5,x=1,y=14,text="\x1b Back",callback=function()plc_pane.set_value(4)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=plc_c_5,y=14,text="\x1b Back",callback=function()plc_pane.set_value(4)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
local function submit_emcool()
|
||||
tmp_cfg.EmerCoolSide = side_options_map[side.get_value()]
|
||||
tmp_cfg.EmerCoolColor = tri(bundled.get_value(), color_options_map[color.get_value()], nil)
|
||||
tmp_cfg.EmerCoolInvert = invert.get_value()
|
||||
plc_pane.set_value(6)
|
||||
end
|
||||
|
||||
PushButton{parent=plc_c_4,y=14,text="\x1b Back",callback=function()plc_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=plc_c_4,x=33,y=14,min_width=10,text="Advanced",callback=function()plc_pane.set_value(5)end,fg_bg=cpair(colors.black,colors.yellow),active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
PushButton{parent=plc_c_4,x=44,y=14,text="Next \x1a",callback=submit_emcool,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=plc_c_6,y=1,height=6,text="Slow ramping is always used up to 40 mB/t, which is ~5 mB/t per second. If you enable fast ramping, it will then hold at 40 mB/t until cooled coolant stabilizes (at least 2 seconds) then increase to a faster ramp rate, which is a percentage of the maximum burn rate."}
|
||||
TextBox{parent=plc_c_6,y=8,height=3,text="When fast ramping is used, if the reactor drops below 80% cooled coolant, it will scale back the ramping proportionally as the coolant level drops.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local fast_ramp = Checkbox{parent=plc_c_6,y=12,label="Enable Fast Ramping",default=ini_cfg.FastRamp,box_fg_bg=cpair(colors.orange,colors.black)}
|
||||
TextBox{parent=plc_c_6,x=23,y=12,text="new!",fg_bg=cpair(colors.red,colors._INHERIT)} ---@todo remove NEW tag on next revision
|
||||
|
||||
local function submit_ramp()
|
||||
tmp_cfg.FastRamp = fast_ramp.get_value()
|
||||
|
||||
if tmp_cfg.FastRampConfirmed or ini_cfg.FastRampConfirmed then
|
||||
next_from_plc()
|
||||
else plc_pane.set_value(7) end
|
||||
end
|
||||
|
||||
PushButton{parent=plc_c_6,y=14,text="\x1b Back",callback=function()plc_pane.set_value(4)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=plc_c_6,x=44,y=14,text="Next \x1a",callback=submit_ramp,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=plc_c_7,y=1,text="!! CAUTION !!",fg_bg=cpair(colors.red,colors._INHERIT)}
|
||||
TextBox{parent=plc_c_7,y=2,height=6,text="Fast ramping has an increased risk of your reactor running low on coolant and overheating. First test this under supervision, as an insufficient cooling setup or lack of auxiliary coolant can cause the reactor to ramp faster than your turbine(s)/boiler(s) can handle."}
|
||||
TextBox{parent=plc_c_7,y=9,height=4,text="In most cases, the low coolant or high temperature automatic SCRAM should prevent damage to the reactor as long as coolant is not lost from the cooling loop.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local fast_ramp_confirm = Checkbox{parent=plc_c_7,y=14,x=13,label="Don't show this warning again",default=ini_cfg.FastRampConfirmed,box_fg_bg=cpair(colors.orange,colors.black)}
|
||||
|
||||
local function submit_ramp_conf()
|
||||
tmp_cfg.FastRampConfirmed = fast_ramp_confirm.get_value()
|
||||
next_from_plc()
|
||||
end
|
||||
|
||||
PushButton{parent=plc_c_4,x=1,y=14,text="\x1b Back",callback=function()plc_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=plc_c_4,x=33,y=14,min_width=10,text="Advanced",callback=function()plc_pane.set_value(5)end,fg_bg=cpair(colors.black,colors.yellow),active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
PushButton{parent=plc_c_4,x=44,y=14,text="Next \x1a",callback=submit_emcool,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=plc_c_7,y=14,text="\x1b Back",callback=function()plc_pane.set_value(6)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=plc_c_7,x=8,y=14,text=" OK ",callback=submit_ramp_conf,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
|
||||
@@ -185,11 +218,11 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
local net_c_3 = Div{parent=net_cfg,x=2,y=4,width=49}
|
||||
local net_c_4 = Div{parent=net_cfg,x=2,y=4,width=49}
|
||||
|
||||
local net_pane = MultiPane{parent=net_cfg,x=1,y=4,panes={net_c_1,net_c_2,net_c_3,net_c_4}}
|
||||
local net_pane = MultiPane{parent=net_cfg,y=4,panes={net_c_1,net_c_2,net_c_3,net_c_4}}
|
||||
|
||||
TextBox{parent=net_cfg,x=1,y=2,text=" Network Configuration",fg_bg=cpair(colors.black,colors.lightBlue)}
|
||||
TextBox{parent=net_cfg,y=2,text=" Network Configuration",fg_bg=cpair(colors.black,colors.lightBlue)}
|
||||
|
||||
TextBox{parent=net_c_1,x=1,y=1,text="Please select the network interface(s)."}
|
||||
TextBox{parent=net_c_1,y=1,text="Please select the network interface(s)."}
|
||||
TextBox{parent=net_c_1,x=41,y=1,text="new!",fg_bg=cpair(colors.red,colors._INHERIT)} ---@todo remove NEW tag on next revision
|
||||
|
||||
local function en_dis_pref()
|
||||
@@ -206,12 +239,12 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
tool_ctl.gen_modem_list()
|
||||
end
|
||||
|
||||
self.wireless = Checkbox{parent=net_c_1,x=1,y=3,label="Wireless/Ender Modem",default=ini_cfg.WirelessModem,box_fg_bg=cpair(colors.lightBlue,colors.black),callback=en_dis_pref}
|
||||
self.wireless = Checkbox{parent=net_c_1,y=3,label="Wireless/Ender Modem",default=ini_cfg.WirelessModem,box_fg_bg=cpair(colors.lightBlue,colors.black),callback=en_dis_pref}
|
||||
self.wl_pref = Checkbox{parent=net_c_1,x=30,y=3,label="Prefer Wireless",default=ini_cfg.PreferWireless,box_fg_bg=cpair(colors.lightBlue,colors.black),disable_fg_bg=g_lg_fg_bg}
|
||||
self.wired = Checkbox{parent=net_c_1,x=1,y=5,label="Wired Modem",default=ini_cfg.WiredModem~=false,box_fg_bg=cpair(colors.lightBlue,colors.black),callback=on_wired_change}
|
||||
self.wired = Checkbox{parent=net_c_1,y=5,label="Wired Modem",default=ini_cfg.WiredModem~=false,box_fg_bg=cpair(colors.lightBlue,colors.black),callback=on_wired_change}
|
||||
TextBox{parent=net_c_1,x=3,y=6,text="this one MUST ONLY connect to SCADA computers",fg_bg=cpair(colors.red,colors._INHERIT)}
|
||||
TextBox{parent=net_c_1,x=3,y=7,text="connecting it to peripherals will cause issues",fg_bg=g_lg_fg_bg}
|
||||
local modem_list = ListBox{parent=net_c_1,x=1,y=8,height=5,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
local modem_list = ListBox{parent=net_c_1,y=8,height=5,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
local modem_err = TextBox{parent=net_c_1,x=8,y=14,width=35,text="",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
|
||||
@@ -251,17 +284,22 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_1,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
local function back_to_plc()
|
||||
plc_pane.set_value(6)
|
||||
main_pane.set_value(2)
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_1,y=14,text="\x1b Back",callback=back_to_plc,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_1,x=44,y=14,text="Next \x1a",callback=submit_interfaces,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_2,x=1,y=1,text="Please set the network channels below."}
|
||||
TextBox{parent=net_c_2,x=1,y=3,height=4,text="Each of the 5 uniquely named channels, including the 2 below, must be the same for each device in this SCADA network. For multiplayer servers, it is recommended to not use the default channels.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_2,y=1,text="Please set the network channels below."}
|
||||
TextBox{parent=net_c_2,y=3,height=4,text="Each of the 5 uniquely named channels, including the 2 below, must be the same for each device in this SCADA network. For multiplayer servers, it is recommended to not use the default channels.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_2,x=1,y=8,text="Supervisor Channel"}
|
||||
local svr_chan = NumberField{parent=net_c_2,x=1,y=9,width=7,default=ini_cfg.SVR_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_2,y=8,text="Supervisor Channel"}
|
||||
local svr_chan = NumberField{parent=net_c_2,y=9,width=7,default=ini_cfg.SVR_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_2,x=9,y=9,height=4,text="[SVR_CHANNEL]",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_2,x=1,y=11,text="PLC Channel"}
|
||||
local plc_chan = NumberField{parent=net_c_2,x=1,y=12,width=7,default=ini_cfg.PLC_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_2,y=11,text="PLC Channel"}
|
||||
local plc_chan = NumberField{parent=net_c_2,y=12,width=7,default=ini_cfg.PLC_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_2,x=9,y=12,height=4,text="[PLC_CHANNEL]",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local chan_err = TextBox{parent=net_c_2,x=8,y=14,width=35,text="",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
@@ -283,17 +321,17 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_2,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_2,y=14,text="\x1b Back",callback=function()net_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_2,x=44,y=14,text="Next \x1a",callback=submit_channels,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_3,x=1,y=1,text="Connection Timeout"}
|
||||
local timeout = NumberField{parent=net_c_3,x=1,y=2,width=7,default=ini_cfg.ConnTimeout,min=2,max=25,max_chars=6,max_frac_digits=2,allow_decimal=true,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_3,y=1,text="Connection Timeout"}
|
||||
local timeout = NumberField{parent=net_c_3,y=2,width=7,default=ini_cfg.ConnTimeout,min=2,max=25,max_chars=6,max_frac_digits=2,allow_decimal=true,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_3,x=9,y=2,height=2,text="seconds (default 5)",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_3,x=1,y=3,height=4,text="You generally do not want or need to modify this. On slow servers, you can increase this to make the system wait longer before assuming a disconnection.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_3,y=3,height=4,text="You generally do not want or need to modify this. On slow servers, you can increase this to make the system wait longer before assuming a disconnection.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_3,x=1,y=8,text="Trusted Range (Wireless Only)"}
|
||||
self.range = NumberField{parent=net_c_3,x=1,y=9,width=10,default=ini_cfg.TrustedRange,min=0,max_chars=20,allow_decimal=true,fg_bg=bw_fg_bg,dis_fg_bg=cpair(colors.lightGray,colors.white)}
|
||||
TextBox{parent=net_c_3,x=1,y=10,height=4,text="Setting this to a value larger than 0 prevents wireless connections with devices that many meters (blocks) away in any direction.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_3,y=8,text="Trusted Range (Wireless Only)"}
|
||||
self.range = NumberField{parent=net_c_3,y=9,width=10,default=ini_cfg.TrustedRange,min=0,max_chars=20,allow_decimal=true,fg_bg=bw_fg_bg,dis_fg_bg=cpair(colors.lightGray,colors.white)}
|
||||
TextBox{parent=net_c_3,y=10,height=4,text="Setting this to a value larger than 0 prevents wireless connections with devices that many meters (blocks) away in any direction.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local n3_err = TextBox{parent=net_c_3,x=8,y=14,width=35,text="",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
|
||||
@@ -322,14 +360,14 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_3,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_3,y=14,text="\x1b Back",callback=function()net_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_3,x=44,y=14,text="Next \x1a",callback=submit_ct_tr,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_4,x=1,y=1,height=2,text="Optionally, set the facility authentication key below. Do NOT use one of your passwords."}
|
||||
TextBox{parent=net_c_4,x=1,y=4,height=6,text="This enables verifying that messages are authentic, so it is intended for wireless security on multiplayer servers. All devices on the same wireless network MUST use the same key if any device has a key. This does result in some extra computation (can slow things down).",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_4,y=1,height=2,text="Optionally, set the facility authentication key below. Do NOT use one of your passwords."}
|
||||
TextBox{parent=net_c_4,y=4,height=6,text="This enables verifying that messages are authentic, so it is intended for wireless security on multiplayer servers. All devices on the same wireless network MUST use the same key if any device has a key. This does result in some extra computation (can slow things down).",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_4,x=1,y=11,text="Auth Key (Wireless Only, Not Used for Wired)"}
|
||||
local key, _ = TextField{parent=net_c_4,x=1,y=12,max_len=64,value=ini_cfg.AuthKey,width=32,height=1,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_4,y=11,text="Auth Key (Wireless Only, Not Used for Wired)"}
|
||||
local key, _ = TextField{parent=net_c_4,y=12,max_len=64,value=ini_cfg.AuthKey,width=32,height=1,fg_bg=bw_fg_bg}
|
||||
|
||||
local function censor_key(enable) key.censor(tri(enable, "*", nil)) end
|
||||
|
||||
@@ -349,7 +387,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
else key_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_4,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_4,y=14,text="\x1b Back",callback=function()net_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_4,x=44,y=14,text="Next \x1a",callback=submit_auth,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -358,17 +396,17 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
|
||||
local log_c_1 = Div{parent=log_cfg,x=2,y=4,width=49}
|
||||
|
||||
TextBox{parent=log_cfg,x=1,y=2,text=" Logging Configuration",fg_bg=cpair(colors.black,colors.pink)}
|
||||
TextBox{parent=log_cfg,y=2,text=" Logging Configuration",fg_bg=cpair(colors.black,colors.pink)}
|
||||
|
||||
TextBox{parent=log_c_1,x=1,y=1,text="Please configure logging below."}
|
||||
TextBox{parent=log_c_1,y=1,text="Please configure logging below."}
|
||||
|
||||
TextBox{parent=log_c_1,x=1,y=3,text="Log File Mode"}
|
||||
local mode = RadioButton{parent=log_c_1,x=1,y=4,default=ini_cfg.LogMode+1,options={"Append on Startup","Replace on Startup"},radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.pink}
|
||||
TextBox{parent=log_c_1,y=3,text="Log File Mode"}
|
||||
local mode = RadioButton{parent=log_c_1,y=4,default=ini_cfg.LogMode+1,options={"Append on Startup","Replace on Startup"},radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.pink}
|
||||
|
||||
TextBox{parent=log_c_1,x=1,y=7,text="Log File Path"}
|
||||
local path = TextField{parent=log_c_1,x=1,y=8,width=49,height=1,value=ini_cfg.LogPath,max_len=128,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=log_c_1,y=7,text="Log File Path"}
|
||||
local path = TextField{parent=log_c_1,y=8,width=49,height=1,value=ini_cfg.LogPath,max_len=128,fg_bg=bw_fg_bg}
|
||||
|
||||
local en_dbg = Checkbox{parent=log_c_1,x=1,y=10,default=ini_cfg.LogDebug,label="Enable Logging Debug Messages",box_fg_bg=cpair(colors.pink,colors.black)}
|
||||
local en_dbg = Checkbox{parent=log_c_1,y=10,default=ini_cfg.LogDebug,label="Enable Logging Debug Messages",box_fg_bg=cpair(colors.pink,colors.black)}
|
||||
TextBox{parent=log_c_1,x=3,y=11,height=2,text="This results in much larger log files. It is best to only use this when there is a problem.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local path_err = TextBox{parent=log_c_1,x=8,y=14,width=35,text="Please provide a log file path.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
@@ -389,7 +427,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
if tmp_cfg.Networked then main_pane.set_value(3) else main_pane.set_value(2) end
|
||||
end
|
||||
|
||||
PushButton{parent=log_c_1,x=1,y=14,text="\x1b Back",callback=back_from_log,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=log_c_1,y=14,text="\x1b Back",callback=back_from_log,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=log_c_1,x=44,y=14,text="Next \x1a",callback=submit_log,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -401,17 +439,17 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
local clr_c_3 = Div{parent=clr_cfg,x=2,y=4,width=49}
|
||||
local clr_c_4 = Div{parent=clr_cfg,x=2,y=4,width=49}
|
||||
|
||||
local clr_pane = MultiPane{parent=clr_cfg,x=1,y=4,panes={clr_c_1,clr_c_2,clr_c_3,clr_c_4}}
|
||||
local clr_pane = MultiPane{parent=clr_cfg,y=4,panes={clr_c_1,clr_c_2,clr_c_3,clr_c_4}}
|
||||
|
||||
TextBox{parent=clr_cfg,x=1,y=2,text=" Color Configuration",fg_bg=cpair(colors.black,colors.magenta)}
|
||||
TextBox{parent=clr_cfg,y=2,text=" Color Configuration",fg_bg=cpair(colors.black,colors.magenta)}
|
||||
|
||||
TextBox{parent=clr_c_1,x=1,y=1,height=2,text="Here you can select the color theme for the front panel."}
|
||||
TextBox{parent=clr_c_1,x=1,y=4,height=2,text="Click 'Accessibility' below to access colorblind assistive options.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=clr_c_1,y=1,height=2,text="Here you can select the color theme for the front panel."}
|
||||
TextBox{parent=clr_c_1,y=4,height=2,text="Click 'Accessibility' below to access colorblind assistive options.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=clr_c_1,x=1,y=7,text="Front Panel Theme"}
|
||||
local fp_theme = RadioButton{parent=clr_c_1,x=1,y=8,default=ini_cfg.FrontPanelTheme,options=themes.FP_THEME_NAMES,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||
TextBox{parent=clr_c_1,y=7,text="Front Panel Theme"}
|
||||
local fp_theme = RadioButton{parent=clr_c_1,y=8,default=ini_cfg.FrontPanelTheme,options=themes.FP_THEME_NAMES,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||
|
||||
TextBox{parent=clr_c_2,x=1,y=1,height=6,text="This system uses color heavily to distinguish ok and not, with some indicators using many colors. By selecting a mode below, indicators will change as shown. For non-standard modes, indicators with more than two colors will be split up."}
|
||||
TextBox{parent=clr_c_2,y=1,height=6,text="This system uses color heavily to distinguish ok and not, with some indicators using many colors. By selecting a mode below, indicators will change as shown. For non-standard modes, indicators with more than two colors will be split up."}
|
||||
|
||||
TextBox{parent=clr_c_2,x=21,y=7,text="Preview"}
|
||||
local _ = IndLight{parent=clr_c_2,x=21,y=8,label="Good",colors=cpair(colors.black,colors.green)}
|
||||
@@ -440,8 +478,8 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
end
|
||||
end
|
||||
|
||||
TextBox{parent=clr_c_2,x=1,y=7,width=10,text="Color Mode"}
|
||||
local c_mode = RadioButton{parent=clr_c_2,x=1,y=8,default=ini_cfg.ColorMode,options=themes.COLOR_MODE_NAMES,callback=recolor,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||
TextBox{parent=clr_c_2,y=7,width=10,text="Color Mode"}
|
||||
local c_mode = RadioButton{parent=clr_c_2,y=8,default=ini_cfg.ColorMode,options=themes.COLOR_MODE_NAMES,callback=recolor,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||
|
||||
TextBox{parent=clr_c_2,x=21,y=13,height=2,width=18,text="Note: exact color varies by theme.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
@@ -482,7 +520,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=clr_c_1,x=1,y=14,text="\x1b Back",callback=back_from_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=clr_c_1,y=14,text="\x1b Back",callback=back_from_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=clr_c_1,x=8,y=14,min_width=15,text="Accessibility",callback=show_access,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
tool_ctl.color_next = PushButton{parent=clr_c_1,x=44,y=14,text="Next \x1a",callback=submit_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
tool_ctl.color_apply = PushButton{parent=clr_c_1,x=43,y=14,min_width=7,text="Apply",callback=submit_colors,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg}
|
||||
@@ -494,12 +532,12 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
clr_pane.set_value(1)
|
||||
end
|
||||
|
||||
TextBox{parent=clr_c_3,x=1,y=1,text="Settings saved!"}
|
||||
PushButton{parent=clr_c_3,x=1,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
TextBox{parent=clr_c_3,y=1,text="Settings saved!"}
|
||||
PushButton{parent=clr_c_3,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
PushButton{parent=clr_c_3,x=44,y=14,min_width=6,text="Home",callback=c_go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=clr_c_4,x=1,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=clr_c_4,x=1,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
TextBox{parent=clr_c_4,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=clr_c_4,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
PushButton{parent=clr_c_4,x=44,y=14,min_width=6,text="Home",callback=c_go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -511,11 +549,11 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
local sum_c_3 = Div{parent=summary,x=2,y=4,width=49}
|
||||
local sum_c_4 = Div{parent=summary,x=2,y=4,width=49}
|
||||
|
||||
local sum_pane = MultiPane{parent=summary,x=1,y=4,panes={sum_c_1,sum_c_2,sum_c_3,sum_c_4}}
|
||||
local sum_pane = MultiPane{parent=summary,y=4,panes={sum_c_1,sum_c_2,sum_c_3,sum_c_4}}
|
||||
|
||||
TextBox{parent=summary,x=1,y=2,text=" Summary",fg_bg=cpair(colors.black,colors.green)}
|
||||
TextBox{parent=summary,y=2,text=" Summary",fg_bg=cpair(colors.black,colors.green)}
|
||||
|
||||
local setting_list = ListBox{parent=sum_c_1,x=1,y=1,height=12,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
local setting_list = ListBox{parent=sum_c_1,y=1,height=12,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
local function back_from_settings()
|
||||
if tool_ctl.viewing_config or self.importing_legacy then
|
||||
@@ -551,6 +589,8 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
try_set(bundled, ini_cfg.EmerCoolColor ~= nil)
|
||||
if ini_cfg.EmerCoolColor ~= nil then try_set(color, color_to_idx(ini_cfg.EmerCoolColor)) end
|
||||
try_set(invert, ini_cfg.EmerCoolInvert)
|
||||
try_set(fast_ramp, ini_cfg.FastRamp)
|
||||
try_set(fast_ramp_confirm, ini_cfg.FastRampConfirmed)
|
||||
try_set(self.wireless, ini_cfg.WirelessModem)
|
||||
try_set(self.wired, ini_cfg.WiredModem ~= false)
|
||||
try_set(self.wl_pref, ini_cfg.PreferWireless)
|
||||
@@ -579,12 +619,12 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=sum_c_1,x=1,y=14,text="\x1b Back",callback=back_from_settings,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_1,y=14,text="\x1b Back",callback=back_from_settings,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
self.show_key_btn = PushButton{parent=sum_c_1,x=8,y=14,min_width=17,text="Unhide Auth Key",callback=function()self.show_auth_key()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
tool_ctl.settings_apply = PushButton{parent=sum_c_1,x=43,y=14,min_width=7,text="Apply",callback=save_and_continue,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=sum_c_2,x=1,y=1,text="Settings saved!"}
|
||||
TextBox{parent=sum_c_2,x=1,y=3,text="Tip: you can run a Self-Check from the configurator home screen to make sure everything is going to work right!"}
|
||||
TextBox{parent=sum_c_2,y=1,text="Settings saved!"}
|
||||
TextBox{parent=sum_c_2,y=3,text="Tip: you can run a Self-Check from the configurator home screen to make sure everything is going to work right!"}
|
||||
|
||||
local function go_home()
|
||||
main_pane.set_value(1)
|
||||
@@ -594,21 +634,21 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
sum_pane.set_value(1)
|
||||
end
|
||||
|
||||
PushButton{parent=sum_c_2,x=1,y=14,min_width=6,text="Home",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_2,y=14,min_width=6,text="Home",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_2,x=44,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
|
||||
TextBox{parent=sum_c_3,x=1,y=1,height=2,text="The old config.lua file will now be deleted, then the configurator will exit."}
|
||||
TextBox{parent=sum_c_3,y=1,height=2,text="The old config.lua file will now be deleted, then the configurator will exit."}
|
||||
|
||||
local function delete_legacy()
|
||||
fs.delete("/reactor-plc/config.lua")
|
||||
exit()
|
||||
end
|
||||
|
||||
PushButton{parent=sum_c_3,x=1,y=14,min_width=8,text="Cancel",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_3,y=14,min_width=8,text="Cancel",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_3,x=44,y=14,min_width=6,text="OK",callback=delete_legacy,fg_bg=cpair(colors.black,colors.green),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
|
||||
TextBox{parent=sum_c_4,x=1,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=sum_c_4,x=1,y=14,min_width=6,text="Home",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
TextBox{parent=sum_c_4,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=sum_c_4,y=14,min_width=6,text="Home",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_4,x=44,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
|
||||
--#endregion
|
||||
@@ -621,6 +661,8 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
|
||||
tmp_cfg.Networked = config.NETWORKED
|
||||
tmp_cfg.UnitID = config.REACTOR_ID
|
||||
tmp_cfg.FastRamp = false
|
||||
tmp_cfg.FastRampConfirmed = false
|
||||
tmp_cfg.EmerCoolEnable = type(config.EMERGENCY_COOL) == "table"
|
||||
|
||||
if tmp_cfg.EmerCoolEnable then
|
||||
@@ -685,21 +727,25 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
if val == "nil" then val = "<not set>" end
|
||||
|
||||
local c = tri(alternate, g_lg_fg_bg, cpair(colors.gray,colors.white))
|
||||
alternate = not alternate
|
||||
|
||||
if (string.len(val) > val_max_w) or string.find(val, "\n") then
|
||||
local lines = util.strwrap(val, inner_width)
|
||||
height = #lines + 1
|
||||
end
|
||||
|
||||
local line = Div{parent=setting_list,height=height,fg_bg=c}
|
||||
TextBox{parent=line,text=f[2],width=string.len(f[2]),fg_bg=cpair(colors.black,line.get_fg_bg().bkg)}
|
||||
|
||||
local textbox
|
||||
if height > 1 then
|
||||
textbox = TextBox{parent=line,x=1,y=2,text=val,height=height-1}
|
||||
else
|
||||
textbox = TextBox{parent=line,x=label_w+1,y=1,text=val,alignment=RIGHT}
|
||||
|
||||
if f[1] ~= "FastRampConfirmed" then
|
||||
alternate = not alternate
|
||||
|
||||
local line = Div{parent=setting_list,height=height,fg_bg=c}
|
||||
TextBox{parent=line,text=f[2],width=string.len(f[2]),fg_bg=cpair(colors.black,line.get_fg_bg().bkg)}
|
||||
|
||||
if height > 1 then
|
||||
textbox = TextBox{parent=line,y=2,text=val,height=height-1}
|
||||
else
|
||||
textbox = TextBox{parent=line,x=label_w+1,y=1,text=val,alignment=RIGHT}
|
||||
end
|
||||
end
|
||||
|
||||
if f[1] == "AuthKey" then self.auth_key_textbox = textbox end
|
||||
@@ -726,19 +772,19 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
end
|
||||
|
||||
if missing.tmp and tmp_cfg.WiredModem then
|
||||
local line = Div{parent=modem_list,x=1,y=1,height=1}
|
||||
local line = Div{parent=modem_list,y=1,height=1}
|
||||
|
||||
TextBox{parent=line,x=1,y=1,width=4,text="Used",fg_bg=cpair(tri(enable,colors.blue,colors.gray),colors.white)}
|
||||
TextBox{parent=line,y=1,width=4,text="Used",fg_bg=cpair(tri(enable,colors.blue,colors.gray),colors.white)}
|
||||
PushButton{parent=line,x=6,y=1,min_width=8,height=1,text="SELECT",callback=function()end,fg_bg=cpair(colors.black,colors.lightBlue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=g_lg_fg_bg}.disable()
|
||||
TextBox{parent=line,x=15,y=1,text="[missing]",fg_bg=cpair(colors.red,colors.white)}
|
||||
TextBox{parent=line,x=25,y=1,text=tmp_cfg.WiredModem}
|
||||
end
|
||||
|
||||
if missing.ini and ini_cfg.WiredModem and (tmp_cfg.WiredModem ~= ini_cfg.WiredModem) then
|
||||
local line = Div{parent=modem_list,x=1,y=1,height=1}
|
||||
local line = Div{parent=modem_list,y=1,height=1}
|
||||
local used = tmp_cfg.WiredModem == ini_cfg.WiredModem
|
||||
|
||||
TextBox{parent=line,x=1,y=1,width=4,text=tri(used,"Used","----"),fg_bg=cpair(tri(used and enable,colors.blue,colors.gray),colors.white)}
|
||||
TextBox{parent=line,y=1,width=4,text=tri(used,"Used","----"),fg_bg=cpair(tri(used and enable,colors.blue,colors.gray),colors.white)}
|
||||
local select_btn = PushButton{parent=line,x=6,y=1,min_width=8,height=1,text="SELECT",callback=function()select(ini_cfg.WiredModem)end,fg_bg=cpair(colors.black,colors.lightBlue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=line,x=15,y=1,text="[missing]",fg_bg=cpair(colors.red,colors.white)}
|
||||
TextBox{parent=line,x=25,y=1,text=ini_cfg.WiredModem}
|
||||
@@ -748,10 +794,10 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
|
||||
|
||||
-- list wired modems
|
||||
for iface, _ in pairs(modems) do
|
||||
local line = Div{parent=modem_list,x=1,y=1,height=1}
|
||||
local line = Div{parent=modem_list,y=1,height=1}
|
||||
local used = tmp_cfg.WiredModem == iface
|
||||
|
||||
TextBox{parent=line,x=1,y=1,width=4,text=tri(used,"Used","----"),fg_bg=cpair(tri(used and enable,colors.blue,colors.gray),colors.white)}
|
||||
TextBox{parent=line,y=1,width=4,text=tri(used,"Used","----"),fg_bg=cpair(tri(used and enable,colors.blue,colors.gray),colors.white)}
|
||||
local select_btn = PushButton{parent=line,x=6,y=1,min_width=8,height=1,text="SELECT",callback=function()select(iface)end,fg_bg=cpair(colors.black,colors.lightBlue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=line,x=15,y=1,text=iface}
|
||||
|
||||
|
||||
@@ -78,6 +78,8 @@ local tool_ctl = {
|
||||
local tmp_cfg = {
|
||||
Networked = false,
|
||||
UnitID = 0,
|
||||
FastRamp = true,
|
||||
FastRampConfirmed = false,
|
||||
EmerCoolEnable = false,
|
||||
EmerCoolSide = nil, ---@type string|nil
|
||||
EmerCoolColor = nil, ---@type color|nil
|
||||
@@ -106,6 +108,8 @@ local settings_cfg = {}
|
||||
local fields = {
|
||||
{ "Networked", "Networked", false },
|
||||
{ "UnitID", "Unit ID", 1 },
|
||||
{ "FastRamp", "Fast Ramp", true },
|
||||
{ "FastRampConfirmed", "Fast Ramp Confirmed", false },
|
||||
{ "EmerCoolEnable", "Emergency Coolant", false },
|
||||
{ "EmerCoolSide", "Emergency Coolant Side", nil },
|
||||
{ "EmerCoolColor", "Emergency Coolant Color", nil },
|
||||
@@ -152,18 +156,18 @@ local function config_view(display)
|
||||
|
||||
TextBox{parent=display,y=1,text="Reactor PLC Configurator",alignment=CENTER,fg_bg=style.header}
|
||||
|
||||
local root_pane_div = Div{parent=display,x=1,y=2}
|
||||
local root_pane_div = Div{parent=display,y=2}
|
||||
|
||||
local main_page = Div{parent=root_pane_div,x=1,y=1}
|
||||
local plc_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local net_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local log_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local clr_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local summary = Div{parent=root_pane_div,x=1,y=1}
|
||||
local changelog = Div{parent=root_pane_div,x=1,y=1}
|
||||
local check_sys = Div{parent=root_pane_div,x=1,y=1}
|
||||
local main_page = Div{parent=root_pane_div,y=1}
|
||||
local plc_cfg = Div{parent=root_pane_div,y=1}
|
||||
local net_cfg = Div{parent=root_pane_div,y=1}
|
||||
local log_cfg = Div{parent=root_pane_div,y=1}
|
||||
local clr_cfg = Div{parent=root_pane_div,y=1}
|
||||
local summary = Div{parent=root_pane_div,y=1}
|
||||
local changelog = Div{parent=root_pane_div,y=1}
|
||||
local check_sys = Div{parent=root_pane_div,y=1}
|
||||
|
||||
local main_pane = MultiPane{parent=root_pane_div,x=1,y=1,panes={main_page,plc_cfg,net_cfg,log_cfg,clr_cfg,summary,changelog,check_sys}}
|
||||
local main_pane = MultiPane{parent=root_pane_div,y=1,panes={main_page,plc_cfg,net_cfg,log_cfg,clr_cfg,summary,changelog,check_sys}}
|
||||
|
||||
--#region Main Page
|
||||
|
||||
@@ -231,20 +235,20 @@ local function config_view(display)
|
||||
|
||||
local cl = Div{parent=changelog,x=2,y=4,width=49}
|
||||
|
||||
TextBox{parent=changelog,x=1,y=2,text=" Config Change Log",fg_bg=bw_fg_bg}
|
||||
TextBox{parent=changelog,y=2,text=" Config Change Log",fg_bg=bw_fg_bg}
|
||||
|
||||
local c_log = ListBox{parent=cl,x=1,y=1,height=12,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
local c_log = ListBox{parent=cl,y=1,height=12,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
for _, change in ipairs(changes) do
|
||||
TextBox{parent=c_log,text=change[1],fg_bg=bw_fg_bg}
|
||||
for _, v in ipairs(change[2]) do
|
||||
local e = Div{parent=c_log,height=#util.strwrap(v,46)}
|
||||
TextBox{parent=e,y=1,x=1,text="- ",fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=e,y=1,text="- ",fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=e,y=1,x=3,text=v,height=e.get_height(),fg_bg=cpair(colors.gray,colors.white)}
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=cl,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=cl,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
|
||||
|
||||
@@ -171,11 +171,11 @@ local function init(panel, config)
|
||||
emer_cool.register(databus.ps, "emer_cool", emer_cool.update)
|
||||
end
|
||||
|
||||
local status_trip_rct = Rectangle{parent=status,height=3,x=1,border=border(1,s_hi_box.bkg,true),even_inner=true}
|
||||
local status_trip_rct = Rectangle{parent=status,height=3,border=border(1,s_hi_box.bkg,true),even_inner=true}
|
||||
local status_trip = Div{parent=status_trip_rct,height=1,fg_bg=s_hi_box}
|
||||
local scram = LED{parent=status_trip,width=10,label="RPS TRIP",colors=ind_red,flash=true,period=flasher.PERIOD.BLINK_250_MS}
|
||||
|
||||
local controls_rct = Rectangle{parent=status,width=status.get_width()-2,height=3,x=1,border=border(1,s_hi_box.bkg,true),even_inner=true}
|
||||
local controls_rct = Rectangle{parent=status,width=status.get_width()-2,height=3,border=border(1,s_hi_box.bkg,true),even_inner=true}
|
||||
local controls = Div{parent=controls_rct,width=controls_rct.get_width()-2,height=1,fg_bg=s_hi_box}
|
||||
local button_padding = math.floor((controls.get_width() - 14) / 3)
|
||||
PushButton{parent=controls,x=button_padding+1,y=1,min_width=7,text="SCRAM",callback=databus.rps_scram,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.black,colors.red_off)}
|
||||
@@ -184,7 +184,7 @@ local function init(panel, config)
|
||||
active.register(databus.ps, "reactor_active", active.update)
|
||||
scram.register(databus.ps, "rps_scram", scram.update)
|
||||
|
||||
local hw_labels = Rectangle{parent=status,width=status.get_width()-2,height=5,x=1,border=border(1,s_hi_box.bkg,true),even_inner=true}
|
||||
local hw_labels = Rectangle{parent=status,width=status.get_width()-2,height=5,border=border(1,s_hi_box.bkg,true),even_inner=true}
|
||||
|
||||
---@diagnostic disable-next-line: undefined-field
|
||||
local comp_id = util.sprintf("%03d", os.getComputerID())
|
||||
|
||||
@@ -44,6 +44,7 @@ function plc.load_config()
|
||||
|
||||
config.Networked = settings.get("Networked")
|
||||
config.UnitID = settings.get("UnitID")
|
||||
config.FastRamp = settings.get("FastRamp")
|
||||
|
||||
config.EmerCoolEnable = settings.get("EmerCoolEnable")
|
||||
config.EmerCoolSide = settings.get("EmerCoolSide")
|
||||
@@ -76,6 +77,7 @@ function plc.validate_config(cfg)
|
||||
|
||||
cfv.assert_type_bool(cfg.Networked)
|
||||
cfv.assert_type_int(cfg.UnitID)
|
||||
cfv.assert_type_bool(cfg.FastRamp)
|
||||
cfv.assert_type_bool(cfg.EmerCoolEnable)
|
||||
|
||||
if cfg.Networked then
|
||||
@@ -127,8 +129,7 @@ function plc.rps_init(reactor, is_formed)
|
||||
local self = {
|
||||
---@type boolean[] check states
|
||||
state = { false, false, false, false, false, false, false, false, false, false, false, false },
|
||||
reactor_enabled = false,
|
||||
enabled_at = 0,
|
||||
reactor_active = false,
|
||||
emer_cool_active = nil, ---@type boolean
|
||||
formed = is_formed, ---@type boolean|nil
|
||||
force_disabled = false,
|
||||
@@ -296,6 +297,14 @@ function plc.rps_init(reactor, is_formed)
|
||||
reactor = new_reactor
|
||||
end
|
||||
|
||||
-- check the reactor enable state and update the internal tracking flag
|
||||
---@return boolean active
|
||||
--- EVENT_CONSUMER: this function consumes events
|
||||
function public.check_active()
|
||||
self.reactor_active = reactor.getStatus() == true
|
||||
return self.reactor_active
|
||||
end
|
||||
|
||||
-- trip for lost peripheral
|
||||
function public.trip_fault()
|
||||
_set_fault()
|
||||
@@ -332,11 +341,7 @@ function plc.rps_init(reactor, is_formed)
|
||||
if reactor.__p_is_faulted() and not string.find(reactor.__p_last_fault(), PCALL_SCRAM_MSG) then
|
||||
log.error("RPS: failed reactor SCRAM")
|
||||
return false
|
||||
else
|
||||
self.reactor_enabled = false
|
||||
self.last_runtime = util.time_ms() - self.enabled_at
|
||||
return true
|
||||
end
|
||||
else return true end
|
||||
end
|
||||
|
||||
-- start the reactor now<br>
|
||||
@@ -349,11 +354,7 @@ function plc.rps_init(reactor, is_formed)
|
||||
reactor.activate()
|
||||
if reactor.__p_is_faulted() and not string.find(reactor.__p_last_fault(), PCALL_START_MSG) then
|
||||
log.error("RPS: failed reactor start")
|
||||
else
|
||||
self.reactor_enabled = true
|
||||
self.enabled_at = util.time_ms()
|
||||
return true
|
||||
end
|
||||
else return true end
|
||||
else
|
||||
log.debug(util.c("RPS: failed start, RPS tripped: ", self.trip_cause))
|
||||
end
|
||||
@@ -363,6 +364,7 @@ function plc.rps_init(reactor, is_formed)
|
||||
|
||||
-- automatic control activate/re-activate
|
||||
---@return boolean success
|
||||
--- EVENT_CONSUMER: this function consumes events
|
||||
function public.auto_activate()
|
||||
-- clear automatic SCRAM if it was the cause
|
||||
if self.tripped and self.trip_cause == "automatic" then
|
||||
@@ -380,6 +382,7 @@ function plc.rps_init(reactor, is_formed)
|
||||
---@nodiscard
|
||||
---@param has_reactor boolean if the PLC state indicates we have a reactor
|
||||
---@return boolean tripped, rps_trip_cause trip_status, boolean first_trip
|
||||
--- EVENT_CONSUMER: this function consumes events
|
||||
function public.check(has_reactor)
|
||||
local status = RPS_TRIP_CAUSE.OK
|
||||
local was_tripped = self.tripped
|
||||
@@ -451,20 +454,16 @@ function plc.rps_init(reactor, is_formed)
|
||||
self.trip_cause = RPS_TRIP_CAUSE.OK
|
||||
end
|
||||
|
||||
-- if a new trip occured...
|
||||
-- SCRAM on a new trip, RPS thread handles reactor becoming active while already tripped
|
||||
if (not was_tripped) and (status ~= RPS_TRIP_CAUSE.OK) then
|
||||
first_trip = true
|
||||
self.tripped = true
|
||||
self.trip_cause = status
|
||||
|
||||
-- in the case that the reactor is detected to be active,
|
||||
-- it will be scrammed shortly after this in the main RPS loop if we don't here
|
||||
if self.formed then
|
||||
if not self.force_disabled then
|
||||
public.scram()
|
||||
else
|
||||
if self.force_disabled then
|
||||
log.warning("RPS: skipping SCRAM due to reactor being force disabled")
|
||||
end
|
||||
else public.scram() end
|
||||
else
|
||||
log.warning("RPS: skipping SCRAM due to not being formed")
|
||||
end
|
||||
@@ -490,18 +489,13 @@ function plc.rps_init(reactor, is_formed)
|
||||
function public.is_low_coolant() return self.states[CHK.LOW_COOLANT] end
|
||||
|
||||
---@nodiscard
|
||||
function public.is_active() return self.reactor_enabled end
|
||||
function public.is_active() return self.reactor_active end
|
||||
---@nodiscard
|
||||
---@return boolean|nil formed true if formed, false if not, nil if unknown
|
||||
function public.is_formed() return self.formed end
|
||||
---@nodiscard
|
||||
function public.is_force_disabled() return self.force_disabled end
|
||||
|
||||
-- get the runtime of the reactor if active, or the last runtime if disabled
|
||||
---@nodiscard
|
||||
---@return integer runtime time since last enable
|
||||
function public.get_runtime() return util.trinary(self.reactor_enabled, util.time_ms() - self.enabled_at, self.last_runtime) end
|
||||
|
||||
-- reset the RPS
|
||||
---@param quiet? boolean true to suppress the info log message
|
||||
function public.reset(quiet)
|
||||
@@ -885,8 +879,8 @@ function plc.comms(version, tx_nic, reactor, rps, conn_watchdog)
|
||||
-- close the connection to the server
|
||||
function public.close()
|
||||
conn_watchdog.cancel()
|
||||
public.unlink()
|
||||
_send_mgmt(MGMT_TYPE.CLOSE, {})
|
||||
public.unlink()
|
||||
end
|
||||
|
||||
-- attempt to establish link with supervisor
|
||||
|
||||
246
reactor-plc/spctl.lua
Normal file
246
reactor-plc/spctl.lua
Normal file
@@ -0,0 +1,246 @@
|
||||
local log = require("scada-common.log")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local plc = require("reactor-plc.plc")
|
||||
|
||||
local SLOW_RAMP_mB_s = 5.0
|
||||
local FAST_SWITCH_mB_s = 40.0
|
||||
local FAST_MAX_PERCENT_s = 0.04
|
||||
|
||||
local spctl = {}
|
||||
|
||||
---@enum RAMP_STATES
|
||||
local STATES = {
|
||||
STOPPED = 1,
|
||||
INIT = 2,
|
||||
SLOW_RAMP_UP = 3,
|
||||
SLOW_RAMP_DOWN = 4,
|
||||
STABLE_WAIT = 5,
|
||||
CCOOL_MON = 6,
|
||||
FAST_RAMP_UP = 7,
|
||||
FAST_RAMP_DOWN = 8
|
||||
}
|
||||
|
||||
local STATE_NAMES = {
|
||||
"STOPPED",
|
||||
"INIT",
|
||||
"SLOW_RAMP_UP",
|
||||
"SLOW_RAMP_DOWN",
|
||||
"STABLE_WAIT",
|
||||
"CCOOL_MON",
|
||||
"FAST_RAMP_UP",
|
||||
"FAST_RAMP_DOWN"
|
||||
}
|
||||
|
||||
local _spctl = {
|
||||
fast_ramp_en = plc.config.FastRamp,
|
||||
|
||||
max_br = 0.0,
|
||||
last_sp = 0.0,
|
||||
last_ccool = 0.0,
|
||||
|
||||
last_change = 0,
|
||||
next_state = STATES.STOPPED, ---@type RAMP_STATES
|
||||
last_state = STATES.STOPPED ---@type RAMP_STATES
|
||||
}
|
||||
|
||||
local rps = nil ---@type rps
|
||||
local setpoints = nil ---@type plc_setpoints
|
||||
|
||||
-- initialize with shared memory data
|
||||
---@param smem plc_shared_memory
|
||||
function spctl.init(smem)
|
||||
rps = smem.plc_sys.rps
|
||||
setpoints = smem.setpoints
|
||||
end
|
||||
|
||||
-- initialize ramping, or set right away if acceptable
|
||||
---@param reactor table
|
||||
---@param cur_br number
|
||||
local function ramp_init(reactor, cur_br)
|
||||
_spctl.last_sp = setpoints.burn_rate
|
||||
|
||||
-- update without ramp if <= 2.5 mB/t increase
|
||||
-- no need to ramp down, as the ramp up poses the safety risks
|
||||
if (setpoints.burn_rate - cur_br) > 2.5 then
|
||||
log.debug(util.c("SPCTL: starting burn rate ramp from ", cur_br, " mB/t to ", setpoints.burn_rate, " mB/t"))
|
||||
|
||||
_spctl.last_change = os.clock()
|
||||
_spctl.next_state = STATES.INIT
|
||||
else
|
||||
log.debug(util.c("SPCTL: setting burn rate directly to ", setpoints.burn_rate, " mB/t"))
|
||||
reactor.setBurnRate(setpoints.burn_rate)
|
||||
end
|
||||
end
|
||||
|
||||
-- reset states and last value tracking
|
||||
local function ramp_reset()
|
||||
_spctl.last_sp = 0
|
||||
_spctl.last_ccool = 0
|
||||
_spctl.next_state = STATES.STOPPED
|
||||
_spctl.last_state = STATES.STOPPED
|
||||
end
|
||||
|
||||
-- run the setpoint ramp controller loop
|
||||
---@param reactor table reactor
|
||||
---@param cur_br number current burn rate
|
||||
---@param cur_ccool number coolant filled percentage (0 to 1)
|
||||
---@param elapsed_s number seconds elapsed in the ramp
|
||||
local function ramp_run(reactor, cur_br, cur_ccool, elapsed_s)
|
||||
local now = os.clock()
|
||||
local state_time = now - _spctl.last_change
|
||||
local state = _spctl.next_state
|
||||
local new_state = _spctl.next_state
|
||||
local new_br = cur_br
|
||||
|
||||
if state == STATES.INIT then
|
||||
-- transition to the appropriate direction and phase
|
||||
if setpoints.burn_rate > cur_br then
|
||||
-- need to ramp up
|
||||
if _spctl.fast_ramp_en and (cur_br >= FAST_SWITCH_mB_s) then
|
||||
new_state = STATES.STABLE_WAIT
|
||||
else
|
||||
new_state = STATES.SLOW_RAMP_UP
|
||||
end
|
||||
else
|
||||
-- need to ramp down
|
||||
if _spctl.fast_ramp_en and (cur_br >= FAST_SWITCH_mB_s) then
|
||||
new_state = STATES.FAST_RAMP_DOWN
|
||||
else
|
||||
new_state = STATES.SLOW_RAMP_DOWN
|
||||
end
|
||||
end
|
||||
elseif state == STATES.SLOW_RAMP_UP then
|
||||
-- slowly ramp up
|
||||
new_br = cur_br + (SLOW_RAMP_mB_s * elapsed_s)
|
||||
if new_br > setpoints.burn_rate then new_br = setpoints.burn_rate end
|
||||
|
||||
-- transition out of slow ramp after hitting the limit
|
||||
if _spctl.fast_ramp_en and (new_br >= FAST_SWITCH_mB_s) then
|
||||
new_br = FAST_SWITCH_mB_s
|
||||
|
||||
new_state = STATES.STABLE_WAIT
|
||||
end
|
||||
elseif state == STATES.SLOW_RAMP_DOWN then
|
||||
-- slowly ramp down
|
||||
new_br = cur_br - (SLOW_RAMP_mB_s * elapsed_s)
|
||||
if new_br < setpoints.burn_rate then new_br = setpoints.burn_rate end
|
||||
elseif state == STATES.STABLE_WAIT then
|
||||
-- wait a minimum of 2 seconds to help with flow stability
|
||||
-- this helps detect broken things before getting too high
|
||||
if state_time >= 2 then
|
||||
new_state = STATES.CCOOL_MON
|
||||
end
|
||||
elseif state == STATES.CCOOL_MON then
|
||||
-- don't move on until coolant is not decreasing
|
||||
if cur_ccool >= _spctl.last_ccool then
|
||||
new_state = STATES.FAST_RAMP_UP
|
||||
end
|
||||
elseif state == STATES.FAST_RAMP_UP then
|
||||
-- step by a percent of the max burn rate
|
||||
local scaler = math.min(FAST_MAX_PERCENT_s, FAST_MAX_PERCENT_s * (state_time / 5.0)) * elapsed_s
|
||||
local step = scaler * _spctl.max_br
|
||||
|
||||
-- slow the step if we are losing coolant
|
||||
if cur_ccool < 0.8 then
|
||||
-- map 0.4-0.8 to 0-1
|
||||
local a = (cur_ccool - 0.4) * 2.5
|
||||
|
||||
-- slow as we approach low coolant condition
|
||||
step = step * a
|
||||
end
|
||||
|
||||
-- minimum is the slow rate, maintain old behavior
|
||||
-- if we overheat, it will be gentle and recoverable, then the user can solve the coolant issue rather than see the reactor not ramping
|
||||
step = math.max((SLOW_RAMP_mB_s * elapsed_s), step)
|
||||
|
||||
-- don't exceed the setpoint
|
||||
new_br = math.min(cur_br + step, setpoints.burn_rate)
|
||||
|
||||
log.debug(util.sprintf("SPCTL: scaler[%f] cur_ccool[%f] step[%f] new_br[%f]", scaler, cur_ccool, step, new_br))
|
||||
elseif state == STATES.FAST_RAMP_DOWN then
|
||||
-- step by a percent of the max burn rate
|
||||
local scaler = math.min(FAST_MAX_PERCENT_s, FAST_MAX_PERCENT_s * (state_time / 5.0)) * elapsed_s
|
||||
local step = scaler * _spctl.max_br
|
||||
|
||||
-- minimum is the slow rate, maintain old behavior
|
||||
-- if we overheat, it will be gentle and recoverable, then the user can solve the coolant issue rather than see the reactor not ramping
|
||||
step = math.max((SLOW_RAMP_mB_s * elapsed_s), step)
|
||||
|
||||
-- don't fall below the setpoint
|
||||
new_br = math.max(cur_br - step, setpoints.burn_rate)
|
||||
|
||||
log.debug(util.sprintf("SPCTL: scaler[%f] cur_ccool[%f] step[%f] new_br[%f]", scaler, cur_ccool, step, new_br))
|
||||
end
|
||||
|
||||
-- set the burn rate
|
||||
reactor.setBurnRate(new_br)
|
||||
|
||||
if new_br ~= setpoints.burn_rate then
|
||||
-- update tracked values and continue
|
||||
_spctl.last_ccool = cur_ccool
|
||||
else
|
||||
new_state = STATES.STOPPED
|
||||
end
|
||||
|
||||
-- state change management
|
||||
if new_state ~= state then
|
||||
log.debug("SPCTL: state changed to " .. (STATE_NAMES[new_state] or "UNKNOWN"))
|
||||
|
||||
_spctl.next_state = new_state
|
||||
_spctl.last_change = now
|
||||
end
|
||||
end
|
||||
|
||||
-- update setpoint controller
|
||||
---@param reactor table
|
||||
---@param elapsed_s integer iteration elapsed time reference
|
||||
function spctl.update(reactor, elapsed_s)
|
||||
-- check if we should start ramping
|
||||
if setpoints.burn_rate_en and (setpoints.burn_rate ~= _spctl.last_sp) and rps.is_active() then
|
||||
local cur_br = reactor.getBurnRate()
|
||||
_spctl.max_br = reactor.getMaxBurnRate()
|
||||
|
||||
if (type(cur_br) == "number") and (type(_spctl.max_br) == "number") and (setpoints.burn_rate ~= cur_br) then
|
||||
ramp_init(reactor, cur_br)
|
||||
end
|
||||
end
|
||||
|
||||
-- minimize operations when not running
|
||||
if _spctl.next_state ~= STATES.STOPPED then
|
||||
-- adjust burn rate (setpoints.burn_rate)
|
||||
if setpoints.burn_rate_en then
|
||||
local cur_br, cur_ccool = 0, 0
|
||||
|
||||
parallel.waitForAll(
|
||||
function () cur_br = reactor.getBurnRate() end,
|
||||
function () cur_ccool = reactor.getCoolantFilledPercentage() end
|
||||
)
|
||||
|
||||
if not rps.is_active() then
|
||||
log.info("SPCTL: ramping aborted (reactor inactive)")
|
||||
setpoints.burn_rate_en = false
|
||||
ramp_reset()
|
||||
-- we yielded, check enable again
|
||||
elseif setpoints.burn_rate_en then
|
||||
if (type(cur_br) == "number") and (type(cur_ccool) == "number") then
|
||||
ramp_run(reactor, cur_br, cur_ccool, elapsed_s)
|
||||
else
|
||||
log.error(util.c("SPCTL: skipped running loop due to bad data (cur_br=", cur_br, ",cur_ccool=", cur_ccool, ")"))
|
||||
end
|
||||
else
|
||||
log.info("SPCTL: ramping cancelled")
|
||||
ramp_reset()
|
||||
end
|
||||
else
|
||||
log.info("SPCTL: ramping cancelled")
|
||||
ramp_reset()
|
||||
end
|
||||
elseif setpoints.burn_rate_en then
|
||||
log.info(util.c("SPCTL: ramping completed (setpoint of ", setpoints.burn_rate, " mB/t)"))
|
||||
setpoints.burn_rate_en = false
|
||||
ramp_reset()
|
||||
end
|
||||
end
|
||||
|
||||
return spctl
|
||||
@@ -19,7 +19,7 @@ local plc = require("reactor-plc.plc")
|
||||
local renderer = require("reactor-plc.renderer")
|
||||
local threads = require("reactor-plc.threads")
|
||||
|
||||
local R_PLC_VERSION = "v1.10.10"
|
||||
local R_PLC_VERSION = "v1.11.5"
|
||||
|
||||
local println = util.println
|
||||
local println_ts = util.println_ts
|
||||
|
||||
@@ -7,6 +7,7 @@ local util = require("scada-common.util")
|
||||
local backplane = require("reactor-plc.backplane")
|
||||
local databus = require("reactor-plc.databus")
|
||||
local renderer = require("reactor-plc.renderer")
|
||||
local spctl = require("reactor-plc.spctl")
|
||||
|
||||
local core = require("graphics.core")
|
||||
|
||||
@@ -17,8 +18,6 @@ local RPS_SLEEP = 250 -- 250ms, 5 ticks
|
||||
local COMMS_SLEEP = 150 -- 150ms, 3 ticks
|
||||
local SP_CTRL_SLEEP = 250 -- 250ms, 5 ticks
|
||||
|
||||
local BURN_RATE_RAMP_mB_s = 5.0
|
||||
|
||||
-- main thread
|
||||
---@nodiscard
|
||||
---@param smem plc_shared_memory
|
||||
@@ -50,6 +49,67 @@ function threads.thread__main(smem)
|
||||
local MQ__RPS_CMD = smem.q_types.MQ__RPS_CMD
|
||||
local MQ__COMM_CMD = smem.q_types.MQ__COMM_CMD
|
||||
|
||||
-- main loop periodic tasks
|
||||
local function loop_tick()
|
||||
-- blink heartbeat indicator
|
||||
databus.heartbeat()
|
||||
|
||||
-- start next clock timer
|
||||
loop_clock.start()
|
||||
|
||||
-- periodic hardware tasks
|
||||
backplane.periodic()
|
||||
|
||||
-- send updated data or try to link
|
||||
if networked then
|
||||
if plc_comms.is_linked() then
|
||||
smem.q.mq_comms_tx.push_command(MQ__COMM_CMD.SEND_STATUS)
|
||||
|
||||
plc_comms.manage_failover(backplane.active_nic())
|
||||
elseif ticks_to_update == 0 then
|
||||
local a_nic, s_nic = backplane.active_nic(), backplane.standby_nic()
|
||||
|
||||
if a_nic.is_network_up() then
|
||||
plc_comms.send_link_req(a_nic)
|
||||
elseif s_nic and s_nic.is_network_up() then
|
||||
plc_comms.send_link_req(s_nic)
|
||||
end
|
||||
|
||||
ticks_to_update = LINK_TICKS
|
||||
else
|
||||
ticks_to_update = ticks_to_update - 1
|
||||
end
|
||||
end
|
||||
|
||||
-- check for formed state change
|
||||
if (not plc_state.reactor_formed) and rps.is_formed() then
|
||||
-- reactor now formed
|
||||
plc_state.reactor_formed = true
|
||||
|
||||
println_ts("reactor is now formed")
|
||||
log.info("reactor is now formed")
|
||||
|
||||
-- determine if we are still in a degraded state
|
||||
if (not networked) or backplane.active_nic().is_connected() then
|
||||
plc_state.degraded = false
|
||||
end
|
||||
|
||||
-- partial reset of RPS, specific to becoming formed
|
||||
-- without this, auto control can't resume on chunk load
|
||||
smem.q.mq_rps.push_command(MQ__RPS_CMD.RESET_REATTACH)
|
||||
elseif plc_state.reactor_formed and (rps.is_formed() == false) then
|
||||
-- reactor no longer formed
|
||||
println_ts("reactor is no longer formed")
|
||||
log.info("reactor is no longer formed")
|
||||
|
||||
plc_state.reactor_formed = false
|
||||
plc_state.degraded = true
|
||||
end
|
||||
|
||||
-- update indicators
|
||||
databus.tx_hw_status(plc_state)
|
||||
end
|
||||
|
||||
-- start clock
|
||||
loop_clock.start()
|
||||
|
||||
@@ -58,90 +118,30 @@ function threads.thread__main(smem)
|
||||
local event, param1, param2, param3, param4, param5 = util.pull_event()
|
||||
|
||||
-- handle event
|
||||
if event == "timer" and loop_clock.is_clock(param1) then
|
||||
-- blink heartbeat indicator
|
||||
databus.heartbeat()
|
||||
|
||||
-- start next clock timer
|
||||
loop_clock.start()
|
||||
|
||||
-- periodic hardware tasks
|
||||
backplane.periodic()
|
||||
|
||||
-- send updated data or try to link
|
||||
if networked then
|
||||
if plc_comms.is_linked() then
|
||||
smem.q.mq_comms_tx.push_command(MQ__COMM_CMD.SEND_STATUS)
|
||||
|
||||
plc_comms.manage_failover(backplane.active_nic())
|
||||
elseif ticks_to_update == 0 then
|
||||
local a_nic, s_nic = backplane.active_nic(), backplane.standby_nic()
|
||||
|
||||
if a_nic.is_network_up() then
|
||||
plc_comms.send_link_req(a_nic)
|
||||
elseif s_nic and s_nic.is_network_up() then
|
||||
plc_comms.send_link_req(s_nic)
|
||||
end
|
||||
|
||||
ticks_to_update = LINK_TICKS
|
||||
else
|
||||
ticks_to_update = ticks_to_update - 1
|
||||
end
|
||||
end
|
||||
|
||||
-- check for formed state change
|
||||
if (not plc_state.reactor_formed) and rps.is_formed() then
|
||||
-- reactor now formed
|
||||
plc_state.reactor_formed = true
|
||||
|
||||
println_ts("reactor is now formed")
|
||||
log.info("reactor is now formed")
|
||||
|
||||
-- SCRAM newly formed reactor
|
||||
smem.q.mq_rps.push_command(MQ__RPS_CMD.SCRAM)
|
||||
|
||||
-- determine if we are still in a degraded state
|
||||
if (not networked) or backplane.active_nic().is_connected() then
|
||||
plc_state.degraded = false
|
||||
end
|
||||
|
||||
-- partial reset of RPS, specific to becoming formed
|
||||
-- without this, auto control can't resume on chunk load
|
||||
smem.q.mq_rps.push_command(MQ__RPS_CMD.RESET_REATTACH)
|
||||
elseif plc_state.reactor_formed and (rps.is_formed() == false) then
|
||||
-- reactor no longer formed
|
||||
println_ts("reactor is no longer formed")
|
||||
log.info("reactor is no longer formed")
|
||||
|
||||
plc_state.reactor_formed = false
|
||||
plc_state.degraded = true
|
||||
end
|
||||
|
||||
-- update indicators
|
||||
databus.tx_hw_status(plc_state)
|
||||
elseif event == "modem_message" and networked then
|
||||
if event == "modem_message" and networked then
|
||||
-- got a packet
|
||||
local packet = plc_comms.parse_packet(param1, param2, param3, param4, param5)
|
||||
if packet ~= nil then
|
||||
-- pass the packet onto the comms message queue
|
||||
smem.q.mq_comms_rx.push_network(packet)
|
||||
end
|
||||
elseif event == "timer" and networked and conn_watchdog.is_timer(param1) then
|
||||
-- haven't heard from server recently? close connection and shutdown reactor
|
||||
plc_comms.close()
|
||||
smem.q.mq_rps.push_command(MQ__RPS_CMD.TRIP_TIMEOUT)
|
||||
elseif event == "timer" then
|
||||
-- notify timer callback dispatcher if no other timer case claimed this event
|
||||
tcd.handle(param1)
|
||||
elseif event == "peripheral_detach" then
|
||||
-- peripheral disconnect
|
||||
local type, device = ppm.handle_unmount(param1)
|
||||
if type ~= nil and device ~= nil then
|
||||
backplane.detach(param1, type, device, println_ts)
|
||||
-- pass this timer event onto the right handler
|
||||
if loop_clock.is_clock(param1) then
|
||||
-- main loop tick
|
||||
loop_tick()
|
||||
elseif networked and conn_watchdog.is_timer(param1) then
|
||||
-- supervisor connection timed out
|
||||
plc_comms.close()
|
||||
smem.q.mq_rps.push_command(MQ__RPS_CMD.TRIP_TIMEOUT)
|
||||
else
|
||||
-- notify timer callback dispatcher, no other handler claimed this event
|
||||
tcd.handle(param1)
|
||||
end
|
||||
|
||||
-- update indicators
|
||||
databus.tx_hw_status(plc_state)
|
||||
elseif event == "mouse_click" or event == "mouse_up" or event == "mouse_drag" or event == "mouse_scroll" or
|
||||
event == "double_click" then
|
||||
-- handle a mouse event
|
||||
renderer.handle_mouse(core.events.new_mouse_event(event, param1, param2, param3))
|
||||
elseif event == "peripheral" then
|
||||
-- peripheral connect
|
||||
local type, device = ppm.mount(param1)
|
||||
@@ -151,10 +151,15 @@ function threads.thread__main(smem)
|
||||
|
||||
-- update indicators
|
||||
databus.tx_hw_status(plc_state)
|
||||
elseif event == "mouse_click" or event == "mouse_up" or event == "mouse_drag" or event == "mouse_scroll" or
|
||||
event == "double_click" then
|
||||
-- handle a mouse event
|
||||
renderer.handle_mouse(core.events.new_mouse_event(event, param1, param2, param3))
|
||||
elseif event == "peripheral_detach" then
|
||||
-- peripheral disconnect
|
||||
local type, device = ppm.handle_unmount(param1)
|
||||
if type ~= nil and device ~= nil then
|
||||
backplane.detach(param1, type, device, println_ts)
|
||||
end
|
||||
|
||||
-- update indicators
|
||||
databus.tx_hw_status(plc_state)
|
||||
end
|
||||
|
||||
-- check for termination request
|
||||
@@ -209,7 +214,9 @@ function threads.thread__rps(smem)
|
||||
-- load in from shared memory
|
||||
local networked = smem.networked
|
||||
local plc_state = smem.plc_state
|
||||
local plc_dev = smem.plc_dev
|
||||
|
||||
local rps = smem.plc_sys.rps
|
||||
local plc_comms = smem.plc_sys.plc_comms
|
||||
|
||||
local rps_queue = smem.q.mq_rps
|
||||
|
||||
@@ -220,12 +227,6 @@ function threads.thread__rps(smem)
|
||||
|
||||
-- thread loop
|
||||
while true do
|
||||
-- get plc_sys fields (may have been set late due to degraded boot)
|
||||
local rps = smem.plc_sys.rps
|
||||
local plc_comms = smem.plc_sys.plc_comms
|
||||
-- get reactor, it may have changed due to a disconnect/reconnect
|
||||
local reactor = plc_dev.reactor
|
||||
|
||||
-- SCRAM if no open connection
|
||||
if networked and not plc_comms.is_linked() then
|
||||
if was_linked then
|
||||
@@ -236,12 +237,13 @@ function threads.thread__rps(smem)
|
||||
|
||||
-- check reactor status
|
||||
if (not plc_state.no_reactor) and rps.is_formed() then
|
||||
local reactor_status = reactor.getStatus()
|
||||
databus.tx_reactor_state(reactor_status)
|
||||
local active = rps.check_active()
|
||||
|
||||
databus.tx_reactor_state(active)
|
||||
|
||||
-- if we tried to SCRAM but failed, keep trying
|
||||
-- in that case, SCRAM won't be called until it reconnects (this is the expected use of this check)
|
||||
if rps.is_tripped() and reactor_status then rps.scram() end
|
||||
if rps.is_tripped() and active then rps.scram() end
|
||||
end
|
||||
|
||||
-- if we are in standalone mode and the front panel isn't working, continuously reset RPS
|
||||
@@ -345,6 +347,8 @@ function threads.thread__comms_tx(smem)
|
||||
|
||||
-- load in from shared memory
|
||||
local plc_state = smem.plc_state
|
||||
local plc_comms = smem.plc_sys.plc_comms
|
||||
|
||||
local comms_queue = smem.q.mq_comms_tx
|
||||
|
||||
local MQ__COMM_CMD = smem.q_types.MQ__COMM_CMD
|
||||
@@ -353,9 +357,6 @@ function threads.thread__comms_tx(smem)
|
||||
|
||||
-- thread loop
|
||||
while true do
|
||||
-- get plc_sys fields (may have been set late due to degraded boot)
|
||||
local plc_comms = smem.plc_sys.plc_comms
|
||||
|
||||
-- check for messages in the message queue
|
||||
while comms_queue.ready() and not plc_state.shutdown do
|
||||
local msg = comms_queue.pop()
|
||||
@@ -427,15 +428,14 @@ function threads.thread__comms_rx(smem)
|
||||
local plc_state = smem.plc_state
|
||||
local setpoints = smem.setpoints
|
||||
|
||||
local plc_comms = smem.plc_sys.plc_comms
|
||||
|
||||
local comms_queue = smem.q.mq_comms_rx
|
||||
|
||||
local last_update = util.time()
|
||||
|
||||
-- thread loop
|
||||
while true do
|
||||
-- get plc_sys fields (may have been set late due to degraded boot)
|
||||
local plc_comms = smem.plc_sys.plc_comms
|
||||
|
||||
-- check for messages in the message queue
|
||||
while comms_queue.ready() and not plc_state.shutdown do
|
||||
local msg = comms_queue.pop()
|
||||
@@ -499,89 +499,22 @@ function threads.thread__setpoint_control(smem)
|
||||
log.debug("OS: setpoint control thread start")
|
||||
|
||||
-- load in from shared memory
|
||||
local plc_state = smem.plc_state
|
||||
local setpoints = smem.setpoints
|
||||
local plc_dev = smem.plc_dev
|
||||
local plc_state = smem.plc_state
|
||||
local plc_dev = smem.plc_dev
|
||||
|
||||
local last_update = util.time()
|
||||
local running = false
|
||||
|
||||
local last_burn_sp = 0.0
|
||||
local last_update = util.time()
|
||||
|
||||
-- do not use the actual elapsed time, it could spike
|
||||
-- we do not want to have big jumps as that is what we are trying to avoid in the first place
|
||||
local min_elapsed_s = SP_CTRL_SLEEP / 1000.0
|
||||
|
||||
-- init controller
|
||||
spctl.init(smem)
|
||||
|
||||
-- thread loop
|
||||
while true do
|
||||
-- get plc_sys fields (may have been set late due to degraded boot)
|
||||
local rps = smem.plc_sys.rps
|
||||
-- get reactor, may have changed do to disconnect/reconnect
|
||||
local reactor = plc_dev.reactor
|
||||
|
||||
if not plc_state.no_reactor then
|
||||
-- check if we should start ramping
|
||||
if setpoints.burn_rate_en and (setpoints.burn_rate ~= last_burn_sp) then
|
||||
local cur_burn_rate = reactor.getBurnRate()
|
||||
|
||||
if (type(cur_burn_rate) == "number") and (setpoints.burn_rate ~= cur_burn_rate) and rps.is_active() then
|
||||
last_burn_sp = setpoints.burn_rate
|
||||
|
||||
-- update without ramp if <= 2.5 mB/t increase
|
||||
-- no need to ramp down, as the ramp up poses the safety risks
|
||||
running = (setpoints.burn_rate - cur_burn_rate) > 2.5
|
||||
|
||||
if running then
|
||||
log.debug(util.c("SPCTL: starting burn rate ramp from ", cur_burn_rate, " mB/t to ", setpoints.burn_rate, " mB/t"))
|
||||
else
|
||||
log.debug(util.c("SPCTL: setting burn rate directly to ", setpoints.burn_rate, " mB/t"))
|
||||
reactor.setBurnRate(setpoints.burn_rate)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- only check I/O if active to save on processing time
|
||||
if running then
|
||||
-- clear so we can later evaluate if we should keep running
|
||||
running = false
|
||||
|
||||
-- adjust burn rate (setpoints.burn_rate)
|
||||
if setpoints.burn_rate_en then
|
||||
if rps.is_active() then
|
||||
local current_burn_rate = reactor.getBurnRate()
|
||||
|
||||
-- we yielded, check enable again
|
||||
if setpoints.burn_rate_en and (type(current_burn_rate) == "number") and (current_burn_rate ~= setpoints.burn_rate) then
|
||||
-- calculate new burn rate
|
||||
local new_burn_rate ---@type number
|
||||
|
||||
if setpoints.burn_rate > current_burn_rate then
|
||||
-- need to ramp up
|
||||
new_burn_rate = current_burn_rate + (BURN_RATE_RAMP_mB_s * min_elapsed_s)
|
||||
if new_burn_rate > setpoints.burn_rate then new_burn_rate = setpoints.burn_rate end
|
||||
else
|
||||
-- need to ramp down
|
||||
new_burn_rate = current_burn_rate - (BURN_RATE_RAMP_mB_s * min_elapsed_s)
|
||||
if new_burn_rate < setpoints.burn_rate then new_burn_rate = setpoints.burn_rate end
|
||||
end
|
||||
|
||||
running = running or (new_burn_rate ~= setpoints.burn_rate)
|
||||
|
||||
-- set the burn rate
|
||||
reactor.setBurnRate(new_burn_rate)
|
||||
end
|
||||
else
|
||||
log.debug("SPCTL: ramping aborted (reactor inactive)")
|
||||
setpoints.burn_rate_en = false
|
||||
end
|
||||
end
|
||||
elseif setpoints.burn_rate_en then
|
||||
log.debug(util.c("SPCTL: ramping completed (setpoint of ", setpoints.burn_rate, " mB/t)"))
|
||||
setpoints.burn_rate_en = false
|
||||
end
|
||||
|
||||
-- if ramping completed or was aborted, reset last burn setpoint so that if it is requested again it will be re-attempted
|
||||
if not setpoints.burn_rate_en then last_burn_sp = 0 end
|
||||
spctl.update(plc_dev.reactor, min_elapsed_s)
|
||||
end
|
||||
|
||||
-- check for termination request
|
||||
|
||||
@@ -285,9 +285,9 @@ function check.create(main_pane, settings_cfg, check_sys, style)
|
||||
|
||||
local sc = Div{parent=check_sys,x=2,y=4,width=49}
|
||||
|
||||
TextBox{parent=check_sys,x=1,y=2,text=" RTU Gateway Self-Check",fg_bg=bw_fg_bg}
|
||||
TextBox{parent=check_sys,y=2,text=" RTU Gateway Self-Check",fg_bg=bw_fg_bg}
|
||||
|
||||
self.sc_log = ListBox{parent=sc,x=1,y=1,height=12,width=49,scroll_height=1000,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
self.sc_log = ListBox{parent=sc,y=1,height=12,width=49,scroll_height=1000,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
local last_check = { nil, nil }
|
||||
|
||||
@@ -310,7 +310,7 @@ function check.create(main_pane, settings_cfg, check_sys, style)
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=sc,x=1,y=14,text="\x1b Back",callback=function()exit_self_check(main_pane)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sc,y=14,text="\x1b Back",callback=function()exit_self_check(main_pane)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
self.run_test_btn = PushButton{parent=sc,x=40,y=14,min_width=10,text="Run Test",callback=function()self_check()end,fg_bg=cpair(colors.black,colors.blue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
end
|
||||
|
||||
|
||||
@@ -72,11 +72,11 @@ function peripherals.create(tool_ctl, main_pane, cfg_sys, peri_cfg, style)
|
||||
local peri_c_6 = Div{parent=peri_cfg,x=2,y=4,width=49}
|
||||
local peri_c_7 = Div{parent=peri_cfg,x=2,y=4,width=49}
|
||||
|
||||
local peri_pane = MultiPane{parent=peri_cfg,x=1,y=4,panes={peri_c_1,peri_c_2,peri_c_3,peri_c_4,peri_c_5,peri_c_6,peri_c_7}}
|
||||
local peri_pane = MultiPane{parent=peri_cfg,y=4,panes={peri_c_1,peri_c_2,peri_c_3,peri_c_4,peri_c_5,peri_c_6,peri_c_7}}
|
||||
|
||||
TextBox{parent=peri_cfg,x=1,y=2,text=" Peripheral Connections",fg_bg=cpair(colors.black,colors.purple)}
|
||||
TextBox{parent=peri_cfg,y=2,text=" Peripheral Connections",fg_bg=cpair(colors.black,colors.purple)}
|
||||
|
||||
local peri_list = ListBox{parent=peri_c_1,x=1,y=1,height=12,width=49,scroll_height=1000,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
local peri_list = ListBox{parent=peri_c_1,y=1,height=12,width=49,scroll_height=1000,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
local function peri_revert()
|
||||
tmp_cfg.Peripherals = tool_ctl.deep_copy_peri(ini_cfg.Peripherals)
|
||||
@@ -99,22 +99,22 @@ function peripherals.create(tool_ctl, main_pane, cfg_sys, peri_cfg, style)
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=peri_c_1,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=peri_c_1,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
local peri_revert_btn = PushButton{parent=peri_c_1,x=8,y=14,min_width=16,text="Revert Changes",callback=peri_revert,fg_bg=cpair(colors.black,colors.yellow),active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
PushButton{parent=peri_c_1,x=35,y=14,min_width=7,text="Add +",callback=function()peri_pane.set_value(2)end,fg_bg=cpair(colors.black,colors.blue),active_fg_bg=btn_act_fg_bg}
|
||||
local peri_apply_btn = PushButton{parent=peri_c_1,x=43,y=14,min_width=7,text="Apply",callback=peri_apply,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
|
||||
TextBox{parent=peri_c_2,x=1,y=1,text="Select one of the below devices to use."}
|
||||
TextBox{parent=peri_c_2,y=1,text="Select one of the below devices to use."}
|
||||
|
||||
self.ppm_devs = ListBox{parent=peri_c_2,x=1,y=3,height=10,width=49,scroll_height=1000,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
self.ppm_devs = ListBox{parent=peri_c_2,y=3,height=10,width=49,scroll_height=1000,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
PushButton{parent=peri_c_2,x=1,y=14,text="\x1b Back",callback=function()peri_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=peri_c_2,y=14,text="\x1b Back",callback=function()peri_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=peri_c_2,x=8,y=14,min_width=10,text="Manual +",callback=function()peri_pane.set_value(3)end,fg_bg=cpair(colors.black,colors.orange),active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=peri_c_2,x=26,y=14,min_width=24,text="I don't see my device!",callback=function()peri_pane.set_value(7)end,fg_bg=cpair(colors.black,colors.yellow),active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=peri_c_7,x=1,y=1,height=10,text="Make sure your device is either touching the RTU or connected via wired modems. There should be a wired modem on a side of the RTU then one on the device, connected by a cable. The modem on the device needs to be right clicked to connect it (which will turn its border red), at which point the peripheral name will be shown in the chat."}
|
||||
TextBox{parent=peri_c_7,x=1,y=9,height=4,text="If it still does not show, it may not be compatible. Currently only Boilers, Turbines, Dynamic Tanks, SNAs, SPSs, Induction Matricies, and Environment Detectors are supported."}
|
||||
PushButton{parent=peri_c_7,x=1,y=14,text="\x1b Back",callback=function()peri_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
TextBox{parent=peri_c_7,y=1,height=10,text="Make sure your device is either touching the RTU or connected via wired modems. There should be a wired modem on a side of the RTU then one on the device, connected by a cable. The modem on the device needs to be right clicked to connect it (which will turn its border red), at which point the peripheral name will be shown in the chat."}
|
||||
TextBox{parent=peri_c_7,y=9,height=4,text="If it still does not show, it may not be compatible. Currently only Boilers, Turbines, Dynamic Tanks, SNAs, SPSs, Induction Matricies, and Environment Detectors are supported."}
|
||||
PushButton{parent=peri_c_7,y=14,text="\x1b Back",callback=function()peri_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
local new_peri_attrs = { "", "" }
|
||||
local function new_peri(name, type)
|
||||
@@ -201,7 +201,7 @@ function peripherals.create(tool_ctl, main_pane, cfg_sys, peri_cfg, style)
|
||||
|
||||
---@cast entry ppm_entry
|
||||
local line = Div{parent=self.ppm_devs,height=2,fg_bg=cpair(colors.black,bkg)}
|
||||
PushButton{parent=line,x=1,y=1,min_width=9,alignment=LEFT,height=1,text="> SELECT",callback=function()new_peri(name,entry.type)end,fg_bg=cpair(colors.black,colors.purple),active_fg_bg=cpair(colors.white,colors.black)}
|
||||
PushButton{parent=line,y=1,min_width=9,alignment=LEFT,height=1,text="> SELECT",callback=function()new_peri(name,entry.type)end,fg_bg=cpair(colors.black,colors.purple),active_fg_bg=cpair(colors.white,colors.black)}
|
||||
TextBox{parent=line,x=11,y=1,text=name,fg_bg=cpair(colors.black,bkg)}
|
||||
TextBox{parent=line,x=11,y=2,text=entry.type,fg_bg=cpair(colors.gray,bkg)}
|
||||
|
||||
@@ -212,10 +212,10 @@ function peripherals.create(tool_ctl, main_pane, cfg_sys, peri_cfg, style)
|
||||
|
||||
tool_ctl.update_peri_list()
|
||||
|
||||
TextBox{parent=peri_c_3,x=1,y=1,height=4,text="This feature is intended for advanced users. If you just can't see your device, click 'I don't see my device!' instead."}
|
||||
TextBox{parent=peri_c_3,x=1,y=5,height=4,text="Peripheral Name"}
|
||||
local p_name = TextField{parent=peri_c_3,x=1,y=6,width=49,height=1,max_len=128,fg_bg=bw_fg_bg}
|
||||
local p_type = Radio2D{parent=peri_c_3,x=1,y=8,rows=5,columns=2,default=1,options=RTU_DEV_TYPES,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.purple}
|
||||
TextBox{parent=peri_c_3,y=1,height=4,text="This feature is intended for advanced users. If you just can't see your device, click 'I don't see my device!' instead."}
|
||||
TextBox{parent=peri_c_3,y=5,height=4,text="Peripheral Name"}
|
||||
local p_name = TextField{parent=peri_c_3,y=6,width=49,height=1,max_len=128,fg_bg=bw_fg_bg}
|
||||
local p_type = Radio2D{parent=peri_c_3,y=8,rows=5,columns=2,default=1,options=RTU_DEV_TYPES,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.purple}
|
||||
local man_p_err = TextBox{parent=peri_c_3,x=8,y=14,width=35,text="Please enter a peripheral name.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
man_p_err.hide(true)
|
||||
|
||||
@@ -228,13 +228,13 @@ function peripherals.create(tool_ctl, main_pane, cfg_sys, peri_cfg, style)
|
||||
else man_p_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=peri_c_3,x=1,y=14,text="\x1b Back",callback=function()peri_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=peri_c_3,y=14,text="\x1b Back",callback=function()peri_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=peri_c_3,x=44,y=14,text="Next \x1a",callback=submit_manual_peri,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
self.p_name_msg = TextBox{parent=peri_c_4,x=1,y=1,height=2,text=""}
|
||||
self.p_prompt = TextBox{parent=peri_c_4,x=1,y=4,height=2,text=""}
|
||||
self.p_name_msg = TextBox{parent=peri_c_4,y=1,height=2,text=""}
|
||||
self.p_prompt = TextBox{parent=peri_c_4,y=4,height=2,text=""}
|
||||
self.p_idx = NumberField{parent=peri_c_4,x=31,y=4,width=4,max_chars=2,min=1,max=2,default=1,fg_bg=bw_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
self.p_assign_btn = RadioButton{parent=peri_c_4,x=1,y=5,default=1,options={"the facility","reactor unit #"},callback=function(v)self.p_assign(v)end,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.purple}
|
||||
self.p_assign_btn = RadioButton{parent=peri_c_4,y=5,default=1,options={"the facility","reactor unit #"},callback=function(v)self.p_assign(v)end,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.purple}
|
||||
|
||||
self.p_unit = NumberField{parent=peri_c_4,x=23,y=4,width=4,max_chars=2,min=1,max=4,default=1,fg_bg=bw_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
self.p_unit.disable()
|
||||
@@ -252,8 +252,8 @@ function peripherals.create(tool_ctl, main_pane, cfg_sys, peri_cfg, style)
|
||||
end
|
||||
end
|
||||
|
||||
self.p_desc = TextBox{parent=peri_c_4,x=1,y=7,height=6,text="",fg_bg=g_lg_fg_bg}
|
||||
self.p_desc_ext = TextBox{parent=peri_c_4,x=1,y=6,height=7,text="",fg_bg=g_lg_fg_bg}
|
||||
self.p_desc = TextBox{parent=peri_c_4,y=7,height=6,text="",fg_bg=g_lg_fg_bg}
|
||||
self.p_desc_ext = TextBox{parent=peri_c_4,y=6,height=7,text="",fg_bg=g_lg_fg_bg}
|
||||
|
||||
self.p_err = TextBox{parent=peri_c_4,x=8,y=14,width=32,text="",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
self.p_err.hide(true)
|
||||
@@ -337,15 +337,15 @@ function peripherals.create(tool_ctl, main_pane, cfg_sys, peri_cfg, style)
|
||||
self.p_idx.set_value(1)
|
||||
end
|
||||
|
||||
PushButton{parent=peri_c_4,x=1,y=14,text="\x1b Back",callback=back_from_peri_opts,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=peri_c_4,y=14,text="\x1b Back",callback=back_from_peri_opts,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=peri_c_4,x=41,y=14,min_width=9,text="Confirm",callback=save_peri_entry,fg_bg=cpair(colors.black,colors.blue),active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=peri_c_5,x=1,y=1,text="Settings saved!"}
|
||||
PushButton{parent=peri_c_5,x=1,y=14,text="\x1b Back",callback=function()peri_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
TextBox{parent=peri_c_5,y=1,text="Settings saved!"}
|
||||
PushButton{parent=peri_c_5,y=14,text="\x1b Back",callback=function()peri_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=peri_c_5,x=44,y=14,min_width=6,text="Home",callback=function()tool_ctl.go_home()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=peri_c_6,x=1,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=peri_c_6,x=1,y=14,text="\x1b Back",callback=function()peri_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
TextBox{parent=peri_c_6,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=peri_c_6,y=14,text="\x1b Back",callback=function()peri_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=peri_c_6,x=44,y=14,min_width=6,text="Home",callback=function()tool_ctl.go_home()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -405,9 +405,9 @@ function peripherals.create(tool_ctl, main_pane, cfg_sys, peri_cfg, style)
|
||||
end
|
||||
|
||||
local entry = Div{parent=peri_list,height=3}
|
||||
TextBox{parent=entry,x=1,y=1,text="@ "..def.name,fg_bg=cpair(colors.black,colors.white)}
|
||||
TextBox{parent=entry,x=1,y=2,text=" \x1a "..t_str,fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=entry,x=1,y=3,text=desc,fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=entry,y=1,text="@ "..def.name,fg_bg=cpair(colors.black,colors.white)}
|
||||
TextBox{parent=entry,y=2,text=" \x1a "..t_str,fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=entry,y=3,text=desc,fg_bg=cpair(colors.gray,colors.white)}
|
||||
local edit_btn = PushButton{parent=entry,x=41,y=2,min_width=8,height=1,text="EDIT",callback=function()edit_peri_entry(i,def,t or "")end,fg_bg=cpair(colors.black,colors.blue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
PushButton{parent=entry,x=41,y=3,min_width=8,height=1,text="DELETE",callback=function()delete_peri_entry(i)end,fg_bg=cpair(colors.black,colors.red),active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
|
||||
@@ -168,14 +168,14 @@ function redstone.create(tool_ctl, main_pane, cfg_sys, rs_cfg, style)
|
||||
local rs_c_9 = Div{parent=rs_cfg,x=2,y=4,width=49}
|
||||
local rs_c_10 = Div{parent=rs_cfg,x=2,y=4,width=49}
|
||||
|
||||
local rs_pane = MultiPane{parent=rs_cfg,x=1,y=4,panes={rs_c_1,rs_c_2,rs_c_3,rs_c_4,rs_c_5,rs_c_6,rs_c_7,rs_c_8,rs_c_9,rs_c_10}}
|
||||
local rs_pane = MultiPane{parent=rs_cfg,y=4,panes={rs_c_1,rs_c_2,rs_c_3,rs_c_4,rs_c_5,rs_c_6,rs_c_7,rs_c_8,rs_c_9,rs_c_10}}
|
||||
|
||||
local header = TextBox{parent=rs_cfg,x=1,y=2,text=" Redstone Connections",fg_bg=cpair(colors.black,colors.red)}
|
||||
local header = TextBox{parent=rs_cfg,y=2,text=" Redstone Connections",fg_bg=cpair(colors.black,colors.red)}
|
||||
|
||||
--#region Interface Selection
|
||||
|
||||
TextBox{parent=rs_c_1,x=1,y=1,text="Configure this computer or a redstone relay."}
|
||||
local iface_list = ListBox{parent=rs_c_1,x=1,y=3,height=10,width=49,scroll_height=1000,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
TextBox{parent=rs_c_1,y=1,text="Configure this computer or a redstone relay."}
|
||||
local iface_list = ListBox{parent=rs_c_1,y=3,height=10,width=49,scroll_height=1000,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
-- update relay interface list
|
||||
function tool_ctl.update_relay_list()
|
||||
@@ -209,7 +209,7 @@ function redstone.create(tool_ctl, main_pane, cfg_sys, rs_cfg, style)
|
||||
end
|
||||
|
||||
local line = Div{parent=iface_list,height=2,fg_bg=cpair(colors.black,colors.white)}
|
||||
TextBox{parent=line,x=1,y=1,text="@ local",fg_bg=cpair(colors.black,colors.white)}
|
||||
TextBox{parent=line,y=1,text="@ local",fg_bg=cpair(colors.black,colors.white)}
|
||||
TextBox{parent=line,x=3,y=2,text="This Computer",fg_bg=cpair(colors.gray,colors.white)}
|
||||
local count = #redstone_subset(ini_cfg.Redstone, nil)
|
||||
TextBox{parent=line,x=33,y=2,width=16,alignment=core.ALIGN.RIGHT,text=count.." connections",fg_bg=cpair(colors.gray,colors.white)}
|
||||
@@ -220,7 +220,7 @@ function redstone.create(tool_ctl, main_pane, cfg_sys, rs_cfg, style)
|
||||
local name = relays[i]
|
||||
|
||||
line = Div{parent=iface_list,height=2,fg_bg=cpair(colors.black,colors.white)}
|
||||
TextBox{parent=line,x=1,y=1,text="@ "..name,fg_bg=cpair(colors.black,colors.white)}
|
||||
TextBox{parent=line,y=1,text="@ "..name,fg_bg=cpair(colors.black,colors.white)}
|
||||
TextBox{parent=line,x=3,y=2,text="Redstone Relay",fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=line,x=18,y=2,text=tri(mounts[name],"ONLINE","OFFLINE"),fg_bg=cpair(tri(mounts[name],colors.green,colors.red),colors.white)}
|
||||
count = #redstone_subset(ini_cfg.Redstone, name)
|
||||
@@ -232,14 +232,14 @@ function redstone.create(tool_ctl, main_pane, cfg_sys, rs_cfg, style)
|
||||
|
||||
tool_ctl.update_relay_list()
|
||||
|
||||
PushButton{parent=rs_c_1,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=rs_c_1,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=rs_c_1,x=27,y=14,min_width=23,text="I don't see my relay!",callback=function()rs_pane.set_value(10)end,fg_bg=cpair(colors.black,colors.yellow),active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
--#region Configuration List
|
||||
|
||||
TextBox{parent=rs_c_2,x=1,y=1,text=" port side/color unit/facility",fg_bg=g_lg_fg_bg}
|
||||
local rs_list = ListBox{parent=rs_c_2,x=1,y=2,height=11,width=49,scroll_height=200,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
TextBox{parent=rs_c_2,y=1,text=" port side/color unit/facility",fg_bg=g_lg_fg_bg}
|
||||
local rs_list = ListBox{parent=rs_c_2,y=2,height=11,width=49,scroll_height=200,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
local function rs_revert()
|
||||
tmp_cfg.Redstone = tool_ctl.deep_copy_rs(ini_cfg.Redstone)
|
||||
@@ -275,7 +275,7 @@ function redstone.create(tool_ctl, main_pane, cfg_sys, rs_cfg, style)
|
||||
header.set_value(" Redstone Connections")
|
||||
end
|
||||
|
||||
PushButton{parent=rs_c_2,x=1,y=14,text="\x1b Back",callback=rs_back,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=rs_c_2,y=14,text="\x1b Back",callback=rs_back,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
local rs_revert_btn = PushButton{parent=rs_c_2,x=8,y=14,min_width=16,text="Revert Changes",callback=rs_revert,fg_bg=cpair(colors.black,colors.yellow),active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
PushButton{parent=rs_c_2,x=35,y=14,min_width=7,text="New +",callback=function()rs_pane.set_value(3)end,fg_bg=cpair(colors.black,colors.blue),active_fg_bg=btn_act_fg_bg}
|
||||
local rs_apply_btn = PushButton{parent=rs_c_2,x=43,y=14,min_width=7,text="Apply",callback=rs_apply,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
@@ -283,9 +283,9 @@ function redstone.create(tool_ctl, main_pane, cfg_sys, rs_cfg, style)
|
||||
--#endregion
|
||||
--#region Port Selection
|
||||
|
||||
TextBox{parent=rs_c_3,x=1,y=1,text="Select one of the below ports to use."}
|
||||
TextBox{parent=rs_c_3,y=1,text="Select one of the below ports to use."}
|
||||
|
||||
local rs_ports = ListBox{parent=rs_c_3,x=1,y=3,height=10,width=49,scroll_height=200,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
local rs_ports = ListBox{parent=rs_c_3,y=3,height=10,width=49,scroll_height=200,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
local function new_rs(port)
|
||||
self.rs_cfg_editing = false
|
||||
@@ -298,6 +298,7 @@ function redstone.create(tool_ctl, main_pane, cfg_sys, rs_cfg, style)
|
||||
self.rs_cfg_side_l.set_value("Output Side")
|
||||
self.rs_cfg_bundled.enable()
|
||||
self.rs_cfg_advanced.disable()
|
||||
|
||||
text = "You selected the ALL_WASTE shortcut."
|
||||
else
|
||||
self.rs_cfg_shortcut.hide(true)
|
||||
@@ -329,17 +330,15 @@ function redstone.create(tool_ctl, main_pane, cfg_sys, rs_cfg, style)
|
||||
io_type = "analog output "
|
||||
end
|
||||
|
||||
text = "You selected the " .. io_type .. rsio.to_string(port) .. " (for "
|
||||
text = "You selected the " .. io_type .. rsio.to_string(port) .. " (for " .. tri(PORT_DSGN[port] == 1, "a unit).", "the facility).")
|
||||
end
|
||||
|
||||
if PORT_DSGN[port] == 1 then
|
||||
text = text .. "a unit)."
|
||||
self.rs_cfg_unit_l.show()
|
||||
self.rs_cfg_unit.show()
|
||||
else
|
||||
self.rs_cfg_unit_l.hide(true)
|
||||
self.rs_cfg_unit.hide(true)
|
||||
text = text .. "the facility)."
|
||||
end
|
||||
if PORT_DSGN[port] == 1 then
|
||||
self.rs_cfg_unit_l.show()
|
||||
self.rs_cfg_unit.show()
|
||||
else
|
||||
self.rs_cfg_unit_l.hide(true)
|
||||
self.rs_cfg_unit.hide(true)
|
||||
end
|
||||
|
||||
self.rs_cfg_selection.set_value(text)
|
||||
@@ -349,7 +348,7 @@ function redstone.create(tool_ctl, main_pane, cfg_sys, rs_cfg, style)
|
||||
|
||||
-- add entries to redstone option list
|
||||
local all_w_macro = Div{parent=rs_ports,height=1}
|
||||
PushButton{parent=all_w_macro,x=1,y=1,min_width=14,alignment=LEFT,height=1,text=">ALL_WASTE",callback=function()new_rs(-1)end,fg_bg=cpair(colors.black,colors.green),active_fg_bg=cpair(colors.white,colors.black)}
|
||||
PushButton{parent=all_w_macro,y=1,min_width=14,alignment=LEFT,height=1,text=">ALL_WASTE",callback=function()new_rs(-1)end,fg_bg=cpair(colors.black,colors.green),active_fg_bg=cpair(colors.white,colors.black)}
|
||||
TextBox{parent=all_w_macro,x=16,y=1,width=5,text="[n/a]",fg_bg=cpair(colors.lightGray,colors.white)}
|
||||
TextBox{parent=all_w_macro,x=22,y=1,text="Create all 4 waste entries",fg_bg=cpair(colors.gray,colors.white)}
|
||||
|
||||
@@ -360,22 +359,22 @@ function redstone.create(tool_ctl, main_pane, cfg_sys, rs_cfg, style)
|
||||
local btn_color = tri(rsio.get_io_dir(p) == rsio.IO_DIR.IN, colors.yellow, colors.lightBlue)
|
||||
|
||||
local entry = Div{parent=rs_ports,height=1}
|
||||
PushButton{parent=entry,x=1,y=1,min_width=14,alignment=LEFT,height=1,text=">"..name,callback=function()new_rs(p)end,fg_bg=cpair(colors.black,btn_color),active_fg_bg=cpair(colors.white,colors.black)}
|
||||
PushButton{parent=entry,y=1,min_width=14,alignment=LEFT,height=1,text=">"..name,callback=function()new_rs(p)end,fg_bg=cpair(colors.black,btn_color),active_fg_bg=cpair(colors.white,colors.black)}
|
||||
TextBox{parent=entry,x=16,y=1,width=5,text=io_dir,fg_bg=cpair(colors.lightGray,colors.white)}
|
||||
TextBox{parent=entry,x=22,y=1,text=PORT_DESC_MAP[i][2],fg_bg=cpair(colors.gray,colors.white)}
|
||||
end
|
||||
|
||||
PushButton{parent=rs_c_3,x=1,y=14,text="\x1b Back",callback=function()rs_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=rs_c_3,y=14,text="\x1b Back",callback=function()rs_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
--#region Port Configuration
|
||||
|
||||
self.rs_cfg_selection = TextBox{parent=rs_c_4,x=1,y=1,height=2,text=""}
|
||||
self.rs_cfg_selection = TextBox{parent=rs_c_4,y=1,height=2,text=""}
|
||||
|
||||
PushButton{parent=rs_c_4,x=36,y=3,text="What's that?",min_width=14,callback=function()rs_pane.set_value(8)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
self.rs_cfg_side_l = TextBox{parent=rs_c_4,x=1,y=4,width=11,text="Output Side"}
|
||||
local side = Radio2D{parent=rs_c_4,x=1,y=5,rows=1,columns=6,default=1,options=side_options,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.red}
|
||||
self.rs_cfg_side_l = TextBox{parent=rs_c_4,y=4,width=11,text="Output Side"}
|
||||
local side = Radio2D{parent=rs_c_4,y=5,rows=1,columns=6,default=1,options=side_options,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.red}
|
||||
|
||||
self.rs_cfg_unit_l = TextBox{parent=rs_c_4,x=25,y=7,width=7,text="Unit ID"}
|
||||
self.rs_cfg_unit = NumberField{parent=rs_c_4,x=33,y=7,width=10,max_chars=2,min=1,max=4,fg_bg=bw_fg_bg}
|
||||
@@ -384,11 +383,11 @@ function redstone.create(tool_ctl, main_pane, cfg_sys, rs_cfg, style)
|
||||
if bundled then self.rs_cfg_color.enable() else self.rs_cfg_color.disable() end
|
||||
end
|
||||
|
||||
self.rs_cfg_shortcut = TextBox{parent=rs_c_4,x=1,y=9,height=4,text="This shortcut will add entries for each of the 4 waste outputs. If you select bundled, 4 colors will be assigned to the selected side. Otherwise, 4 default sides will be used."}
|
||||
self.rs_cfg_shortcut = TextBox{parent=rs_c_4,y=9,height=4,text="This shortcut will add entries for each of the 4 waste outputs. If you select bundled, 4 colors will be assigned to the selected side. Otherwise, 4 default sides will be used."}
|
||||
self.rs_cfg_shortcut.hide(true)
|
||||
|
||||
self.rs_cfg_bundled = Checkbox{parent=rs_c_4,x=1,y=7,label="Is Bundled?",default=false,box_fg_bg=cpair(colors.red,colors.black),callback=set_bundled,disable_fg_bg=g_lg_fg_bg}
|
||||
self.rs_cfg_color = Radio2D{parent=rs_c_4,x=1,y=9,rows=4,columns=4,default=1,options=color_options,radio_colors=cpair(colors.lightGray,colors.black),color_map=color_options_map,disable_color=colors.gray,disable_fg_bg=g_lg_fg_bg}
|
||||
self.rs_cfg_bundled = Checkbox{parent=rs_c_4,y=7,label="Is Bundled?",default=false,box_fg_bg=cpair(colors.red,colors.black),callback=set_bundled,disable_fg_bg=g_lg_fg_bg}
|
||||
self.rs_cfg_color = Radio2D{parent=rs_c_4,y=9,rows=4,columns=4,default=1,options=color_options,radio_colors=cpair(colors.lightGray,colors.black),color_map=color_options_map,disable_color=colors.gray,disable_fg_bg=g_lg_fg_bg}
|
||||
self.rs_cfg_color.disable()
|
||||
|
||||
local rs_err = TextBox{parent=rs_c_4,x=8,y=14,width=30,text="Unit ID invalid.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
@@ -461,35 +460,35 @@ function redstone.create(tool_ctl, main_pane, cfg_sys, rs_cfg, style)
|
||||
else rs_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=rs_c_4,x=1,y=14,text="\x1b Back",callback=back_from_rs_opts,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=rs_c_4,y=14,text="\x1b Back",callback=back_from_rs_opts,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
self.rs_cfg_advanced = PushButton{parent=rs_c_4,x=30,y=14,min_width=10,text="Advanced",callback=function()rs_pane.set_value(9)end,fg_bg=cpair(colors.black,colors.yellow),active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
PushButton{parent=rs_c_4,x=41,y=14,min_width=9,text="Confirm",callback=save_rs_entry,fg_bg=cpair(colors.black,colors.blue),active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
|
||||
TextBox{parent=rs_c_5,x=1,y=1,text="Settings saved!"}
|
||||
PushButton{parent=rs_c_5,x=1,y=14,text="\x1b Back",callback=function()rs_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
TextBox{parent=rs_c_5,y=1,text="Settings saved!"}
|
||||
PushButton{parent=rs_c_5,y=14,text="\x1b Back",callback=function()rs_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=rs_c_5,x=44,y=14,min_width=6,text="Home",callback=function()tool_ctl.go_home()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=rs_c_6,x=1,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=rs_c_6,x=1,y=14,text="\x1b Back",callback=function()rs_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
TextBox{parent=rs_c_6,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=rs_c_6,y=14,text="\x1b Back",callback=function()rs_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=rs_c_6,x=44,y=14,min_width=6,text="Home",callback=function()tool_ctl.go_home()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=rs_c_7,x=1,y=1,height=6,text="You already configured this input for this facility/unit assignment. There can only be one entry for each input per each unit or the facility (for facility inputs).\n\nPlease select a different port."}
|
||||
PushButton{parent=rs_c_7,x=1,y=14,text="\x1b Back",callback=function()rs_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
TextBox{parent=rs_c_7,y=1,height=6,text="You already configured this input for this facility/unit assignment. There can only be one entry for each input per each unit or the facility (for facility inputs).\n\nPlease select a different port."}
|
||||
PushButton{parent=rs_c_7,y=14,text="\x1b Back",callback=function()rs_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=rs_c_8,x=1,y=1,height=4,text="(Normal) Digital Input: On if there is a redstone signal, off otherwise\nInverted Digital Input: On without a redstone signal, off otherwise"}
|
||||
TextBox{parent=rs_c_8,x=1,y=6,height=4,text="(Normal) Digital Output: Redstone signal to 'turn it on', none to 'turn it off'\nInverted Digital Output: No redstone signal to 'turn it on', redstone signal to 'turn it off'"}
|
||||
TextBox{parent=rs_c_8,x=1,y=11,height=2,text="Analog Input: 0-15 redstone power level input\nAnalog Output: 0-15 scaled redstone power level output"}
|
||||
PushButton{parent=rs_c_8,x=1,y=14,text="\x1b Back",callback=function()rs_pane.set_value(4)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
TextBox{parent=rs_c_8,y=1,height=4,text="(Normal) Digital Input: On if there is a redstone signal, off otherwise\nInverted Digital Input: On without a redstone signal, off otherwise"}
|
||||
TextBox{parent=rs_c_8,y=6,height=4,text="(Normal) Digital Output: Redstone signal to 'turn it on', none to 'turn it off'\nInverted Digital Output: No redstone signal to 'turn it on', redstone signal to 'turn it off'"}
|
||||
TextBox{parent=rs_c_8,y=11,height=2,text="Analog Input: 0-15 redstone power level input\nAnalog Output: 0-15 scaled redstone power level output"}
|
||||
PushButton{parent=rs_c_8,y=14,text="\x1b Back",callback=function()rs_pane.set_value(4)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=rs_c_9,x=1,y=1,height=5,text="Advanced Options"}
|
||||
self.rs_cfg_inverted = Checkbox{parent=rs_c_9,x=1,y=3,label="Invert",default=false,box_fg_bg=cpair(colors.red,colors.black),disable_fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=rs_c_9,y=1,height=5,text="Advanced Options"}
|
||||
self.rs_cfg_inverted = Checkbox{parent=rs_c_9,y=3,label="Invert",default=false,box_fg_bg=cpair(colors.red,colors.black),disable_fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=rs_c_9,x=3,y=4,height=4,text="Digital I/O is already inverted (or not) based on intended use. If you have a non-standard setup, you can use this option to avoid needing a redstone inverter.",fg_bg=cpair(colors.gray,colors.lightGray)}
|
||||
PushButton{parent=rs_c_9,x=1,y=14,text="\x1b Back",callback=function()rs_pane.set_value(4)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=rs_c_9,y=14,text="\x1b Back",callback=function()rs_pane.set_value(4)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=rs_c_10,x=1,y=1,height=10,text="Make sure your relay is either touching the RTU gateway or connected via wired modems. There should be a wired modem on a side of the RTU gateway then one on the device, connected by a cable. The modem on the device needs to be right clicked to connect it (which will turn its border red), at which point the peripheral name will be shown in the chat."}
|
||||
PushButton{parent=rs_c_10,x=1,y=14,text="\x1b Back",callback=function()rs_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
TextBox{parent=rs_c_10,y=1,height=10,text="Make sure your relay is either touching the RTU gateway or connected via wired modems. There should be a wired modem on a side of the RTU gateway then one on the device, connected by a cable. The modem on the device needs to be right clicked to connect it (which will turn its border red), at which point the peripheral name will be shown in the chat."}
|
||||
PushButton{parent=rs_c_10,y=14,text="\x1b Back",callback=function()rs_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
|
||||
@@ -571,7 +570,7 @@ function redstone.create(tool_ctl, main_pane, cfg_sys, rs_cfg, style)
|
||||
if def.color ~= nil then conn = def.side .. "/" .. rsio.color_name(def.color) end
|
||||
|
||||
local entry = Div{parent=rs_list,height=1}
|
||||
TextBox{parent=entry,x=1,y=1,width=1,text=io_dir,fg_bg=cpair(tri(def.invert,colors.orange,io_c),colors.white)}
|
||||
TextBox{parent=entry,y=1,width=1,text=io_dir,fg_bg=cpair(tri(def.invert,colors.orange,io_c),colors.white)}
|
||||
TextBox{parent=entry,x=2,y=1,width=14,text=name}
|
||||
TextBox{parent=entry,x=16,y=1,width=string.len(conn),text=conn,fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=entry,x=33,y=1,width=1,text=unit,fg_bg=cpair(colors.gray,colors.white)}
|
||||
|
||||
@@ -64,14 +64,14 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
|
||||
local spkr_c = Div{parent=spkr_cfg,x=2,y=4,width=49}
|
||||
|
||||
TextBox{parent=spkr_cfg,x=1,y=2,text=" Speaker Configuration",fg_bg=cpair(colors.black,colors.cyan)}
|
||||
TextBox{parent=spkr_cfg,y=2,text=" Speaker Configuration",fg_bg=cpair(colors.black,colors.cyan)}
|
||||
|
||||
TextBox{parent=spkr_c,x=1,y=1,height=2,text="Speakers can be connected to this RTU gateway without RTU unit configuration entries."}
|
||||
TextBox{parent=spkr_c,x=1,y=4,height=3,text="You can change the speaker audio volume from the default. The range is 0.0 to 3.0, where 1.0 is standard volume."}
|
||||
TextBox{parent=spkr_c,y=1,height=2,text="Speakers can be connected to this RTU gateway without RTU unit configuration entries."}
|
||||
TextBox{parent=spkr_c,y=4,height=3,text="You can change the speaker audio volume from the default. The range is 0.0 to 3.0, where 1.0 is standard volume."}
|
||||
|
||||
local s_vol = NumberField{parent=spkr_c,x=1,y=8,width=9,max_chars=7,allow_decimal=true,default=ini_cfg.SpeakerVolume,min=0,max=3,fg_bg=bw_fg_bg}
|
||||
local s_vol = NumberField{parent=spkr_c,y=8,width=9,max_chars=7,allow_decimal=true,default=ini_cfg.SpeakerVolume,min=0,max=3,fg_bg=bw_fg_bg}
|
||||
|
||||
TextBox{parent=spkr_c,x=1,y=10,height=3,text="Note: alarm sine waves are at half scale so that multiple will be required to reach full scale.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=spkr_c,y=10,height=3,text="Note: alarm sine waves are at half scale so that multiple will be required to reach full scale.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local s_vol_err = TextBox{parent=spkr_c,x=8,y=14,width=35,text="Please set a volume.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
|
||||
@@ -84,7 +84,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
else s_vol_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=spkr_c,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=spkr_c,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=spkr_c,x=44,y=14,text="Next \x1a",callback=submit_vol,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -96,11 +96,11 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
local net_c_3 = Div{parent=net_cfg,x=2,y=4,width=49}
|
||||
local net_c_4 = Div{parent=net_cfg,x=2,y=4,width=49}
|
||||
|
||||
local net_pane = MultiPane{parent=net_cfg,x=1,y=4,panes={net_c_1,net_c_2,net_c_3,net_c_4}}
|
||||
local net_pane = MultiPane{parent=net_cfg,y=4,panes={net_c_1,net_c_2,net_c_3,net_c_4}}
|
||||
|
||||
TextBox{parent=net_cfg,x=1,y=2,text=" Network Configuration",fg_bg=cpair(colors.black,colors.lightBlue)}
|
||||
TextBox{parent=net_cfg,y=2,text=" Network Configuration",fg_bg=cpair(colors.black,colors.lightBlue)}
|
||||
|
||||
TextBox{parent=net_c_1,x=1,y=1,text="Please select the network interface(s)."}
|
||||
TextBox{parent=net_c_1,y=1,text="Please select the network interface(s)."}
|
||||
TextBox{parent=net_c_1,x=41,y=1,text="new!",fg_bg=cpair(colors.red,colors._INHERIT)} ---@todo remove NEW tag on next revision
|
||||
|
||||
local function en_dis_pref()
|
||||
@@ -117,12 +117,12 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
tool_ctl.gen_modem_list()
|
||||
end
|
||||
|
||||
self.wireless = Checkbox{parent=net_c_1,x=1,y=3,label="Wireless/Ender Modem",default=ini_cfg.WirelessModem,box_fg_bg=cpair(colors.lightBlue,colors.black),callback=en_dis_pref}
|
||||
self.wireless = Checkbox{parent=net_c_1,y=3,label="Wireless/Ender Modem",default=ini_cfg.WirelessModem,box_fg_bg=cpair(colors.lightBlue,colors.black),callback=en_dis_pref}
|
||||
self.wl_pref = Checkbox{parent=net_c_1,x=30,y=3,label="Prefer Wireless",default=ini_cfg.PreferWireless,box_fg_bg=cpair(colors.lightBlue,colors.black),disable_fg_bg=g_lg_fg_bg}
|
||||
self.wired = Checkbox{parent=net_c_1,x=1,y=5,label="Wired Modem",default=ini_cfg.WiredModem~=false,box_fg_bg=cpair(colors.lightBlue,colors.black),callback=on_wired_change}
|
||||
self.wired = Checkbox{parent=net_c_1,y=5,label="Wired Modem",default=ini_cfg.WiredModem~=false,box_fg_bg=cpair(colors.lightBlue,colors.black),callback=on_wired_change}
|
||||
TextBox{parent=net_c_1,x=3,y=6,text="this one MUST ONLY connect to SCADA computers",fg_bg=cpair(colors.red,colors._INHERIT)}
|
||||
TextBox{parent=net_c_1,x=3,y=7,text="connecting it to peripherals will cause issues",fg_bg=g_lg_fg_bg}
|
||||
local modem_list = ListBox{parent=net_c_1,x=1,y=8,height=5,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
local modem_list = ListBox{parent=net_c_1,y=8,height=5,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
local modem_err = TextBox{parent=net_c_1,x=8,y=14,width=35,text="",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
|
||||
@@ -162,17 +162,17 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_1,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_1,y=14,text="\x1b Back",callback=function()main_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_1,x=44,y=14,text="Next \x1a",callback=submit_interfaces,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_2,x=1,y=1,text="Please set the network channels below."}
|
||||
TextBox{parent=net_c_2,x=1,y=3,height=4,text="Each of the 5 uniquely named channels, including the 2 below, must be the same for each device in this SCADA network. For multiplayer servers, it is recommended to not use the default channels.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_2,y=1,text="Please set the network channels below."}
|
||||
TextBox{parent=net_c_2,y=3,height=4,text="Each of the 5 uniquely named channels, including the 2 below, must be the same for each device in this SCADA network. For multiplayer servers, it is recommended to not use the default channels.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_2,x=1,y=8,text="Supervisor Channel"}
|
||||
local svr_chan = NumberField{parent=net_c_2,x=1,y=9,width=7,default=ini_cfg.SVR_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_2,y=8,text="Supervisor Channel"}
|
||||
local svr_chan = NumberField{parent=net_c_2,y=9,width=7,default=ini_cfg.SVR_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_2,x=9,y=9,height=4,text="[SVR_CHANNEL]",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_2,x=1,y=11,text="RTU Channel"}
|
||||
local rtu_chan = NumberField{parent=net_c_2,x=1,y=12,width=7,default=ini_cfg.RTU_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_2,y=11,text="RTU Channel"}
|
||||
local rtu_chan = NumberField{parent=net_c_2,y=12,width=7,default=ini_cfg.RTU_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_2,x=9,y=12,height=4,text="[RTU_CHANNEL]",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local chan_err = TextBox{parent=net_c_2,x=8,y=14,width=35,text="",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
@@ -194,17 +194,17 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_2,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_2,y=14,text="\x1b Back",callback=function()net_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_2,x=44,y=14,text="Next \x1a",callback=submit_channels,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_3,x=1,y=1,text="Connection Timeout"}
|
||||
local timeout = NumberField{parent=net_c_3,x=1,y=2,width=7,default=ini_cfg.ConnTimeout,min=2,max=25,max_chars=6,max_frac_digits=2,allow_decimal=true,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_3,y=1,text="Connection Timeout"}
|
||||
local timeout = NumberField{parent=net_c_3,y=2,width=7,default=ini_cfg.ConnTimeout,min=2,max=25,max_chars=6,max_frac_digits=2,allow_decimal=true,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_3,x=9,y=2,height=2,text="seconds (default 5)",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_3,x=1,y=3,height=4,text="You generally do not want or need to modify this. On slow servers, you can increase this to make the system wait longer before assuming a disconnection.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_3,y=3,height=4,text="You generally do not want or need to modify this. On slow servers, you can increase this to make the system wait longer before assuming a disconnection.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_3,x=1,y=8,text="Trusted Range (Wireless Only)"}
|
||||
self.range = NumberField{parent=net_c_3,x=1,y=9,width=10,default=ini_cfg.TrustedRange,min=0,max_chars=20,allow_decimal=true,fg_bg=bw_fg_bg,dis_fg_bg=cpair(colors.lightGray,colors.white)}
|
||||
TextBox{parent=net_c_3,x=1,y=10,height=4,text="Setting this to a value larger than 0 prevents wireless connections with devices that many meters (blocks) away in any direction.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_3,y=8,text="Trusted Range (Wireless Only)"}
|
||||
self.range = NumberField{parent=net_c_3,y=9,width=10,default=ini_cfg.TrustedRange,min=0,max_chars=20,allow_decimal=true,fg_bg=bw_fg_bg,dis_fg_bg=cpair(colors.lightGray,colors.white)}
|
||||
TextBox{parent=net_c_3,y=10,height=4,text="Setting this to a value larger than 0 prevents wireless connections with devices that many meters (blocks) away in any direction.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local n3_err = TextBox{parent=net_c_3,x=8,y=14,width=35,text="",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
|
||||
@@ -233,14 +233,14 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_3,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_3,y=14,text="\x1b Back",callback=function()net_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_3,x=44,y=14,text="Next \x1a",callback=submit_ct_tr,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_4,x=1,y=1,height=2,text="Optionally, set the facility authentication key below. Do NOT use one of your passwords."}
|
||||
TextBox{parent=net_c_4,x=1,y=4,height=6,text="This enables verifying that messages are authentic, so it is intended for wireless security on multiplayer servers. All devices on the same wireless network MUST use the same key if any device has a key. This does result in some extra computation (can slow things down).",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_4,y=1,height=2,text="Optionally, set the facility authentication key below. Do NOT use one of your passwords."}
|
||||
TextBox{parent=net_c_4,y=4,height=6,text="This enables verifying that messages are authentic, so it is intended for wireless security on multiplayer servers. All devices on the same wireless network MUST use the same key if any device has a key. This does result in some extra computation (can slow things down).",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_4,x=1,y=11,text="Auth Key (Wireless Only, Not Used for Wired)"}
|
||||
local key, _ = TextField{parent=net_c_4,x=1,y=12,max_len=64,value=ini_cfg.AuthKey,width=32,height=1,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_4,y=11,text="Auth Key (Wireless Only, Not Used for Wired)"}
|
||||
local key, _ = TextField{parent=net_c_4,y=12,max_len=64,value=ini_cfg.AuthKey,width=32,height=1,fg_bg=bw_fg_bg}
|
||||
|
||||
local function censor_key(enable) key.censor(tri(enable, "*", nil)) end
|
||||
|
||||
@@ -260,7 +260,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
else key_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_4,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_4,y=14,text="\x1b Back",callback=function()net_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_4,x=44,y=14,text="Next \x1a",callback=submit_auth,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -269,17 +269,17 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
|
||||
local log_c_1 = Div{parent=log_cfg,x=2,y=4,width=49}
|
||||
|
||||
TextBox{parent=log_cfg,x=1,y=2,text=" Logging Configuration",fg_bg=cpair(colors.black,colors.pink)}
|
||||
TextBox{parent=log_cfg,y=2,text=" Logging Configuration",fg_bg=cpair(colors.black,colors.pink)}
|
||||
|
||||
TextBox{parent=log_c_1,x=1,y=1,text="Please configure logging below."}
|
||||
TextBox{parent=log_c_1,y=1,text="Please configure logging below."}
|
||||
|
||||
TextBox{parent=log_c_1,x=1,y=3,text="Log File Mode"}
|
||||
local mode = RadioButton{parent=log_c_1,x=1,y=4,default=ini_cfg.LogMode+1,options={"Append on Startup","Replace on Startup"},radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.pink}
|
||||
TextBox{parent=log_c_1,y=3,text="Log File Mode"}
|
||||
local mode = RadioButton{parent=log_c_1,y=4,default=ini_cfg.LogMode+1,options={"Append on Startup","Replace on Startup"},radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.pink}
|
||||
|
||||
TextBox{parent=log_c_1,x=1,y=7,text="Log File Path"}
|
||||
local path = TextField{parent=log_c_1,x=1,y=8,width=49,height=1,value=ini_cfg.LogPath,max_len=128,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=log_c_1,y=7,text="Log File Path"}
|
||||
local path = TextField{parent=log_c_1,y=8,width=49,height=1,value=ini_cfg.LogPath,max_len=128,fg_bg=bw_fg_bg}
|
||||
|
||||
local en_dbg = Checkbox{parent=log_c_1,x=1,y=10,default=ini_cfg.LogDebug,label="Enable Logging Debug Messages",box_fg_bg=cpair(colors.pink,colors.black)}
|
||||
local en_dbg = Checkbox{parent=log_c_1,y=10,default=ini_cfg.LogDebug,label="Enable Logging Debug Messages",box_fg_bg=cpair(colors.pink,colors.black)}
|
||||
TextBox{parent=log_c_1,x=3,y=11,height=2,text="This results in much larger log files. It is best to only use this when there is a problem.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local path_err = TextBox{parent=log_c_1,x=8,y=14,width=35,text="Please provide a log file path.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
@@ -296,7 +296,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
else path_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=log_c_1,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=log_c_1,y=14,text="\x1b Back",callback=function()main_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=log_c_1,x=44,y=14,text="Next \x1a",callback=submit_log,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -308,17 +308,17 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
local clr_c_3 = Div{parent=clr_cfg,x=2,y=4,width=49}
|
||||
local clr_c_4 = Div{parent=clr_cfg,x=2,y=4,width=49}
|
||||
|
||||
local clr_pane = MultiPane{parent=clr_cfg,x=1,y=4,panes={clr_c_1,clr_c_2,clr_c_3,clr_c_4}}
|
||||
local clr_pane = MultiPane{parent=clr_cfg,y=4,panes={clr_c_1,clr_c_2,clr_c_3,clr_c_4}}
|
||||
|
||||
TextBox{parent=clr_cfg,x=1,y=2,text=" Color Configuration",fg_bg=cpair(colors.black,colors.magenta)}
|
||||
TextBox{parent=clr_cfg,y=2,text=" Color Configuration",fg_bg=cpair(colors.black,colors.magenta)}
|
||||
|
||||
TextBox{parent=clr_c_1,x=1,y=1,height=2,text="Here you can select the color theme for the front panel."}
|
||||
TextBox{parent=clr_c_1,x=1,y=4,height=2,text="Click 'Accessibility' below to access colorblind assistive options.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=clr_c_1,y=1,height=2,text="Here you can select the color theme for the front panel."}
|
||||
TextBox{parent=clr_c_1,y=4,height=2,text="Click 'Accessibility' below to access colorblind assistive options.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=clr_c_1,x=1,y=7,text="Front Panel Theme"}
|
||||
local fp_theme = RadioButton{parent=clr_c_1,x=1,y=8,default=ini_cfg.FrontPanelTheme,options=themes.FP_THEME_NAMES,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||
TextBox{parent=clr_c_1,y=7,text="Front Panel Theme"}
|
||||
local fp_theme = RadioButton{parent=clr_c_1,y=8,default=ini_cfg.FrontPanelTheme,options=themes.FP_THEME_NAMES,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||
|
||||
TextBox{parent=clr_c_2,x=1,y=1,height=6,text="This system uses color heavily to distinguish ok and not, with some indicators using many colors. By selecting a mode below, indicators will change as shown. For non-standard modes, indicators with more than two colors will be split up."}
|
||||
TextBox{parent=clr_c_2,y=1,height=6,text="This system uses color heavily to distinguish ok and not, with some indicators using many colors. By selecting a mode below, indicators will change as shown. For non-standard modes, indicators with more than two colors will be split up."}
|
||||
|
||||
TextBox{parent=clr_c_2,x=21,y=7,text="Preview"}
|
||||
local _ = IndLight{parent=clr_c_2,x=21,y=8,label="Good",colors=cpair(colors.black,colors.green)}
|
||||
@@ -347,8 +347,8 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
end
|
||||
end
|
||||
|
||||
TextBox{parent=clr_c_2,x=1,y=7,width=10,text="Color Mode"}
|
||||
local c_mode = RadioButton{parent=clr_c_2,x=1,y=8,default=ini_cfg.ColorMode,options=themes.COLOR_MODE_NAMES,callback=recolor,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||
TextBox{parent=clr_c_2,y=7,width=10,text="Color Mode"}
|
||||
local c_mode = RadioButton{parent=clr_c_2,y=8,default=ini_cfg.ColorMode,options=themes.COLOR_MODE_NAMES,callback=recolor,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||
|
||||
TextBox{parent=clr_c_2,x=21,y=13,height=2,width=18,text="Note: exact color varies by theme.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
@@ -390,19 +390,19 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=clr_c_1,x=1,y=14,text="\x1b Back",callback=back_from_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=clr_c_1,y=14,text="\x1b Back",callback=back_from_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=clr_c_1,x=8,y=14,min_width=15,text="Accessibility",callback=show_access,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
tool_ctl.color_next = PushButton{parent=clr_c_1,x=44,y=14,text="Next \x1a",callback=submit_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
tool_ctl.color_apply = PushButton{parent=clr_c_1,x=43,y=14,min_width=7,text="Apply",callback=submit_colors,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
tool_ctl.color_apply.hide(true)
|
||||
|
||||
TextBox{parent=clr_c_3,x=1,y=1,text="Settings saved!"}
|
||||
PushButton{parent=clr_c_3,x=1,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
TextBox{parent=clr_c_3,y=1,text="Settings saved!"}
|
||||
PushButton{parent=clr_c_3,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
PushButton{parent=clr_c_3,x=44,y=14,min_width=6,text="Home",callback=function()tool_ctl.go_home()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=clr_c_4,x=1,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=clr_c_4,x=1,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
TextBox{parent=clr_c_4,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=clr_c_4,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
PushButton{parent=clr_c_4,x=44,y=14,min_width=6,text="Home",callback=function()tool_ctl.go_home()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -417,11 +417,11 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
local sum_c_6 = Div{parent=summary,x=2,y=4,width=49}
|
||||
local sum_c_7 = Div{parent=summary,x=2,y=4,width=49}
|
||||
|
||||
local sum_pane = MultiPane{parent=summary,x=1,y=4,panes={sum_c_1,sum_c_2,sum_c_3,sum_c_4,sum_c_5,sum_c_6,sum_c_7}}
|
||||
local sum_pane = MultiPane{parent=summary,y=4,panes={sum_c_1,sum_c_2,sum_c_3,sum_c_4,sum_c_5,sum_c_6,sum_c_7}}
|
||||
|
||||
TextBox{parent=summary,x=1,y=2,text=" Summary",fg_bg=cpair(colors.black,colors.green)}
|
||||
TextBox{parent=summary,y=2,text=" Summary",fg_bg=cpair(colors.black,colors.green)}
|
||||
|
||||
local setting_list = ListBox{parent=sum_c_1,x=1,y=1,height=12,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
local setting_list = ListBox{parent=sum_c_1,y=1,height=12,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
local function back_from_settings()
|
||||
if tool_ctl.viewing_config or self.importing_legacy then
|
||||
@@ -492,22 +492,22 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
else sum_pane.set_value(6) end
|
||||
end
|
||||
|
||||
PushButton{parent=sum_c_1,x=1,y=14,text="\x1b Back",callback=back_from_settings,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_1,y=14,text="\x1b Back",callback=back_from_settings,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
self.show_key_btn = PushButton{parent=sum_c_1,x=8,y=14,min_width=17,text="Unhide Auth Key",callback=function()self.show_auth_key()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
tool_ctl.settings_apply = PushButton{parent=sum_c_1,x=43,y=14,min_width=7,text="Apply",callback=function()save_and_continue(true)end,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg}
|
||||
tool_ctl.settings_confirm = PushButton{parent=sum_c_1,x=41,y=14,min_width=9,text="Confirm",callback=function()sum_pane.set_value(2)end,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg}
|
||||
tool_ctl.settings_confirm.hide()
|
||||
|
||||
TextBox{parent=sum_c_2,x=1,y=1,text="The following peripherals will be imported:"}
|
||||
local peri_import_list = ListBox{parent=sum_c_2,x=1,y=3,height=10,width=49,scroll_height=1000,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
TextBox{parent=sum_c_2,y=1,text="The following peripherals will be imported:"}
|
||||
local peri_import_list = ListBox{parent=sum_c_2,y=3,height=10,width=49,scroll_height=1000,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
PushButton{parent=sum_c_2,x=1,y=14,text="\x1b Back",callback=function()sum_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_2,y=14,text="\x1b Back",callback=function()sum_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_2,x=41,y=14,min_width=9,text="Confirm",callback=function()sum_pane.set_value(3)end,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=sum_c_3,x=1,y=1,text="The following redstone entries will be imported:"}
|
||||
local rs_import_list = ListBox{parent=sum_c_3,x=1,y=3,height=10,width=49,scroll_height=1000,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
TextBox{parent=sum_c_3,y=1,text="The following redstone entries will be imported:"}
|
||||
local rs_import_list = ListBox{parent=sum_c_3,y=3,height=10,width=49,scroll_height=1000,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
PushButton{parent=sum_c_3,x=1,y=14,text="\x1b Back",callback=function()sum_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_3,y=14,text="\x1b Back",callback=function()sum_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_3,x=43,y=14,min_width=7,text="Apply",callback=save_and_continue,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
local function jump_peri_conns()
|
||||
@@ -520,30 +520,30 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
show_rs_conns()
|
||||
end
|
||||
|
||||
TextBox{parent=sum_c_4,x=1,y=1,text="Settings saved!"}
|
||||
TextBox{parent=sum_c_4,x=1,y=3,height=4,text="Remember to configure any peripherals or redstone that you have connected to this RTU gateway if you have not already done so, or if you have added, removed, or modified any of them."}
|
||||
PushButton{parent=sum_c_4,x=1,y=8,min_width=24,text="Peripheral Connections",callback=jump_peri_conns,fg_bg=cpair(colors.black,colors.yellow),active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_4,x=1,y=10,min_width=22,text="Redstone Connections",callback=jump_rs_conns,fg_bg=cpair(colors.black,colors.yellow),active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_4,x=1,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
TextBox{parent=sum_c_4,y=1,text="Settings saved!"}
|
||||
TextBox{parent=sum_c_4,y=3,height=4,text="Remember to configure any peripherals or redstone that you have connected to this RTU gateway if you have not already done so, or if you have added, removed, or modified any of them."}
|
||||
PushButton{parent=sum_c_4,y=8,min_width=24,text="Peripheral Connections",callback=jump_peri_conns,fg_bg=cpair(colors.black,colors.yellow),active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_4,y=10,min_width=22,text="Redstone Connections",callback=jump_rs_conns,fg_bg=cpair(colors.black,colors.yellow),active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_4,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
PushButton{parent=sum_c_4,x=44,y=14,min_width=6,text="Home",callback=function()tool_ctl.go_home()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=sum_c_5,x=1,y=1,height=2,text="The old config.lua file will now be deleted, then the configurator will exit."}
|
||||
TextBox{parent=sum_c_5,y=1,height=2,text="The old config.lua file will now be deleted, then the configurator will exit."}
|
||||
|
||||
local function delete_legacy()
|
||||
fs.delete("/rtu/config.lua")
|
||||
exit()
|
||||
end
|
||||
|
||||
PushButton{parent=sum_c_5,x=1,y=14,min_width=8,text="Cancel",callback=function()tool_ctl.go_home()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_5,y=14,min_width=8,text="Cancel",callback=function()tool_ctl.go_home()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_5,x=44,y=14,min_width=6,text="OK",callback=delete_legacy,fg_bg=cpair(colors.black,colors.green),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
|
||||
TextBox{parent=sum_c_6,x=1,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=sum_c_6,x=1,y=14,min_width=6,text="Home",callback=function()tool_ctl.go_home()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
TextBox{parent=sum_c_6,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=sum_c_6,y=14,min_width=6,text="Home",callback=function()tool_ctl.go_home()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_6,x=44,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
|
||||
TextBox{parent=sum_c_7,x=1,y=1,height=8,text="Warning!\n\nSome of the devices in your old config file aren't currently connected. If the device isn't connected, the options can't be properly validated. Please either connect your devices and try again or complete the import without validation on those entry's settings."}
|
||||
TextBox{parent=sum_c_7,x=1,y=10,height=3,text="Afterwards, either (a) edit then save entries for currently disconnected devices to properly configure or (b) delete those entries."}
|
||||
PushButton{parent=sum_c_7,x=1,y=14,text="\x1b Back",callback=function()tool_ctl.go_home()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
TextBox{parent=sum_c_7,y=1,height=8,text="Warning!\n\nSome of the devices in your old config file aren't currently connected. If the device isn't connected, the options can't be properly validated. Please either connect your devices and try again or complete the import without validation on those entry's settings."}
|
||||
TextBox{parent=sum_c_7,y=10,height=3,text="Afterwards, either (a) edit then save entries for currently disconnected devices to properly configure or (b) delete those entries."}
|
||||
PushButton{parent=sum_c_7,y=14,text="\x1b Back",callback=function()tool_ctl.go_home()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_7,x=41,y=14,min_width=9,text="Confirm",callback=function()sum_pane.set_value(1)end,fg_bg=cpair(colors.black,colors.orange),active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -639,9 +639,9 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
end
|
||||
|
||||
local line = Div{parent=peri_import_list,height=3}
|
||||
TextBox{parent=line,x=1,y=1,text="@ "..def.name,fg_bg=cpair(colors.black,colors.white)}
|
||||
TextBox{parent=line,x=1,y=2,text=status,fg_bg=cpair(color,colors.white)}
|
||||
TextBox{parent=line,x=1,y=3,text=desc,fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=line,y=1,text="@ "..def.name,fg_bg=cpair(colors.black,colors.white)}
|
||||
TextBox{parent=line,y=2,text=status,fg_bg=cpair(color,colors.white)}
|
||||
TextBox{parent=line,y=3,text=desc,fg_bg=cpair(colors.gray,colors.white)}
|
||||
end
|
||||
|
||||
rs_import_list.remove_all()
|
||||
@@ -660,7 +660,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
if def.color ~= nil then conn = def.side .. "/" .. rsio.color_name(def.color) end
|
||||
|
||||
local line = Div{parent=rs_import_list,height=1}
|
||||
TextBox{parent=line,x=1,y=1,width=1,text=io_dir,fg_bg=cpair(colors.lightGray,colors.white)}
|
||||
TextBox{parent=line,y=1,width=1,text=io_dir,fg_bg=cpair(colors.lightGray,colors.white)}
|
||||
TextBox{parent=line,x=2,y=1,width=14,text=name}
|
||||
TextBox{parent=line,x=18,y=1,width=string.len(conn),text=conn,fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=line,x=40,y=1,text=unit,fg_bg=cpair(colors.gray,colors.white)}
|
||||
@@ -737,7 +737,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
|
||||
local textbox
|
||||
if height > 1 then
|
||||
textbox = TextBox{parent=line,x=1,y=2,text=val,height=height-1}
|
||||
textbox = TextBox{parent=line,y=2,text=val,height=height-1}
|
||||
else
|
||||
textbox = TextBox{parent=line,x=label_w+1,y=1,text=val,alignment=RIGHT}
|
||||
end
|
||||
@@ -766,19 +766,19 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
end
|
||||
|
||||
if missing.tmp and tmp_cfg.WiredModem then
|
||||
local line = Div{parent=modem_list,x=1,y=1,height=1}
|
||||
local line = Div{parent=modem_list,y=1,height=1}
|
||||
|
||||
TextBox{parent=line,x=1,y=1,width=4,text="Used",fg_bg=cpair(tri(enable,colors.blue,colors.gray),colors.white)}
|
||||
TextBox{parent=line,y=1,width=4,text="Used",fg_bg=cpair(tri(enable,colors.blue,colors.gray),colors.white)}
|
||||
PushButton{parent=line,x=6,y=1,min_width=8,height=1,text="SELECT",callback=function()end,fg_bg=cpair(colors.black,colors.lightBlue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=g_lg_fg_bg}.disable()
|
||||
TextBox{parent=line,x=15,y=1,text="[missing]",fg_bg=cpair(colors.red,colors.white)}
|
||||
TextBox{parent=line,x=25,y=1,text=tmp_cfg.WiredModem}
|
||||
end
|
||||
|
||||
if missing.ini and ini_cfg.WiredModem and (tmp_cfg.WiredModem ~= ini_cfg.WiredModem) then
|
||||
local line = Div{parent=modem_list,x=1,y=1,height=1}
|
||||
local line = Div{parent=modem_list,y=1,height=1}
|
||||
local used = tmp_cfg.WiredModem == ini_cfg.WiredModem
|
||||
|
||||
TextBox{parent=line,x=1,y=1,width=4,text=tri(used,"Used","----"),fg_bg=cpair(tri(used and enable,colors.blue,colors.gray),colors.white)}
|
||||
TextBox{parent=line,y=1,width=4,text=tri(used,"Used","----"),fg_bg=cpair(tri(used and enable,colors.blue,colors.gray),colors.white)}
|
||||
local select_btn = PushButton{parent=line,x=6,y=1,min_width=8,height=1,text="SELECT",callback=function()select(ini_cfg.WiredModem)end,fg_bg=cpair(colors.black,colors.lightBlue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=line,x=15,y=1,text="[missing]",fg_bg=cpair(colors.red,colors.white)}
|
||||
TextBox{parent=line,x=25,y=1,text=ini_cfg.WiredModem}
|
||||
@@ -788,10 +788,10 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
|
||||
|
||||
-- list wired modems
|
||||
for iface, _ in pairs(modems) do
|
||||
local line = Div{parent=modem_list,x=1,y=1,height=1}
|
||||
local line = Div{parent=modem_list,y=1,height=1}
|
||||
local used = tmp_cfg.WiredModem == iface
|
||||
|
||||
TextBox{parent=line,x=1,y=1,width=4,text=tri(used,"Used","----"),fg_bg=cpair(tri(used and enable,colors.blue,colors.gray),colors.white)}
|
||||
TextBox{parent=line,y=1,width=4,text=tri(used,"Used","----"),fg_bg=cpair(tri(used and enable,colors.blue,colors.gray),colors.white)}
|
||||
local select_btn = PushButton{parent=line,x=6,y=1,min_width=8,height=1,text="SELECT",callback=function()select(iface)end,fg_bg=cpair(colors.black,colors.lightBlue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=line,x=15,y=1,text=iface}
|
||||
|
||||
|
||||
@@ -173,20 +173,20 @@ local function config_view(display)
|
||||
|
||||
TextBox{parent=display,y=1,text="RTU Gateway Configurator",alignment=CENTER,fg_bg=style.header}
|
||||
|
||||
local root_pane_div = Div{parent=display,x=1,y=2}
|
||||
local root_pane_div = Div{parent=display,y=2}
|
||||
|
||||
local main_page = Div{parent=root_pane_div,x=1,y=1}
|
||||
local spkr_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local net_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local log_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local clr_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local summary = Div{parent=root_pane_div,x=1,y=1}
|
||||
local changelog = Div{parent=root_pane_div,x=1,y=1}
|
||||
local peri_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local rs_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local check_sys = Div{parent=root_pane_div,x=1,y=1}
|
||||
local main_page = Div{parent=root_pane_div,y=1}
|
||||
local spkr_cfg = Div{parent=root_pane_div,y=1}
|
||||
local net_cfg = Div{parent=root_pane_div,y=1}
|
||||
local log_cfg = Div{parent=root_pane_div,y=1}
|
||||
local clr_cfg = Div{parent=root_pane_div,y=1}
|
||||
local summary = Div{parent=root_pane_div,y=1}
|
||||
local changelog = Div{parent=root_pane_div,y=1}
|
||||
local peri_cfg = Div{parent=root_pane_div,y=1}
|
||||
local rs_cfg = Div{parent=root_pane_div,y=1}
|
||||
local check_sys = Div{parent=root_pane_div,y=1}
|
||||
|
||||
local main_pane = MultiPane{parent=root_pane_div,x=1,y=1,panes={main_page,spkr_cfg,net_cfg,log_cfg,clr_cfg,summary,changelog,peri_cfg,rs_cfg,check_sys}}
|
||||
local main_pane = MultiPane{parent=root_pane_div,y=1,panes={main_page,spkr_cfg,net_cfg,log_cfg,clr_cfg,summary,changelog,peri_cfg,rs_cfg,check_sys}}
|
||||
|
||||
--#region Main Page
|
||||
|
||||
@@ -283,20 +283,20 @@ local function config_view(display)
|
||||
|
||||
local cl = Div{parent=changelog,x=2,y=4,width=49}
|
||||
|
||||
TextBox{parent=changelog,x=1,y=2,text=" Config Change Log",fg_bg=bw_fg_bg}
|
||||
TextBox{parent=changelog,y=2,text=" Config Change Log",fg_bg=bw_fg_bg}
|
||||
|
||||
local c_log = ListBox{parent=cl,x=1,y=1,height=12,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
local c_log = ListBox{parent=cl,y=1,height=12,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
for _, change in ipairs(changes) do
|
||||
TextBox{parent=c_log,text=change[1],fg_bg=bw_fg_bg}
|
||||
for _, v in ipairs(change[2]) do
|
||||
local e = Div{parent=c_log,height=#util.strwrap(v,46)}
|
||||
TextBox{parent=e,y=1,x=1,text="- ",fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=e,y=1,text="- ",fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=e,y=1,x=3,text=v,height=e.get_height(),fg_bg=cpair(colors.gray,colors.white)}
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=cl,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=cl,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ local function init(panel, config, units)
|
||||
|
||||
-- show routine statuses
|
||||
for i = 1, list_length do
|
||||
TextBox{parent=threads,x=1,y=i,text=util.sprintf("%02d",i)}
|
||||
TextBox{parent=threads,y=i,text=util.sprintf("%02d",i)}
|
||||
local rt_unit = LED{parent=threads,x=4,y=i,label="RT",colors=util.trinary(units[i].type~=RTU_UNIT_TYPE.REDSTONE,ind_grn,cpair(style.ind_bkg,style.ind_bkg))}
|
||||
rt_unit.register(databus.ps, "routine__unit_" .. i, rt_unit.update)
|
||||
end
|
||||
|
||||
@@ -409,8 +409,8 @@ function rtu.comms(version, backplane, conn_watchdog)
|
||||
---@param rtu_state rtu_state
|
||||
function public.close(rtu_state)
|
||||
conn_watchdog.cancel()
|
||||
public.unlink(rtu_state)
|
||||
_send(MGMT_TYPE.CLOSE, {})
|
||||
public.unlink(rtu_state)
|
||||
end
|
||||
|
||||
-- send a MODBUS TCP packet
|
||||
|
||||
@@ -21,7 +21,7 @@ local rtu = require("rtu.rtu")
|
||||
local threads = require("rtu.threads")
|
||||
local uinit = require("rtu.uinit")
|
||||
|
||||
local RTU_VERSION = "v1.13.7"
|
||||
local RTU_VERSION = "v1.13.11"
|
||||
|
||||
local println = util.println
|
||||
local println_ts = util.println_ts
|
||||
|
||||
139
rtu/threads.lua
139
rtu/threads.lua
@@ -197,6 +197,41 @@ function threads.thread__main(smem)
|
||||
|
||||
local sounders = backplane.sounders()
|
||||
|
||||
-- main loop periodic tasks
|
||||
local function loop_tick()
|
||||
-- blink heartbeat indicator
|
||||
databus.heartbeat()
|
||||
|
||||
-- periodic hardware tasks
|
||||
backplane.periodic()
|
||||
|
||||
-- update speaker states
|
||||
for _, sounder in pairs(sounders) do
|
||||
-- re-compute output if needed, then play audio if available
|
||||
if sounder.stream.is_recompute_needed() then
|
||||
sounder.stream.compute_buffer()
|
||||
if sounder.stream.any_active() then sounder.play() else sounder.stop() end
|
||||
end
|
||||
end
|
||||
|
||||
-- period tick, if we are not linked send establish request
|
||||
if rtu_state.linked then
|
||||
rtu_comms.manage_failover(backplane.active_nic())
|
||||
else
|
||||
-- advertise units
|
||||
local a_nic, s_nic = backplane.active_nic(), backplane.standby_nic()
|
||||
|
||||
if a_nic.is_network_up() then
|
||||
rtu_comms.send_establish(a_nic, units)
|
||||
elseif s_nic and s_nic.is_network_up() then
|
||||
rtu_comms.send_establish(s_nic, units)
|
||||
end
|
||||
end
|
||||
|
||||
-- start next clock timer
|
||||
loop_clock.start()
|
||||
end
|
||||
|
||||
-- start unlinked (in case of restart)
|
||||
rtu_comms.unlink(rtu_state)
|
||||
|
||||
@@ -207,51 +242,52 @@ function threads.thread__main(smem)
|
||||
while true do
|
||||
local event, param1, param2, param3, param4, param5 = util.pull_event()
|
||||
|
||||
if event == "timer" and loop_clock.is_clock(param1) then
|
||||
-- blink heartbeat indicator
|
||||
databus.heartbeat()
|
||||
|
||||
-- periodic hardware tasks
|
||||
backplane.periodic()
|
||||
|
||||
-- update speaker states
|
||||
for _, sounder in pairs(sounders) do
|
||||
-- re-compute output if needed, then play audio if available
|
||||
if sounder.stream.is_recompute_needed() then
|
||||
sounder.stream.compute_buffer()
|
||||
if sounder.stream.any_active() then sounder.play() else sounder.stop() end
|
||||
end
|
||||
end
|
||||
|
||||
-- period tick, if we are not linked send establish request
|
||||
if rtu_state.linked then
|
||||
rtu_comms.manage_failover(backplane.active_nic())
|
||||
else
|
||||
-- advertise units
|
||||
local a_nic, s_nic = backplane.active_nic(), backplane.standby_nic()
|
||||
|
||||
if a_nic.is_network_up() then
|
||||
rtu_comms.send_establish(a_nic, units)
|
||||
elseif s_nic and s_nic.is_network_up() then
|
||||
rtu_comms.send_establish(s_nic, units)
|
||||
end
|
||||
end
|
||||
|
||||
-- start next clock timer
|
||||
loop_clock.start()
|
||||
elseif event == "modem_message" then
|
||||
if event == "modem_message" then
|
||||
-- got a packet
|
||||
local packet = rtu_comms.parse_packet(param1, param2, param3, param4, param5)
|
||||
if packet ~= nil then
|
||||
-- pass the packet onto the comms message queue
|
||||
smem.q.mq_comms.push_network(packet)
|
||||
end
|
||||
elseif event == "timer" and conn_watchdog.is_timer(param1) then
|
||||
-- haven't heard from server recently? close connection
|
||||
rtu_comms.close(rtu_state)
|
||||
elseif event == "timer" then
|
||||
-- notify timer callback dispatcher if no other timer case claimed this event
|
||||
tcd.handle(param1)
|
||||
-- pass this timer event onto the right handler
|
||||
if loop_clock.is_clock(param1) then
|
||||
-- main loop tick
|
||||
loop_tick()
|
||||
elseif conn_watchdog.is_timer(param1) then
|
||||
-- supervisor connection timed out
|
||||
rtu_comms.close(rtu_state)
|
||||
else
|
||||
-- notify timer callback dispatcher, no other handler claimed this event
|
||||
tcd.handle(param1)
|
||||
end
|
||||
elseif event == "speaker_audio_empty" then
|
||||
-- handle empty speaker audio buffer
|
||||
for i = 1, #sounders do
|
||||
local sounder = sounders[i]
|
||||
if sounder.name == param1 then
|
||||
sounder.continue()
|
||||
break
|
||||
end
|
||||
end
|
||||
elseif event == "mouse_click" or event == "mouse_up" or event == "mouse_drag" or event == "mouse_scroll" or
|
||||
event == "double_click" then
|
||||
-- handle a mouse event
|
||||
renderer.handle_mouse(core.events.new_mouse_event(event, param1, param2, param3))
|
||||
elseif event == "peripheral" then
|
||||
-- peripheral connect
|
||||
local type, device = ppm.mount(param1)
|
||||
|
||||
if type ~= nil and device ~= nil then
|
||||
if type == "modem" or type == "speaker" then
|
||||
backplane.attach(type, device, param1, println_ts)
|
||||
else
|
||||
-- relink lost peripheral to correct unit entry
|
||||
for i = 1, #units do
|
||||
handle_unit_mount(smem, println_ts, param1, type, device, units[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif event == "peripheral_detach" then
|
||||
-- handle loss of a device
|
||||
local type, device = ppm.handle_unmount(param1)
|
||||
@@ -277,33 +313,6 @@ function threads.thread__main(smem)
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif event == "peripheral" then
|
||||
-- peripheral connect
|
||||
local type, device = ppm.mount(param1)
|
||||
|
||||
if type ~= nil and device ~= nil then
|
||||
if type == "modem" or type == "speaker" then
|
||||
backplane.attach(type, device, param1, println_ts)
|
||||
else
|
||||
-- relink lost peripheral to correct unit entry
|
||||
for i = 1, #units do
|
||||
handle_unit_mount(smem, println_ts, param1, type, device, units[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif event == "mouse_click" or event == "mouse_up" or event == "mouse_drag" or event == "mouse_scroll" or
|
||||
event == "double_click" then
|
||||
-- handle a mouse event
|
||||
renderer.handle_mouse(core.events.new_mouse_event(event, param1, param2, param3))
|
||||
elseif event == "speaker_audio_empty" then
|
||||
-- handle empty speaker audio buffer
|
||||
for i = 1, #sounders do
|
||||
local sounder = sounders[i]
|
||||
if sounder.name == param1 then
|
||||
sounder.continue()
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- check for termination request
|
||||
|
||||
@@ -72,7 +72,7 @@ local rs = {}
|
||||
|
||||
rs.IMATRIX_CHARGE_LOW = 0.05 -- activation threshold (less than) for F_MATRIX_LOW
|
||||
rs.IMATRIX_CHARGE_HIGH = 0.95 -- activation threshold (greater than) for F_MATRIX_HIGH
|
||||
rs.AUX_COOL_ENABLE = 0.60 -- actiation threshold (less than or equal) for U_AUX_COOL
|
||||
rs.AUX_COOL_ENABLE = 0.85 -- actiation threshold (less than or equal) for U_AUX_COOL
|
||||
rs.AUX_COOL_DISABLE = 1.00 -- deactivation threshold (greater than or equal) for U_AUX_COOL
|
||||
|
||||
constants.RS_THRESHOLDS = rs
|
||||
|
||||
@@ -210,6 +210,8 @@ end
|
||||
|
||||
---@alias color integer
|
||||
|
||||
---@alias auto_ctl_cfg [ PROCESS, number, integer, integer, number, number, number[] ]
|
||||
|
||||
--#region ENUMERATION TYPES
|
||||
|
||||
---@enum LISTEN_MODE
|
||||
@@ -392,9 +394,10 @@ types.PROCESS = {
|
||||
BURN_RATE = 2,
|
||||
CHARGE = 3,
|
||||
GEN_RATE = 4,
|
||||
MATRIX_FAULT_IDLE = 5,
|
||||
SYSTEM_ALARM_IDLE = 6,
|
||||
GEN_RATE_FAULT_IDLE = 7
|
||||
RANGE_CONTROL = 5,
|
||||
MATRIX_FAULT_IDLE = 6,
|
||||
SYSTEM_ALARM_IDLE = 7,
|
||||
GEN_RATE_FAULT_IDLE = 8
|
||||
}
|
||||
|
||||
types.PROCESS_NAMES = {
|
||||
@@ -403,6 +406,7 @@ types.PROCESS_NAMES = {
|
||||
"BURN_RATE",
|
||||
"CHARGE",
|
||||
"GEN_RATE",
|
||||
"RANGE_CONTROL",
|
||||
"MATRIX_FAULT_IDLE",
|
||||
"SYSTEM_ALARM_IDLE",
|
||||
"GEN_RATE_FAULT_IDLE"
|
||||
|
||||
@@ -24,7 +24,7 @@ local t_pack = table.pack
|
||||
local util = {}
|
||||
|
||||
-- scada-common version
|
||||
util.version = "1.8.1"
|
||||
util.version = "1.8.2"
|
||||
|
||||
util.TICK_TIME_S = 0.05
|
||||
util.TICK_TIME_MS = 50
|
||||
@@ -199,7 +199,7 @@ function util.sign(x) return util.trinary(x < 0, -1, 1) end
|
||||
---@return integer rounded
|
||||
function util.round(x) return math.floor(x + 0.5) end
|
||||
|
||||
-- get a new moving average object
|
||||
-- get a new moving average object (FIR filter)
|
||||
---@nodiscard
|
||||
---@param length integer history length
|
||||
function util.mov_avg(length)
|
||||
|
||||
@@ -185,16 +185,16 @@ function facility.create(tool_ctl, main_pane, cfg_sys, fac_cfg, style)
|
||||
local fac_c_8 = Div{parent=fac_cfg,x=2,y=4,width=49}
|
||||
local fac_c_9 = Div{parent=fac_cfg,x=2,y=4,width=49}
|
||||
|
||||
local fac_pane = MultiPane{parent=fac_cfg,x=1,y=4,panes={fac_c_1,fac_c_2,fac_c_3,fac_c_4,fac_c_5,fac_c_6,fac_c_7,fac_c_8,fac_c_9}}
|
||||
local fac_pane = MultiPane{parent=fac_cfg,y=4,panes={fac_c_1,fac_c_2,fac_c_3,fac_c_4,fac_c_5,fac_c_6,fac_c_7,fac_c_8,fac_c_9}}
|
||||
|
||||
TextBox{parent=fac_cfg,x=1,y=2,text=" Facility Configuration",fg_bg=cpair(colors.black,colors.yellow)}
|
||||
TextBox{parent=fac_cfg,y=2,text=" Facility Configuration",fg_bg=cpair(colors.black,colors.yellow)}
|
||||
|
||||
--#region Unit Count
|
||||
|
||||
TextBox{parent=fac_c_1,x=1,y=1,height=3,text="Please enter the number of reactors you have, also referred to as reactor units or 'units' for short. A maximum of 4 is currently supported."}
|
||||
tool_ctl.num_units = NumberField{parent=fac_c_1,x=1,y=5,width=5,max_chars=2,default=ini_cfg.UnitCount,min=1,max=4,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=fac_c_1,y=1,height=3,text="Please enter the number of reactors you have, also referred to as reactor units or 'units' for short. A maximum of 4 is currently supported."}
|
||||
tool_ctl.num_units = NumberField{parent=fac_c_1,y=5,width=5,max_chars=2,default=ini_cfg.UnitCount,min=1,max=4,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=fac_c_1,x=7,y=5,text="reactors"}
|
||||
TextBox{parent=fac_c_1,x=1,y=7,height=3,text="If you already configured your coordinator, make sure you update the coordinator's configured unit count.",fg_bg=cpair(colors.yellow,colors._INHERIT)}
|
||||
TextBox{parent=fac_c_1,y=7,height=3,text="If you already configured your coordinator, make sure you update the coordinator's configured unit count.",fg_bg=cpair(colors.yellow,colors._INHERIT)}
|
||||
|
||||
local nu_error = TextBox{parent=fac_c_1,x=8,y=14,width=35,text="Please set the number of reactors.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
|
||||
@@ -221,14 +221,14 @@ function facility.create(tool_ctl, main_pane, cfg_sys, fac_cfg, style)
|
||||
else nu_error.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=fac_c_1,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_1,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_1,x=44,y=14,text="Next \x1a",callback=submit_num_units,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
--#region Cooling Configuration
|
||||
|
||||
TextBox{parent=fac_c_2,x=1,y=1,height=4,text="Please provide the reactor cooling configuration below. This includes the number of turbines, boilers, and if that reactor has a connection to a dynamic tank for emergency coolant."}
|
||||
TextBox{parent=fac_c_2,x=1,y=6,text="UNIT TURBINES BOILERS HAS TANK CONNECTION?",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=fac_c_2,y=1,height=4,text="Please provide the reactor cooling configuration below. This includes the number of turbines, boilers, and if that reactor has a connection to a dynamic tank for emergency coolant."}
|
||||
TextBox{parent=fac_c_2,y=6,text="UNIT TURBINES BOILERS HAS TANK CONNECTION?",fg_bg=g_lg_fg_bg}
|
||||
|
||||
for i = 1, 4 do
|
||||
local num_t, num_b, has_t = 1, 0, false
|
||||
@@ -240,7 +240,7 @@ function facility.create(tool_ctl, main_pane, cfg_sys, fac_cfg, style)
|
||||
has_t = conf.TankConnection == true
|
||||
end
|
||||
|
||||
local line = Div{parent=fac_c_2,x=1,y=7+i,height=1}
|
||||
local line = Div{parent=fac_c_2,y=7+i,height=1}
|
||||
|
||||
TextBox{parent=line,text="Unit "..i,width=6}
|
||||
local turbines = NumberField{parent=line,x=9,y=1,width=5,max_chars=2,default=num_t,min=1,max=3,fg_bg=bw_fg_bg}
|
||||
@@ -304,16 +304,16 @@ function facility.create(tool_ctl, main_pane, cfg_sys, fac_cfg, style)
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=fac_c_2,x=1,y=14,text="\x1b Back",callback=function()fac_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_2,y=14,text="\x1b Back",callback=function()fac_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_2,x=44,y=14,text="Next \x1a",callback=submit_cooling,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
--#region Facility Tanks Option
|
||||
|
||||
TextBox{parent=fac_c_3,x=1,y=1,height=6,text="You have set one or more of your units to use dynamic tanks for emergency coolant. You have two paths for configuration. The first is to assign dynamic tanks to reactor units; one tank per reactor, only connected to that reactor. RTU configurations must also assign it as such."}
|
||||
TextBox{parent=fac_c_3,x=1,y=8,height=3,text="Alternatively, you can configure them as facility tanks to connect to multiple reactor units. These can intermingle with unit-specific tanks."}
|
||||
TextBox{parent=fac_c_3,y=1,height=6,text="You have set one or more of your units to use dynamic tanks for emergency coolant. You have two paths for configuration. The first is to assign dynamic tanks to reactor units; one tank per reactor, only connected to that reactor. RTU configurations must also assign it as such."}
|
||||
TextBox{parent=fac_c_3,y=8,height=3,text="Alternatively, you can configure them as facility tanks to connect to multiple reactor units. These can intermingle with unit-specific tanks."}
|
||||
|
||||
tool_ctl.en_fac_tanks = Checkbox{parent=fac_c_3,x=1,y=12,label="Use Facility Dynamic Tanks",default=ini_cfg.FacilityTankMode>0,box_fg_bg=cpair(colors.yellow,colors.black)}
|
||||
tool_ctl.en_fac_tanks = Checkbox{parent=fac_c_3,y=12,label="Use Facility Dynamic Tanks",default=ini_cfg.FacilityTankMode>0,box_fg_bg=cpair(colors.yellow,colors.black)}
|
||||
|
||||
local function submit_en_fac_tank()
|
||||
if tool_ctl.en_fac_tanks.get_value() then
|
||||
@@ -336,19 +336,19 @@ function facility.create(tool_ctl, main_pane, cfg_sys, fac_cfg, style)
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=fac_c_3,x=1,y=14,text="\x1b Back",callback=function()fac_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_3,y=14,text="\x1b Back",callback=function()fac_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_3,x=44,y=14,text="Next \x1a",callback=submit_en_fac_tank,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
--#region Facility Tank Connections
|
||||
|
||||
TextBox{parent=fac_c_4,x=1,y=1,height=4,text="Please set unit connections to dynamic tanks, selecting at least one facility tank. The layout for facility tanks will be configured next."}
|
||||
TextBox{parent=fac_c_4,y=1,height=4,text="Please set unit connections to dynamic tanks, selecting at least one facility tank. The layout for facility tanks will be configured next."}
|
||||
|
||||
for i = 1, 4 do
|
||||
local val = math.max(1, ini_cfg.FacilityTankDefs[i] or 2)
|
||||
local div = Div{parent=fac_c_4,x=1,y=3+(2*i),height=2}
|
||||
local div = Div{parent=fac_c_4,y=3+(2*i),height=2}
|
||||
|
||||
TextBox{parent=div,x=1,y=1,width=33,text="Unit "..i.." will be connected to..."}
|
||||
TextBox{parent=div,y=1,width=33,text="Unit "..i.." will be connected to..."}
|
||||
TextBox{parent=div,x=6,y=2,width=3,text="..."}
|
||||
local tank_opt = Radio2D{parent=div,x=9,y=2,rows=1,columns=2,default=val,options={"its own Unit Tank","a Facility Tank"},radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.yellow,disable_color=colors.gray,disable_fg_bg=g_lg_fg_bg}
|
||||
local no_tank = TextBox{parent=div,x=9,y=2,width=34,text="no tank (as you set two steps ago)",fg_bg=cpair(colors.gray,colors.lightGray),hidden=true}
|
||||
@@ -402,13 +402,13 @@ function facility.create(tool_ctl, main_pane, cfg_sys, fac_cfg, style)
|
||||
else tank_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=fac_c_4,x=1,y=14,text="\x1b Back",callback=function()fac_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_4,y=14,text="\x1b Back",callback=function()fac_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_4,x=44,y=14,text="Next \x1a",callback=submit_tank_defs,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
--#region Facility Tank Mode
|
||||
|
||||
TextBox{parent=fac_c_5,x=1,y=1,text="Please select your dynamic tank layout."}
|
||||
TextBox{parent=fac_c_5,y=1,text="Please select your dynamic tank layout."}
|
||||
TextBox{parent=fac_c_5,x=12,y=3,text="Facility Tanks Unit Tanks",fg_bg=g_lg_fg_bg}
|
||||
|
||||
--#region Tank Layout Visualizer
|
||||
@@ -429,18 +429,18 @@ function facility.create(tool_ctl, main_pane, cfg_sys, fac_cfg, style)
|
||||
|
||||
-- draw facility tank connections
|
||||
|
||||
local ftank_1 = Div{parent=vis,x=1,y=1,width=13,height=1}
|
||||
local ftank_1 = Div{parent=vis,y=1,width=13,height=1}
|
||||
TextBox{parent=ftank_1,width=7,text="Tank F1"}
|
||||
self.vis_ftanks[1] = {
|
||||
line = ftank_1, pipe_direct = TextBox{parent=ftank_1,x=9,y=1,width=5,text=string.rep("\x8c",5),fg_bg=pipe_cpair}
|
||||
}
|
||||
|
||||
for i = 2, 4 do
|
||||
local line = Div{parent=vis,x=1,y=(i-1)*2,width=13,height=2}
|
||||
local line = Div{parent=vis,y=(i-1)*2,width=13,height=2}
|
||||
local pipe_conn = TextBox{parent=line,x=13,y=2,width=1,text="\x8c",fg_bg=pipe_cpair}
|
||||
local pipe_chain = TextBox{parent=line,x=12,y=1,width=1,height=2,text="\x95\n\x8d",fg_bg=pipe_cpair}
|
||||
local pipe_direct = TextBox{parent=line,x=9,y=2,width=4,text="\x8c\x8c\x8c\x8c",fg_bg=pipe_cpair}
|
||||
local label = TextBox{parent=line,x=1,y=2,width=7,text=""}
|
||||
local label = TextBox{parent=line,y=2,width=7,text=""}
|
||||
self.vis_ftanks[i] = { line = line, pipe_conn = pipe_conn, pipe_chain = pipe_chain, pipe_direct = pipe_direct, label = label }
|
||||
end
|
||||
|
||||
@@ -572,7 +572,7 @@ function facility.create(tool_ctl, main_pane, cfg_sys, fac_cfg, style)
|
||||
end
|
||||
|
||||
local tank_modes = { "Mode 1", "Mode 2", "Mode 3", "Mode 4", "Mode 5", "Mode 6", "Mode 7", "Mode 8" }
|
||||
tool_ctl.tank_mode = RadioButton{parent=fac_c_5,x=1,y=4,callback=change_mode,default=math.max(1,ini_cfg.FacilityTankMode),options=tank_modes,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.yellow}
|
||||
tool_ctl.tank_mode = RadioButton{parent=fac_c_5,y=4,callback=change_mode,default=math.max(1,ini_cfg.FacilityTankMode),options=tank_modes,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.yellow}
|
||||
|
||||
--#endregion
|
||||
|
||||
@@ -585,7 +585,7 @@ function facility.create(tool_ctl, main_pane, cfg_sys, fac_cfg, style)
|
||||
fac_pane.set_value(7)
|
||||
end
|
||||
|
||||
PushButton{parent=fac_c_5,x=1,y=14,text="\x1b Back",callback=function()fac_pane.set_value(4)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_5,y=14,text="\x1b Back",callback=function()fac_pane.set_value(4)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_5,x=44,y=14,text="Next \x1a",callback=next_from_tank_mode,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
PushButton{parent=fac_c_5,x=8,y=14,min_width=7,text="About",callback=function()fac_pane.set_value(6)end,fg_bg=cpair(colors.black,colors.lightBlue),active_fg_bg=btn_act_fg_bg}
|
||||
@@ -597,14 +597,14 @@ function facility.create(tool_ctl, main_pane, cfg_sys, fac_cfg, style)
|
||||
TextBox{parent=fac_c_6,y=5,height=4,text="Examples: A U2 tank should be configured on an RTU as the dynamic tank for unit #2. An F3 tank should be configured on an RTU as the #3 dynamic tank for the facility."}
|
||||
TextBox{parent=fac_c_6,y=10,height=3,text="Some modes may look the same if you are not using 4 total reactor units. The wiki has details. Modes that look the same will function the same.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
PushButton{parent=fac_c_6,x=1,y=14,text="\x1b Back",callback=function()fac_pane.set_value(5)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_6,y=14,text="\x1b Back",callback=function()fac_pane.set_value(5)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
--#region Dynamic Tank Fluid Types
|
||||
|
||||
TextBox{parent=fac_c_7,height=3,text="Specify each tank's coolant type, for display use only. Water is the only option if one or more of the connected units is water cooled."}
|
||||
|
||||
local tank_fluid_list = Div{parent=fac_c_7,x=1,y=5,height=8}
|
||||
local tank_fluid_list = Div{parent=fac_c_7,y=5,height=8}
|
||||
|
||||
function self.draw_fluid_ops()
|
||||
tank_fluid_list.remove_all()
|
||||
@@ -682,7 +682,7 @@ function facility.create(tool_ctl, main_pane, cfg_sys, fac_cfg, style)
|
||||
fac_pane.set_value(8)
|
||||
end
|
||||
|
||||
PushButton{parent=fac_c_7,x=1,y=14,text="\x1b Back",callback=back_from_fluids,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_7,y=14,text="\x1b Back",callback=back_from_fluids,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_7,x=44,y=14,text="Next \x1a",callback=submit_tank_fluids,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -691,7 +691,7 @@ function facility.create(tool_ctl, main_pane, cfg_sys, fac_cfg, style)
|
||||
TextBox{parent=fac_c_8,height=5,text="Auxiliary water coolant can be enabled for units to provide extra water during turbine ramp-up. For water cooled reactors, this goes to the reactor. For sodium cooled reactors, water goes to the boiler."}
|
||||
|
||||
for i = 1, 4 do
|
||||
local line = Div{parent=fac_c_8,x=1,y=7+i,height=1}
|
||||
local line = Div{parent=fac_c_8,y=7+i,height=1}
|
||||
|
||||
TextBox{parent=line,text="Unit "..i.." -",width=8}
|
||||
local aux_cool = Checkbox{parent=line,x=10,y=1,label="Has Auxiliary Coolant",default=ini_cfg.AuxiliaryCoolant[i],box_fg_bg=cpair(colors.yellow,colors.black)}
|
||||
@@ -709,7 +709,7 @@ function facility.create(tool_ctl, main_pane, cfg_sys, fac_cfg, style)
|
||||
fac_pane.set_value(9)
|
||||
end
|
||||
|
||||
PushButton{parent=fac_c_8,x=1,y=14,text="\x1b Back",callback=function()fac_pane.set_value(7)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_8,y=14,text="\x1b Back",callback=function()fac_pane.set_value(7)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_8,x=44,y=14,text="Next \x1a",callback=submit_aux_cool,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -718,14 +718,14 @@ function facility.create(tool_ctl, main_pane, cfg_sys, fac_cfg, style)
|
||||
TextBox{parent=fac_c_9,height=6,text="Charge control provides automatic control to maintain an induction matrix charge level. In order to have smoother control, reactors that were activated will be held on at 0.01 mB/t for a short period before allowing them to turn off. This minimizes overshooting the charge target."}
|
||||
TextBox{parent=fac_c_9,y=8,height=3,text="You can extend this to a full minute to minimize reactors flickering on/off, but there may be more overshoot of the target."}
|
||||
|
||||
local ext_idling = Checkbox{parent=fac_c_9,x=1,y=12,label="Enable Extended Idling",default=ini_cfg.ExtChargeIdling,box_fg_bg=cpair(colors.yellow,colors.black)}
|
||||
local ext_idling = Checkbox{parent=fac_c_9,y=12,label="Enable Extended Idling",default=ini_cfg.ExtChargeIdling,box_fg_bg=cpair(colors.yellow,colors.black)}
|
||||
|
||||
local function submit_idling()
|
||||
tmp_cfg.ExtChargeIdling = ext_idling.get_value()
|
||||
main_pane.set_value(3)
|
||||
end
|
||||
|
||||
PushButton{parent=fac_c_9,x=1,y=14,text="\x1b Back",callback=function()fac_pane.set_value(8)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_9,y=14,text="\x1b Back",callback=function()fac_pane.set_value(8)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=fac_c_9,x=44,y=14,text="Next \x1a",callback=submit_idling,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
|
||||
@@ -75,21 +75,21 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
local net_c_5 = Div{parent=net_cfg,x=2,y=4,width=49}
|
||||
local net_c_6 = Div{parent=net_cfg,x=2,y=4,width=49}
|
||||
|
||||
local net_pane = MultiPane{parent=net_cfg,x=1,y=4,panes={net_c_1,net_c_2,net_c_3,net_c_4,net_c_5,net_c_6}}
|
||||
local net_pane = MultiPane{parent=net_cfg,y=4,panes={net_c_1,net_c_2,net_c_3,net_c_4,net_c_5,net_c_6}}
|
||||
|
||||
TextBox{parent=net_cfg,x=1,y=2,text=" Network Configuration",fg_bg=cpair(colors.black,colors.lightBlue)}
|
||||
TextBox{parent=net_cfg,y=2,text=" Network Configuration",fg_bg=cpair(colors.black,colors.lightBlue)}
|
||||
|
||||
TextBox{parent=net_c_1,x=1,y=1,text="Please select the network interface(s)."}
|
||||
TextBox{parent=net_c_1,y=1,text="Please select the network interface(s)."}
|
||||
TextBox{parent=net_c_1,x=41,y=1,text="new!",fg_bg=cpair(colors.red,colors._INHERIT)} ---@todo remove NEW tag on next revision
|
||||
|
||||
local function on_wired_change(_) tool_ctl.gen_modem_list() end
|
||||
|
||||
local wireless = Checkbox{parent=net_c_1,x=1,y=3,label="Wireless/Ender Modem",default=ini_cfg.WirelessModem,box_fg_bg=cpair(colors.lightBlue,colors.black)}
|
||||
local wireless = Checkbox{parent=net_c_1,y=3,label="Wireless/Ender Modem",default=ini_cfg.WirelessModem,box_fg_bg=cpair(colors.lightBlue,colors.black)}
|
||||
TextBox{parent=net_c_1,x=24,y=3,text="(required for Pocket)",fg_bg=g_lg_fg_bg}
|
||||
local wired = Checkbox{parent=net_c_1,x=1,y=5,label="Wired Modem",default=ini_cfg.WiredModem~=false,box_fg_bg=cpair(colors.lightBlue,colors.black),callback=on_wired_change}
|
||||
local wired = Checkbox{parent=net_c_1,y=5,label="Wired Modem",default=ini_cfg.WiredModem~=false,box_fg_bg=cpair(colors.lightBlue,colors.black),callback=on_wired_change}
|
||||
TextBox{parent=net_c_1,x=3,y=6,text="this one MUST ONLY connect to SCADA computers",fg_bg=cpair(colors.red,colors._INHERIT)}
|
||||
TextBox{parent=net_c_1,x=3,y=7,text="connecting it to peripherals will cause issues",fg_bg=g_lg_fg_bg}
|
||||
local modem_list = ListBox{parent=net_c_1,x=1,y=8,height=5,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
local modem_list = ListBox{parent=net_c_1,y=8,height=5,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
local modem_err = TextBox{parent=net_c_1,x=8,y=14,width=35,text="",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
|
||||
@@ -114,12 +114,12 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_1,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_1,y=14,text="\x1b Back",callback=function()main_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_1,x=44,y=14,text="Next \x1a",callback=submit_interfaces,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_2,x=1,y=1,text="Please assign device connection interfaces if you selected multiple network interfaces."}
|
||||
TextBox{parent=net_c_2,y=1,text="Please assign device connection interfaces if you selected multiple network interfaces."}
|
||||
TextBox{parent=net_c_2,x=39,y=2,text="new!",fg_bg=cpair(colors.red,colors._INHERIT)} ---@todo remove NEW tag on next revision
|
||||
TextBox{parent=net_c_2,x=1,y=4,text="Reactor PLC\nRTU Gateway\nCoordinator",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_2,y=4,text="Reactor PLC\nRTU Gateway\nCoordinator",fg_bg=g_lg_fg_bg}
|
||||
local opts = { "Wireless", "Wired", "Both" }
|
||||
local plc_listen = Radio2D{parent=net_c_2,x=14,y=4,rows=1,columns=3,default=ini_cfg.PLC_Listen,options=opts,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.lightBlue,disable_color=colors.gray,disable_fg_bg=g_lg_fg_bg}
|
||||
local rtu_listen = Radio2D{parent=net_c_2,x=14,rows=1,columns=3,default=ini_cfg.RTU_Listen,options=opts,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.lightBlue,disable_color=colors.gray,disable_fg_bg=g_lg_fg_bg}
|
||||
@@ -175,29 +175,29 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
net_pane.set_value(3)
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_2,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_2,y=14,text="\x1b Back",callback=function()net_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_2,x=44,y=14,text="Next \x1a",callback=submit_net_cfg_opts,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_3,x=1,y=1,text="Please set the network channels below."}
|
||||
TextBox{parent=net_c_3,x=1,y=3,height=4,text="Each of the 5 uniquely named channels must be the same for each device in this SCADA network. For multiplayer servers, it is recommended to not use the default channels.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_3,y=1,text="Please set the network channels below."}
|
||||
TextBox{parent=net_c_3,y=3,height=4,text="Each of the 5 uniquely named channels must be the same for each device in this SCADA network. For multiplayer servers, it is recommended to not use the default channels.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_3,x=1,y=8,width=18,text="Supervisor Channel"}
|
||||
TextBox{parent=net_c_3,y=8,width=18,text="Supervisor Channel"}
|
||||
local svr_chan = NumberField{parent=net_c_3,x=21,y=8,width=7,default=ini_cfg.SVR_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_3,x=29,y=8,height=4,text="[SVR_CHANNEL]",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_3,x=1,y=9,width=11,text="PLC Channel"}
|
||||
TextBox{parent=net_c_3,y=9,width=11,text="PLC Channel"}
|
||||
local plc_chan = NumberField{parent=net_c_3,x=21,y=9,width=7,default=ini_cfg.PLC_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_3,x=29,y=9,height=4,text="[PLC_CHANNEL]",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_3,x=1,y=10,width=19,text="RTU Gateway Channel"}
|
||||
TextBox{parent=net_c_3,y=10,width=19,text="RTU Gateway Channel"}
|
||||
local rtu_chan = NumberField{parent=net_c_3,x=21,y=10,width=7,default=ini_cfg.RTU_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_3,x=29,y=10,height=4,text="[RTU_CHANNEL]",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_3,x=1,y=11,width=19,text="Coordinator Channel"}
|
||||
TextBox{parent=net_c_3,y=11,width=19,text="Coordinator Channel"}
|
||||
local crd_chan = NumberField{parent=net_c_3,x=21,y=11,width=7,default=ini_cfg.CRD_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_3,x=29,y=11,height=4,text="[CRD_CHANNEL]",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_3,x=1,y=12,width=14,text="Pocket Channel"}
|
||||
TextBox{parent=net_c_3,y=12,width=14,text="Pocket Channel"}
|
||||
self.pkt_chan = NumberField{parent=net_c_3,x=21,y=12,width=7,default=ini_cfg.PKT_Channel,min=1,max=65535,fg_bg=bw_fg_bg,dis_fg_bg=cpair(colors.lightGray,colors.white)}
|
||||
TextBox{parent=net_c_3,x=29,y=12,height=4,text="[PKT_CHANNEL]",fg_bg=g_lg_fg_bg}
|
||||
|
||||
@@ -217,22 +217,22 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
else chan_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_3,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_3,y=14,text="\x1b Back",callback=function()net_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_3,x=44,y=14,text="Next \x1a",callback=submit_channels,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_4,x=1,y=1,text="Please set the connection timeouts below."}
|
||||
TextBox{parent=net_c_4,x=1,y=3,height=4,text="You generally should not need to modify these. On slow servers, you can try to increase this to make the system wait longer before assuming a disconnection. The default for all is 5 seconds.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_4,y=1,text="Please set the connection timeouts below."}
|
||||
TextBox{parent=net_c_4,y=3,height=4,text="You generally should not need to modify these. On slow servers, you can try to increase this to make the system wait longer before assuming a disconnection. The default for all is 5 seconds.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_4,x=1,y=8,width=11,text="PLC Timeout"}
|
||||
TextBox{parent=net_c_4,y=8,width=11,text="PLC Timeout"}
|
||||
local plc_timeout = NumberField{parent=net_c_4,x=21,y=8,width=7,default=ini_cfg.PLC_Timeout,min=2,max=25,max_chars=6,max_frac_digits=2,allow_decimal=true,fg_bg=bw_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_4,x=1,y=9,width=19,text="RTU Gateway Timeout"}
|
||||
TextBox{parent=net_c_4,y=9,width=19,text="RTU Gateway Timeout"}
|
||||
local rtu_timeout = NumberField{parent=net_c_4,x=21,y=9,width=7,default=ini_cfg.RTU_Timeout,min=2,max=25,max_chars=6,max_frac_digits=2,allow_decimal=true,fg_bg=bw_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_4,x=1,y=10,width=19,text="Coordinator Timeout"}
|
||||
TextBox{parent=net_c_4,y=10,width=19,text="Coordinator Timeout"}
|
||||
local crd_timeout = NumberField{parent=net_c_4,x=21,y=10,width=7,default=ini_cfg.CRD_Timeout,min=2,max=25,max_chars=6,max_frac_digits=2,allow_decimal=true,fg_bg=bw_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_4,x=1,y=11,width=14,text="Pocket Timeout"}
|
||||
TextBox{parent=net_c_4,y=11,width=14,text="Pocket Timeout"}
|
||||
self.pkt_timeout = NumberField{parent=net_c_4,x=21,y=11,width=7,default=ini_cfg.PKT_Timeout,min=2,max=25,max_chars=6,max_frac_digits=2,allow_decimal=true,fg_bg=bw_fg_bg,dis_fg_bg=cpair(colors.lightGray,colors.white)}
|
||||
|
||||
TextBox{parent=net_c_4,x=29,y=8,height=4,width=7,text="seconds\nseconds\nseconds\nseconds",fg_bg=g_lg_fg_bg}
|
||||
@@ -259,14 +259,14 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
else ct_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_4,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_4,y=14,text="\x1b Back",callback=function()net_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_4,x=44,y=14,text="Next \x1a",callback=submit_timeouts,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_5,x=1,y=1,text="Please set the wireless trusted range below."}
|
||||
TextBox{parent=net_c_5,x=1,y=3,height=3,text="Setting this to a value larger than 0 prevents wireless connections with devices that many meters (blocks) away in any direction.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_5,x=1,y=7,height=2,text="This is optional. You can disable this functionality by setting the value to 0.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_5,y=1,text="Please set the wireless trusted range below."}
|
||||
TextBox{parent=net_c_5,y=3,height=3,text="Setting this to a value larger than 0 prevents wireless connections with devices that many meters (blocks) away in any direction.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_5,y=7,height=2,text="This is optional. You can disable this functionality by setting the value to 0.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local range = NumberField{parent=net_c_5,x=1,y=10,width=10,default=ini_cfg.TrustedRange,min=0,max_chars=20,allow_decimal=true,fg_bg=bw_fg_bg}
|
||||
local range = NumberField{parent=net_c_5,y=10,width=10,default=ini_cfg.TrustedRange,min=0,max_chars=20,allow_decimal=true,fg_bg=bw_fg_bg}
|
||||
|
||||
local tr_err = TextBox{parent=net_c_5,x=8,y=14,width=35,text="Please set the trusted range.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
|
||||
@@ -279,14 +279,14 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
else tr_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_5,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(4)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_5,y=14,text="\x1b Back",callback=function()net_pane.set_value(4)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_5,x=44,y=14,text="Next \x1a",callback=submit_tr,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_6,x=1,y=1,height=2,text="Optionally, set the facility authentication key below. Do NOT use one of your passwords."}
|
||||
TextBox{parent=net_c_6,x=1,y=4,height=6,text="This enables verifying that messages are authentic, so it is intended for wireless security on multiplayer servers. All devices on the same wireless network MUST use the same key if any device has a key. This does result in some extra computation (can slow things down).",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=net_c_6,y=1,height=2,text="Optionally, set the facility authentication key below. Do NOT use one of your passwords."}
|
||||
TextBox{parent=net_c_6,y=4,height=6,text="This enables verifying that messages are authentic, so it is intended for wireless security on multiplayer servers. All devices on the same wireless network MUST use the same key if any device has a key. This does result in some extra computation (can slow things down).",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=net_c_6,x=1,y=11,text="Auth Key (Wireless Only, Not Used for Wired)"}
|
||||
local key, _ = TextField{parent=net_c_6,x=1,y=12,max_len=64,value=ini_cfg.AuthKey,width=32,height=1,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=net_c_6,y=11,text="Auth Key (Wireless Only, Not Used for Wired)"}
|
||||
local key, _ = TextField{parent=net_c_6,y=12,max_len=64,value=ini_cfg.AuthKey,width=32,height=1,fg_bg=bw_fg_bg}
|
||||
|
||||
local function censor_key(enable) key.censor(tri(enable, "*", nil)) end
|
||||
|
||||
@@ -306,7 +306,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
else key_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=net_c_6,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(5)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_6,y=14,text="\x1b Back",callback=function()net_pane.set_value(5)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=net_c_6,x=44,y=14,text="Next \x1a",callback=submit_auth,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -315,17 +315,17 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
|
||||
local log_c_1 = Div{parent=log_cfg,x=2,y=4,width=49}
|
||||
|
||||
TextBox{parent=log_cfg,x=1,y=2,text=" Logging Configuration",fg_bg=cpair(colors.black,colors.pink)}
|
||||
TextBox{parent=log_cfg,y=2,text=" Logging Configuration",fg_bg=cpair(colors.black,colors.pink)}
|
||||
|
||||
TextBox{parent=log_c_1,x=1,y=1,text="Please configure logging below."}
|
||||
TextBox{parent=log_c_1,y=1,text="Please configure logging below."}
|
||||
|
||||
TextBox{parent=log_c_1,x=1,y=3,text="Log File Mode"}
|
||||
local mode = RadioButton{parent=log_c_1,x=1,y=4,default=ini_cfg.LogMode+1,options={"Append on Startup","Replace on Startup"},radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.pink}
|
||||
TextBox{parent=log_c_1,y=3,text="Log File Mode"}
|
||||
local mode = RadioButton{parent=log_c_1,y=4,default=ini_cfg.LogMode+1,options={"Append on Startup","Replace on Startup"},radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.pink}
|
||||
|
||||
TextBox{parent=log_c_1,x=1,y=7,text="Log File Path"}
|
||||
local path = TextField{parent=log_c_1,x=1,y=8,width=49,height=1,value=ini_cfg.LogPath,max_len=128,fg_bg=bw_fg_bg}
|
||||
TextBox{parent=log_c_1,y=7,text="Log File Path"}
|
||||
local path = TextField{parent=log_c_1,y=8,width=49,height=1,value=ini_cfg.LogPath,max_len=128,fg_bg=bw_fg_bg}
|
||||
|
||||
local en_dbg = Checkbox{parent=log_c_1,x=1,y=10,default=ini_cfg.LogDebug,label="Enable Logging Debug Messages",box_fg_bg=cpair(colors.pink,colors.black)}
|
||||
local en_dbg = Checkbox{parent=log_c_1,y=10,default=ini_cfg.LogDebug,label="Enable Logging Debug Messages",box_fg_bg=cpair(colors.pink,colors.black)}
|
||||
TextBox{parent=log_c_1,x=3,y=11,height=2,text="This results in much larger log files. It is best to only use this when there is a problem.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
local path_err = TextBox{parent=log_c_1,x=8,y=14,width=35,text="Please provide a log file path.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
|
||||
@@ -342,7 +342,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
else path_err.show() end
|
||||
end
|
||||
|
||||
PushButton{parent=log_c_1,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=log_c_1,y=14,text="\x1b Back",callback=function()main_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=log_c_1,x=44,y=14,text="Next \x1a",callback=submit_log,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -354,17 +354,17 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
local clr_c_3 = Div{parent=clr_cfg,x=2,y=4,width=49}
|
||||
local clr_c_4 = Div{parent=clr_cfg,x=2,y=4,width=49}
|
||||
|
||||
local clr_pane = MultiPane{parent=clr_cfg,x=1,y=4,panes={clr_c_1,clr_c_2,clr_c_3,clr_c_4}}
|
||||
local clr_pane = MultiPane{parent=clr_cfg,y=4,panes={clr_c_1,clr_c_2,clr_c_3,clr_c_4}}
|
||||
|
||||
TextBox{parent=clr_cfg,x=1,y=2,text=" Color Configuration",fg_bg=cpair(colors.black,colors.magenta)}
|
||||
TextBox{parent=clr_cfg,y=2,text=" Color Configuration",fg_bg=cpair(colors.black,colors.magenta)}
|
||||
|
||||
TextBox{parent=clr_c_1,x=1,y=1,height=2,text="Here you can select the color theme for the front panel."}
|
||||
TextBox{parent=clr_c_1,x=1,y=4,height=2,text="Click 'Accessibility' below to access colorblind assistive options.",fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=clr_c_1,y=1,height=2,text="Here you can select the color theme for the front panel."}
|
||||
TextBox{parent=clr_c_1,y=4,height=2,text="Click 'Accessibility' below to access colorblind assistive options.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
TextBox{parent=clr_c_1,x=1,y=7,text="Front Panel Theme"}
|
||||
local fp_theme = RadioButton{parent=clr_c_1,x=1,y=8,default=ini_cfg.FrontPanelTheme,options=themes.FP_THEME_NAMES,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||
TextBox{parent=clr_c_1,y=7,text="Front Panel Theme"}
|
||||
local fp_theme = RadioButton{parent=clr_c_1,y=8,default=ini_cfg.FrontPanelTheme,options=themes.FP_THEME_NAMES,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||
|
||||
TextBox{parent=clr_c_2,x=1,y=1,height=6,text="This system uses color heavily to distinguish ok and not, with some indicators using many colors. By selecting a mode below, indicators will change as shown. For non-standard modes, indicators with more than two colors will be split up."}
|
||||
TextBox{parent=clr_c_2,y=1,height=6,text="This system uses color heavily to distinguish ok and not, with some indicators using many colors. By selecting a mode below, indicators will change as shown. For non-standard modes, indicators with more than two colors will be split up."}
|
||||
|
||||
TextBox{parent=clr_c_2,x=21,y=7,text="Preview"}
|
||||
local _ = IndLight{parent=clr_c_2,x=21,y=8,label="Good",colors=cpair(colors.black,colors.green)}
|
||||
@@ -393,8 +393,8 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
end
|
||||
end
|
||||
|
||||
TextBox{parent=clr_c_2,x=1,y=7,width=10,text="Color Mode"}
|
||||
local c_mode = RadioButton{parent=clr_c_2,x=1,y=8,default=ini_cfg.ColorMode,options=themes.COLOR_MODE_NAMES,callback=recolor,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||
TextBox{parent=clr_c_2,y=7,width=10,text="Color Mode"}
|
||||
local c_mode = RadioButton{parent=clr_c_2,y=8,default=ini_cfg.ColorMode,options=themes.COLOR_MODE_NAMES,callback=recolor,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||
|
||||
TextBox{parent=clr_c_2,x=21,y=13,height=2,width=18,text="Note: exact color varies by theme.",fg_bg=g_lg_fg_bg}
|
||||
|
||||
@@ -435,7 +435,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=clr_c_1,x=1,y=14,text="\x1b Back",callback=back_from_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=clr_c_1,y=14,text="\x1b Back",callback=back_from_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=clr_c_1,x=8,y=14,min_width=15,text="Accessibility",callback=show_access,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
tool_ctl.color_next = PushButton{parent=clr_c_1,x=44,y=14,text="Next \x1a",callback=submit_colors,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
tool_ctl.color_apply = PushButton{parent=clr_c_1,x=43,y=14,min_width=7,text="Apply",callback=submit_colors,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg}
|
||||
@@ -447,12 +447,12 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
clr_pane.set_value(1)
|
||||
end
|
||||
|
||||
TextBox{parent=clr_c_3,x=1,y=1,text="Settings saved!"}
|
||||
PushButton{parent=clr_c_3,x=1,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
TextBox{parent=clr_c_3,y=1,text="Settings saved!"}
|
||||
PushButton{parent=clr_c_3,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
PushButton{parent=clr_c_3,x=44,y=14,min_width=6,text="Home",callback=c_go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=clr_c_4,x=1,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=clr_c_4,x=1,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
TextBox{parent=clr_c_4,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=clr_c_4,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
PushButton{parent=clr_c_4,x=44,y=14,min_width=6,text="Home",callback=c_go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
@@ -464,11 +464,11 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
local sum_c_3 = Div{parent=summary,x=2,y=4,width=49}
|
||||
local sum_c_4 = Div{parent=summary,x=2,y=4,width=49}
|
||||
|
||||
local sum_pane = MultiPane{parent=summary,x=1,y=4,panes={sum_c_1,sum_c_2,sum_c_3,sum_c_4}}
|
||||
local sum_pane = MultiPane{parent=summary,y=4,panes={sum_c_1,sum_c_2,sum_c_3,sum_c_4}}
|
||||
|
||||
TextBox{parent=summary,x=1,y=2,text=" Summary",fg_bg=cpair(colors.black,colors.green)}
|
||||
TextBox{parent=summary,y=2,text=" Summary",fg_bg=cpair(colors.black,colors.green)}
|
||||
|
||||
local setting_list = ListBox{parent=sum_c_1,x=1,y=1,height=12,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
local setting_list = ListBox{parent=sum_c_1,y=1,height=12,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
local function back_from_settings()
|
||||
if tool_ctl.viewing_config or self.importing_legacy then
|
||||
@@ -564,11 +564,11 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=sum_c_1,x=1,y=14,text="\x1b Back",callback=back_from_settings,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_1,y=14,text="\x1b Back",callback=back_from_settings,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
self.show_key_btn = PushButton{parent=sum_c_1,x=8,y=14,min_width=17,text="Unhide Auth Key",callback=function()self.show_auth_key()end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg,dis_fg_bg=btn_dis_fg_bg}
|
||||
tool_ctl.settings_apply = PushButton{parent=sum_c_1,x=43,y=14,min_width=7,text="Apply",callback=save_and_continue,fg_bg=cpair(colors.black,colors.green),active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
TextBox{parent=sum_c_2,x=1,y=1,text="Settings saved!"}
|
||||
TextBox{parent=sum_c_2,y=1,text="Settings saved!"}
|
||||
|
||||
local function go_home()
|
||||
main_pane.set_value(1)
|
||||
@@ -578,21 +578,21 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
sum_pane.set_value(1)
|
||||
end
|
||||
|
||||
PushButton{parent=sum_c_2,x=1,y=14,min_width=6,text="Home",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_2,y=14,min_width=6,text="Home",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_2,x=44,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
|
||||
TextBox{parent=sum_c_3,x=1,y=1,height=2,text="The old config.lua file will now be deleted, then the configurator will exit."}
|
||||
TextBox{parent=sum_c_3,y=1,height=2,text="The old config.lua file will now be deleted, then the configurator will exit."}
|
||||
|
||||
local function delete_legacy()
|
||||
fs.delete("/supervisor/config.lua")
|
||||
exit()
|
||||
end
|
||||
|
||||
PushButton{parent=sum_c_3,x=1,y=14,min_width=8,text="Cancel",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_3,y=14,min_width=8,text="Cancel",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_3,x=44,y=14,min_width=6,text="OK",callback=delete_legacy,fg_bg=cpair(colors.black,colors.green),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
|
||||
TextBox{parent=sum_c_4,x=1,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=sum_c_4,x=1,y=14,min_width=6,text="Home",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
TextBox{parent=sum_c_4,y=1,height=5,text="Failed to save the settings file.\n\nThere may not be enough space for the modification or server file permissions may be denying writes."}
|
||||
PushButton{parent=sum_c_4,y=14,min_width=6,text="Home",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=sum_c_4,x=44,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
|
||||
--#endregion
|
||||
@@ -601,12 +601,12 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
|
||||
local i_err = Div{parent=import_err,x=2,y=4,width=49}
|
||||
|
||||
TextBox{parent=import_err,x=1,y=2,text=" Import Error",fg_bg=cpair(colors.black,colors.red)}
|
||||
TextBox{parent=i_err,x=1,y=1,text="There is a problem with your config.lua file:"}
|
||||
TextBox{parent=import_err,y=2,text=" Import Error",fg_bg=cpair(colors.black,colors.red)}
|
||||
TextBox{parent=i_err,y=1,text="There is a problem with your config.lua file:"}
|
||||
|
||||
local import_err_msg = TextBox{parent=i_err,x=1,y=3,height=6,text=""}
|
||||
local import_err_msg = TextBox{parent=i_err,y=3,height=6,text=""}
|
||||
|
||||
PushButton{parent=i_err,x=1,y=14,min_width=6,text="Home",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=i_err,y=14,min_width=6,text="Home",callback=go_home,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=i_err,x=44,y=14,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.white,colors.gray)}
|
||||
|
||||
--#endregion
|
||||
@@ -870,7 +870,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
|
||||
local textbox
|
||||
if height > 1 then
|
||||
textbox = TextBox{parent=line,x=1,y=2,text=val,height=height-1}
|
||||
textbox = TextBox{parent=line,y=2,text=val,height=height-1}
|
||||
else
|
||||
textbox = TextBox{parent=line,x=label_w+1,y=1,text=val,alignment=RIGHT}
|
||||
end
|
||||
@@ -900,19 +900,19 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
end
|
||||
|
||||
if missing.tmp and tmp_cfg.WiredModem then
|
||||
local line = Div{parent=modem_list,x=1,y=1,height=1}
|
||||
local line = Div{parent=modem_list,y=1,height=1}
|
||||
|
||||
TextBox{parent=line,x=1,y=1,width=4,text="Used",fg_bg=cpair(tri(enable,colors.blue,colors.gray),colors.white)}
|
||||
TextBox{parent=line,y=1,width=4,text="Used",fg_bg=cpair(tri(enable,colors.blue,colors.gray),colors.white)}
|
||||
PushButton{parent=line,x=6,y=1,min_width=8,height=1,text="SELECT",callback=function()end,fg_bg=cpair(colors.black,colors.lightBlue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=g_lg_fg_bg}.disable()
|
||||
TextBox{parent=line,x=15,y=1,text="[missing]",fg_bg=cpair(colors.red,colors.white)}
|
||||
TextBox{parent=line,x=25,y=1,text=tmp_cfg.WiredModem}
|
||||
end
|
||||
|
||||
if missing.ini and ini_cfg.WiredModem and (tmp_cfg.WiredModem ~= ini_cfg.WiredModem) then
|
||||
local line = Div{parent=modem_list,x=1,y=1,height=1}
|
||||
local line = Div{parent=modem_list,y=1,height=1}
|
||||
local used = tmp_cfg.WiredModem == ini_cfg.WiredModem
|
||||
|
||||
TextBox{parent=line,x=1,y=1,width=4,text=tri(used,"Used","----"),fg_bg=cpair(tri(used and enable,colors.blue,colors.gray),colors.white)}
|
||||
TextBox{parent=line,y=1,width=4,text=tri(used,"Used","----"),fg_bg=cpair(tri(used and enable,colors.blue,colors.gray),colors.white)}
|
||||
local select_btn = PushButton{parent=line,x=6,y=1,min_width=8,height=1,text="SELECT",callback=function()select(ini_cfg.WiredModem)end,fg_bg=cpair(colors.black,colors.lightBlue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=line,x=15,y=1,text="[missing]",fg_bg=cpair(colors.red,colors.white)}
|
||||
TextBox{parent=line,x=25,y=1,text=ini_cfg.WiredModem}
|
||||
@@ -922,10 +922,10 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, fac_pane, style, exit
|
||||
|
||||
-- list wired modems
|
||||
for iface, _ in pairs(modems) do
|
||||
local line = Div{parent=modem_list,x=1,y=1,height=1}
|
||||
local line = Div{parent=modem_list,y=1,height=1}
|
||||
local used = tmp_cfg.WiredModem == iface
|
||||
|
||||
TextBox{parent=line,x=1,y=1,width=4,text=tri(used,"Used","----"),fg_bg=cpair(tri(used and enable,colors.blue,colors.gray),colors.white)}
|
||||
TextBox{parent=line,y=1,width=4,text=tri(used,"Used","----"),fg_bg=cpair(tri(used and enable,colors.blue,colors.gray),colors.white)}
|
||||
local select_btn = PushButton{parent=line,x=6,y=1,min_width=8,height=1,text="SELECT",callback=function()select(iface)end,fg_bg=cpair(colors.black,colors.lightBlue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=g_lg_fg_bg}
|
||||
TextBox{parent=line,x=15,y=1,text=iface}
|
||||
|
||||
|
||||
@@ -186,18 +186,18 @@ local function config_view(display)
|
||||
|
||||
TextBox{parent=display,y=1,text="Supervisor Configurator",alignment=CENTER,fg_bg=style.header}
|
||||
|
||||
local root_pane_div = Div{parent=display,x=1,y=2}
|
||||
local root_pane_div = Div{parent=display,y=2}
|
||||
|
||||
local main_page = Div{parent=root_pane_div,x=1,y=1}
|
||||
local fac_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local net_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local log_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local clr_cfg = Div{parent=root_pane_div,x=1,y=1}
|
||||
local summary = Div{parent=root_pane_div,x=1,y=1}
|
||||
local changelog = Div{parent=root_pane_div,x=1,y=1}
|
||||
local import_err = Div{parent=root_pane_div,x=1,y=1}
|
||||
local main_page = Div{parent=root_pane_div,y=1}
|
||||
local fac_cfg = Div{parent=root_pane_div,y=1}
|
||||
local net_cfg = Div{parent=root_pane_div,y=1}
|
||||
local log_cfg = Div{parent=root_pane_div,y=1}
|
||||
local clr_cfg = Div{parent=root_pane_div,y=1}
|
||||
local summary = Div{parent=root_pane_div,y=1}
|
||||
local changelog = Div{parent=root_pane_div,y=1}
|
||||
local import_err = Div{parent=root_pane_div,y=1}
|
||||
|
||||
local main_pane = MultiPane{parent=root_pane_div,x=1,y=1,panes={main_page,fac_cfg,net_cfg,log_cfg,clr_cfg,summary,changelog,import_err}}
|
||||
local main_pane = MultiPane{parent=root_pane_div,y=1,panes={main_page,fac_cfg,net_cfg,log_cfg,clr_cfg,summary,changelog,import_err}}
|
||||
|
||||
--#region Main Page
|
||||
|
||||
@@ -271,20 +271,20 @@ local function config_view(display)
|
||||
|
||||
local cl = Div{parent=changelog,x=2,y=4,width=49}
|
||||
|
||||
TextBox{parent=changelog,x=1,y=2,text=" Config Change Log",fg_bg=bw_fg_bg}
|
||||
TextBox{parent=changelog,y=2,text=" Config Change Log",fg_bg=bw_fg_bg}
|
||||
|
||||
local c_log = ListBox{parent=cl,x=1,y=1,height=12,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
local c_log = ListBox{parent=cl,y=1,height=12,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
|
||||
|
||||
for _, change in ipairs(changes) do
|
||||
TextBox{parent=c_log,text=change[1],fg_bg=bw_fg_bg}
|
||||
for _, v in ipairs(change[2]) do
|
||||
local e = Div{parent=c_log,height=#util.strwrap(v,46)}
|
||||
TextBox{parent=e,y=1,x=1,text="- ",fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=e,y=1,text="- ",fg_bg=cpair(colors.gray,colors.white)}
|
||||
TextBox{parent=e,y=1,x=3,text=v,height=e.get_height(),fg_bg=cpair(colors.gray,colors.white)}
|
||||
end
|
||||
end
|
||||
|
||||
PushButton{parent=cl,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
PushButton{parent=cl,y=14,text="\x1b Back",callback=function()main_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||
|
||||
--#endregion
|
||||
end
|
||||
|
||||
@@ -94,9 +94,13 @@ function facility.new(config)
|
||||
mode_set = PROCESS.MAX_BURN, ---@type PROCESS
|
||||
start_fail = START_STATUS.OK, ---@type START_STATUS
|
||||
max_burn_combined = 0.0, -- maximum burn rate to clamp at
|
||||
burn_target = 0.1, -- burn rate target for aggregate burn mode
|
||||
charge_setpoint = 0, -- FE charge target setpoint
|
||||
gen_rate_setpoint = 0, -- FE/t charge rate target setpoint
|
||||
sp = {
|
||||
burn_target = 0.1, -- burn rate target for aggregate burn mode
|
||||
range_start = 10, -- start threshold for range control
|
||||
range_stop = 90, -- stop threshold for range control
|
||||
charge_setpoint = 0, -- FE charge target setpoint
|
||||
gen_rate_setpoint = 0 -- FE/t charge rate target setpoint
|
||||
},
|
||||
group_map = {}, ---@type AUTO_GROUP[] units -> group IDs
|
||||
prio_defs = { {}, {}, {}, {} }, ---@type reactor_unit[][] priority definitions (each level is a table of units)
|
||||
at_max_burn = false,
|
||||
@@ -116,6 +120,7 @@ function facility.new(config)
|
||||
initial_ramp = true,
|
||||
waiting_on_ramp = false, -- waiting on auto ramping
|
||||
waiting_on_stable = false, -- waiting on gen rate stabilization
|
||||
range_control_en = false,
|
||||
accumulator = 0.0,
|
||||
saturated = false,
|
||||
last_update = 0,
|
||||
@@ -135,6 +140,7 @@ function facility.new(config)
|
||||
test_alarm_states = {}, ---@type { [ALARM]: boolean }
|
||||
-- statistics
|
||||
im_stat_init = false,
|
||||
imtx_percent = 0.0,
|
||||
avg_charge = util.mov_avg(3), -- 3 seconds
|
||||
avg_inflow = util.mov_avg(6), -- 3 seconds
|
||||
avg_outflow = util.mov_avg(6), -- 3 seconds
|
||||
@@ -207,21 +213,31 @@ function facility.new(config)
|
||||
|
||||
-- only allow changes if not running
|
||||
if self.mode == PROCESS.INACTIVE then
|
||||
if (type(auto_cfg.mode) == "number") and (auto_cfg.mode > PROCESS.INACTIVE) and (auto_cfg.mode <= PROCESS.GEN_RATE) then
|
||||
if (type(auto_cfg.mode) == "number") and (auto_cfg.mode > PROCESS.INACTIVE) and (auto_cfg.mode <= PROCESS.RANGE_CONTROL) then
|
||||
self.mode_set = auto_cfg.mode
|
||||
end
|
||||
|
||||
ready = self.mode_set > 0
|
||||
|
||||
if (type(auto_cfg.burn_target) == "number") and auto_cfg.burn_target >= 0.1 then
|
||||
self.burn_target = auto_cfg.burn_target
|
||||
end
|
||||
self.sp.burn_target = auto_cfg.burn_target
|
||||
elseif self.mode_set == PROCESS.BURN_RATE then ready = false end
|
||||
|
||||
if (type(auto_cfg.range_start) == "number") and (auto_cfg.range_start >= 0) and (auto_cfg.range_start < 100) then
|
||||
self.sp.range_start = auto_cfg.range_start
|
||||
elseif self.mode_set == PROCESS.RANGE_CONTROL then ready = false end
|
||||
|
||||
if (type(auto_cfg.range_stop) == "number") and (auto_cfg.range_stop <= 100) and (auto_cfg.range_stop > auto_cfg.range_start) then
|
||||
self.sp.range_stop = auto_cfg.range_stop
|
||||
elseif self.mode_set == PROCESS.RANGE_CONTROL then ready = false end
|
||||
|
||||
if (type(auto_cfg.charge_target) == "number") and auto_cfg.charge_target >= 0 then
|
||||
self.charge_setpoint = auto_cfg.charge_target * CHARGE_SCALER
|
||||
end
|
||||
self.sp.charge_setpoint = auto_cfg.charge_target * CHARGE_SCALER
|
||||
elseif self.mode_set == PROCESS.CHARGE then ready = false end
|
||||
|
||||
if (type(auto_cfg.gen_target) == "number") and auto_cfg.gen_target >= 0 then
|
||||
self.gen_rate_setpoint = auto_cfg.gen_target * GEN_SCALER
|
||||
end
|
||||
self.sp.gen_rate_setpoint = auto_cfg.gen_target * GEN_SCALER
|
||||
elseif self.mode_set == PROCESS.GEN_RATE then ready = false end
|
||||
|
||||
if (type(auto_cfg.limits) == "table") and (#auto_cfg.limits == config.UnitCount) then
|
||||
for i = 1, config.UnitCount do
|
||||
@@ -233,14 +249,6 @@ function facility.new(config)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ready = self.mode_set > 0
|
||||
|
||||
if ((self.mode_set == PROCESS.CHARGE) and (self.charge_setpoint <= 0)) or
|
||||
((self.mode_set == PROCESS.GEN_RATE) and (self.gen_rate_setpoint <= 0)) or
|
||||
((self.mode_set == PROCESS.BURN_RATE) and (self.burn_target < 0.1)) then
|
||||
ready = false
|
||||
end
|
||||
end
|
||||
|
||||
return ready, limits
|
||||
@@ -455,9 +463,11 @@ function facility.new(config)
|
||||
return {
|
||||
ready,
|
||||
self.mode_set,
|
||||
self.burn_target,
|
||||
self.charge_setpoint / CHARGE_SCALER,
|
||||
self.gen_rate_setpoint / GEN_SCALER,
|
||||
self.sp.burn_target,
|
||||
self.sp.range_start,
|
||||
self.sp.range_stop,
|
||||
self.sp.charge_setpoint / CHARGE_SCALER,
|
||||
self.sp.gen_rate_setpoint / GEN_SCALER,
|
||||
limits
|
||||
}
|
||||
end
|
||||
|
||||
@@ -230,6 +230,8 @@ function update.pre_auto()
|
||||
local input = util.joules_to_fe_rf(db.state.last_input)
|
||||
local output = util.joules_to_fe_rf(db.state.last_output)
|
||||
|
||||
self.imtx_percent = db.tanks.energy_fill * 100
|
||||
|
||||
if self.im_stat_init then
|
||||
self.avg_charge.record(energy, charge_update)
|
||||
self.avg_inflow.record(input, rate_update)
|
||||
@@ -431,8 +433,42 @@ function update.auto_control(ExtChargeIdling)
|
||||
end
|
||||
end
|
||||
|
||||
local unallocated = allocate_burn_rate(self.burn_target, true)
|
||||
self.saturated = self.burn_target == self.max_burn_combined or unallocated > 0
|
||||
local unallocated = allocate_burn_rate(self.sp.burn_target, true)
|
||||
self.saturated = self.sp.burn_target == self.max_burn_combined or unallocated > 0
|
||||
elseif self.mode == PROCESS.RANGE_CONTROL then
|
||||
-- run units at their limits if within the enable range
|
||||
if state_changed then
|
||||
self.time_start = now
|
||||
self.waiting_on_ramp = false
|
||||
self.range_control_en = false
|
||||
|
||||
self.status_text = { "RANGE CONTROL", "idle, sufficient charge" }
|
||||
log.info("FAC: RANGE_CONTROL process mode started")
|
||||
elseif self.range_control_en and (self.imtx_percent >= self.sp.range_stop) then
|
||||
self.range_control_en = false
|
||||
self.waiting_on_ramp = false
|
||||
|
||||
self.status_text = { "RANGE CONTROL", "stopped, sufficient charge" }
|
||||
log.info("FAC: RANGE_CONTROL process mode started")
|
||||
elseif (not self.range_control_en) and (self.imtx_percent <= self.sp.range_start) then
|
||||
self.range_control_en = true
|
||||
self.waiting_on_ramp = true
|
||||
|
||||
self.status_text = { "RANGE CONTROL", "ramping reactors to limit" }
|
||||
log.info("FAC: CONTROL process mode ramp completed")
|
||||
elseif self.waiting_on_ramp then
|
||||
if all_units_ramped() then
|
||||
self.waiting_on_ramp = false
|
||||
|
||||
self.status_text = { "RANGE CONTROL", "running reactors at limit" }
|
||||
log.info("FAC: CONTROL process mode ramp completed")
|
||||
end
|
||||
end
|
||||
|
||||
local burn_rate = util.trinary(self.range_control_en, self.max_burn_combined, 0)
|
||||
local unallocated = allocate_burn_rate(burn_rate, true)
|
||||
|
||||
self.saturated = burn_rate == self.max_burn_combined or unallocated > 0
|
||||
elseif self.mode == PROCESS.CHARGE then
|
||||
-- target a level of charge
|
||||
if state_changed then
|
||||
@@ -448,7 +484,7 @@ function update.auto_control(ExtChargeIdling)
|
||||
log.info("FAC: CHARGE mode starting PID control")
|
||||
elseif self.last_update < charge_update then
|
||||
-- convert to kFE to make constants not microscopic
|
||||
local error = util.round((self.charge_setpoint - avg_charge) / 1000) / 1000
|
||||
local error = util.round((self.sp.charge_setpoint - avg_charge) / 1000) / 1000
|
||||
|
||||
-- stop accumulator when saturated to avoid windup
|
||||
if not self.saturated then
|
||||
@@ -489,7 +525,7 @@ function update.auto_control(ExtChargeIdling)
|
||||
-- target a rate of generation
|
||||
if state_changed then
|
||||
-- estimate an initial output
|
||||
local output = self.gen_rate_setpoint / self.charge_conversion
|
||||
local output = self.sp.gen_rate_setpoint / self.charge_conversion
|
||||
|
||||
local unallocated = allocate_burn_rate(output, true)
|
||||
|
||||
@@ -522,7 +558,7 @@ function update.auto_control(ExtChargeIdling)
|
||||
end
|
||||
elseif self.last_update < rate_update then
|
||||
-- convert to MFE (in rounded kFE) to make constants not microscopic
|
||||
local error = util.round((self.gen_rate_setpoint - avg_inflow) / 1000) / 1000
|
||||
local error = util.round((self.sp.gen_rate_setpoint - avg_inflow) / 1000) / 1000
|
||||
|
||||
-- stop accumulator when saturated to avoid windup
|
||||
if not self.saturated then
|
||||
@@ -538,7 +574,7 @@ function update.auto_control(ExtChargeIdling)
|
||||
local D = RATE_Kd * derivative
|
||||
|
||||
-- velocity (rate) (derivative of charge level => rate) feed forward
|
||||
local FF = self.gen_rate_setpoint / self.charge_conversion
|
||||
local FF = self.sp.gen_rate_setpoint / self.charge_conversion
|
||||
|
||||
local output = P + I + D + FF
|
||||
|
||||
|
||||
@@ -33,9 +33,9 @@ local function init(parent, id)
|
||||
|
||||
local ps_prefix = "pdg_" .. id .. "_"
|
||||
|
||||
TextBox{parent=entry,x=1,y=1,text="",width=8,fg_bg=s_hi_box}
|
||||
local pdg_addr = TextBox{parent=entry,x=1,y=2,text="@ C ??",alignment=ALIGN.CENTER,width=8,fg_bg=s_hi_box,nav_active=cpair(colors.gray,colors.black)}
|
||||
TextBox{parent=entry,x=1,y=3,text="",width=8,fg_bg=s_hi_box}
|
||||
TextBox{parent=entry,y=1,text="",width=8,fg_bg=s_hi_box}
|
||||
local pdg_addr = TextBox{parent=entry,y=2,text="@ C ??",alignment=ALIGN.CENTER,width=8,fg_bg=s_hi_box,nav_active=cpair(colors.gray,colors.black)}
|
||||
TextBox{parent=entry,y=3,text="",width=8,fg_bg=s_hi_box}
|
||||
pdg_addr.register(databus.ps, ps_prefix .. "addr", pdg_addr.set_value)
|
||||
|
||||
TextBox{parent=entry,x=10,y=2,text="FW:",width=3}
|
||||
|
||||
@@ -33,9 +33,9 @@ local function init(parent, id)
|
||||
|
||||
local ps_prefix = "rtu_" .. id .. "_"
|
||||
|
||||
TextBox{parent=entry,x=1,y=1,text="",width=8,fg_bg=s_hi_box}
|
||||
local rtu_addr = TextBox{parent=entry,x=1,y=2,text="@ C ??",alignment=ALIGN.CENTER,width=8,fg_bg=s_hi_box,nav_active=cpair(colors.gray,colors.black)}
|
||||
TextBox{parent=entry,x=1,y=3,text="",width=8,fg_bg=s_hi_box}
|
||||
TextBox{parent=entry,y=1,text="",width=8,fg_bg=s_hi_box}
|
||||
local rtu_addr = TextBox{parent=entry,y=2,text="@ C ??",alignment=ALIGN.CENTER,width=8,fg_bg=s_hi_box,nav_active=cpair(colors.gray,colors.black)}
|
||||
TextBox{parent=entry,y=3,text="",width=8,fg_bg=s_hi_box}
|
||||
rtu_addr.register(databus.ps, ps_prefix .. "addr", rtu_addr.set_value)
|
||||
|
||||
TextBox{parent=entry,x=10,y=2,text="UNITS:",width=7}
|
||||
|
||||
@@ -48,13 +48,13 @@ local function init(panel, config)
|
||||
|
||||
TextBox{parent=panel,y=1,text="SCADA SUPERVISOR",alignment=ALIGN.CENTER,fg_bg=style.theme.header}
|
||||
|
||||
local page_div = Div{parent=panel,x=1,y=3}
|
||||
local page_div = Div{parent=panel,y=3}
|
||||
|
||||
--
|
||||
-- system indicators
|
||||
--
|
||||
|
||||
local main_page = Div{parent=page_div,x=1,y=1}
|
||||
local main_page = Div{parent=page_div,y=1}
|
||||
|
||||
local system = Div{parent=main_page,width=18,height=17,x=2,y=2}
|
||||
|
||||
@@ -94,16 +94,16 @@ local function init(panel, config)
|
||||
|
||||
-- plc sessions page
|
||||
|
||||
local plc_page = Div{parent=page_div,x=1,y=1,hidden=true}
|
||||
local plc_page = Div{parent=page_div,y=1,hidden=true}
|
||||
local plc_list = Div{parent=plc_page,x=2,y=2,width=term_w-2}
|
||||
|
||||
for i = 1, supervisor.config.UnitCount do
|
||||
local ps_prefix = "plc_" .. i .. "_"
|
||||
local plc_entry = Div{parent=plc_list,height=3,fg_bg=s_hi_bright}
|
||||
|
||||
TextBox{parent=plc_entry,x=1,y=1,text="",width=8,fg_bg=s_hi_box}
|
||||
TextBox{parent=plc_entry,x=1,y=2,text="UNIT "..i,alignment=ALIGN.CENTER,width=8,fg_bg=s_hi_box}
|
||||
TextBox{parent=plc_entry,x=1,y=3,text="",width=8,fg_bg=s_hi_box}
|
||||
TextBox{parent=plc_entry,y=1,text="",width=8,fg_bg=s_hi_box}
|
||||
TextBox{parent=plc_entry,y=2,text="UNIT "..i,alignment=ALIGN.CENTER,width=8,fg_bg=s_hi_box}
|
||||
TextBox{parent=plc_entry,y=3,text="",width=8,fg_bg=s_hi_box}
|
||||
|
||||
local conn = LED{parent=plc_entry,x=10,y=2,label="LINK",colors=cpair(colors.green_hc,colors.green_off)}
|
||||
conn.register(databus.ps, ps_prefix .. "conn", conn.update)
|
||||
@@ -126,13 +126,13 @@ local function init(panel, config)
|
||||
|
||||
-- rtu sessions page
|
||||
|
||||
local rtu_page = Div{parent=page_div,x=1,y=1,hidden=true}
|
||||
local rtu_page = Div{parent=page_div,y=1,hidden=true}
|
||||
local rtu_list = ListBox{parent=rtu_page,y=1,height=term_h-2,width=term_w,scroll_height=1000,fg_bg=cpair(colors.black,colors.ivory),nav_fg_bg=cpair(colors.gray,colors.lightGray),nav_active=cpair(colors.black,colors.gray)}
|
||||
local _ = Div{parent=rtu_list,height=1} -- padding
|
||||
|
||||
-- coordinator session page
|
||||
|
||||
local crd_page = Div{parent=page_div,x=1,y=1,hidden=true}
|
||||
local crd_page = Div{parent=page_div,y=1,hidden=true}
|
||||
local crd_box = Div{parent=crd_page,x=2,y=2,width=term_w-2,height=4,fg_bg=s_hi_bright}
|
||||
|
||||
local crd_conn = LED{parent=crd_box,x=2,y=2,label="CONNECTION",colors=cpair(colors.green_hc,colors.green_off)}
|
||||
@@ -184,7 +184,7 @@ local function init(panel, config)
|
||||
|
||||
local panes = { main_page, plc_page, rtu_page, crd_page, pkt_page, chk_page, info_page }
|
||||
|
||||
local page_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes}
|
||||
local page_pane = MultiPane{parent=page_div,y=1,panes=panes}
|
||||
|
||||
local tabs = {
|
||||
{ name = "SVR", color = style.fp.text },
|
||||
|
||||
@@ -243,9 +243,11 @@ function coordinator.new_session(id, s_addr, i_seq_num, in_queue, out_queue, tim
|
||||
local config = {
|
||||
mode = pkt.data[1],
|
||||
burn_target = pkt.data[2],
|
||||
charge_target = pkt.data[3],
|
||||
gen_target = pkt.data[4],
|
||||
limits = pkt.data[5]
|
||||
range_start = pkt.data[3],
|
||||
range_stop = pkt.data[4],
|
||||
charge_target = pkt.data[5],
|
||||
gen_target = pkt.data[6],
|
||||
limits = pkt.data[7]
|
||||
}
|
||||
|
||||
facility.boot_recovery_start(config)
|
||||
@@ -276,14 +278,16 @@ function coordinator.new_session(id, s_addr, i_seq_num, in_queue, out_queue, tim
|
||||
elseif cmd == FAC_COMMAND.START then
|
||||
facility.cancel_recovery()
|
||||
|
||||
if pkt.length == 6 then
|
||||
if pkt.length == 8 then
|
||||
---@class start_auto_config
|
||||
local config = {
|
||||
mode = pkt.data[2], ---@type PROCESS
|
||||
burn_target = pkt.data[3], ---@type number
|
||||
charge_target = pkt.data[4], ---@type number
|
||||
gen_target = pkt.data[5], ---@type number
|
||||
limits = pkt.data[6] ---@type number[]
|
||||
range_start = pkt.data[4], ---@type integer
|
||||
range_stop = pkt.data[5], ---@type integer
|
||||
charge_target = pkt.data[6], ---@type number
|
||||
gen_target = pkt.data[7], ---@type number
|
||||
limits = pkt.data[8] ---@type number[]
|
||||
}
|
||||
|
||||
_send(CRDN_TYPE.FAC_CMD, { cmd, table.unpack(facility.auto_start(config)) })
|
||||
|
||||
@@ -174,6 +174,7 @@ end
|
||||
-- check if a watchdog timer event matches that of one of the provided sessions
|
||||
---@param sessions sv_session_structs[]
|
||||
---@param timer_event number
|
||||
---@return boolean was_watchdog if this event was one of the watchdogs
|
||||
local function _check_watchdogs(sessions, timer_event)
|
||||
for i = 1, #sessions do
|
||||
local session = sessions[i]
|
||||
@@ -182,9 +183,12 @@ local function _check_watchdogs(sessions, timer_event)
|
||||
if triggered then
|
||||
log.debug(util.c("SVS: watchdog closing session ", session, "..."))
|
||||
_shutdown(session)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- delete any closed sessions
|
||||
@@ -648,8 +652,13 @@ end
|
||||
|
||||
-- attempt to identify which session's watchdog timer fired
|
||||
---@param timer_event number
|
||||
---@return boolean was_watchdog if this event was one of the watchdogs
|
||||
function svsessions.check_all_watchdogs(timer_event)
|
||||
for _, list in pairs(self.sessions) do _check_watchdogs(list, timer_event) end
|
||||
for _, list in pairs(self.sessions) do
|
||||
if _check_watchdogs(list, timer_event) then return true end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- iterate all sessions, and update facility/unit data & process control logic
|
||||
|
||||
@@ -24,7 +24,7 @@ local supervisor = require("supervisor.supervisor")
|
||||
|
||||
local svsessions = require("supervisor.session.svsessions")
|
||||
|
||||
local SUPERVISOR_VERSION = "v1.8.7"
|
||||
local SUPERVISOR_VERSION = "v1.9.0"
|
||||
|
||||
local println = util.println
|
||||
local println_ts = util.println_ts
|
||||
@@ -150,17 +150,35 @@ local function main()
|
||||
local MAIN_CLOCK = 0.15
|
||||
local loop_clock = util.new_clock(MAIN_CLOCK)
|
||||
|
||||
-- start clock
|
||||
loop_clock.start()
|
||||
|
||||
-- halve the rate heartbeat LED flash
|
||||
local heartbeat_toggle = true
|
||||
|
||||
-- local counters = {}
|
||||
|
||||
-- main loop periodic tasks
|
||||
local function loop_tick()
|
||||
-- blink heartbeat indicator at half the main loop rate due to how quick it runs
|
||||
if heartbeat_toggle then databus.heartbeat() end
|
||||
heartbeat_toggle = not heartbeat_toggle
|
||||
|
||||
-- iterate sessions
|
||||
svsessions.iterate_all()
|
||||
|
||||
-- free any closed sessions
|
||||
svsessions.free_all_closed()
|
||||
|
||||
-- start next clock timer
|
||||
loop_clock.start()
|
||||
|
||||
-- log.debug(textutils.serialize(counters, { compact = true })); counters = {}
|
||||
end
|
||||
|
||||
-- start clock
|
||||
loop_clock.start()
|
||||
|
||||
-- init startup recovery
|
||||
sv_facility.boot_recovery_init(supervisor.boot_state)
|
||||
|
||||
-- local counters = {}
|
||||
|
||||
-- event loop
|
||||
while true do
|
||||
local event, param1, param2, param3, param4, param5 = util.pull_event()
|
||||
@@ -168,46 +186,33 @@ local function main()
|
||||
-- counters[event] = (counters[event] or 0) + 1
|
||||
|
||||
-- handle event
|
||||
if event == "peripheral_detach" then
|
||||
local type, device = ppm.handle_unmount(param1)
|
||||
if type ~= nil and device ~= nil then
|
||||
backplane.detach(param1, type, device, println_ts)
|
||||
if event == "modem_message" then
|
||||
-- got a packet
|
||||
local packet = superv_comms.parse_packet(param1, param2, param3, param4, param5)
|
||||
if packet then superv_comms.handle_packet(packet) end
|
||||
elseif event == "timer" then
|
||||
-- pass this timer event onto the right handler
|
||||
if loop_clock.is_clock(param1) then
|
||||
-- main loop tick
|
||||
loop_tick()
|
||||
elseif not svsessions.check_all_watchdogs(param1) then -- check session watchdogs
|
||||
-- notify timer callback dispatcher, no other handler claimed this event
|
||||
tcd.handle(param1)
|
||||
end
|
||||
elseif event == "mouse_click" or event == "mouse_up" or event == "mouse_drag" or event == "mouse_scroll" or
|
||||
event == "double_click" then
|
||||
-- handle a mouse event
|
||||
renderer.handle_mouse(core.events.new_mouse_event(event, param1, param2, param3))
|
||||
elseif event == "peripheral" then
|
||||
local type, device = ppm.mount(param1)
|
||||
if type ~= nil and device ~= nil then
|
||||
backplane.attach(param1, type, device, println_ts)
|
||||
end
|
||||
elseif event == "timer" and loop_clock.is_clock(param1) then
|
||||
-- main loop tick
|
||||
|
||||
if heartbeat_toggle then databus.heartbeat() end
|
||||
heartbeat_toggle = not heartbeat_toggle
|
||||
|
||||
-- iterate sessions
|
||||
svsessions.iterate_all()
|
||||
|
||||
-- free any closed sessions
|
||||
svsessions.free_all_closed()
|
||||
|
||||
-- start next clock timer
|
||||
loop_clock.start()
|
||||
|
||||
-- log.debug(textutils.serialize(counters, { compact = true })); counters = {}
|
||||
elseif event == "timer" then
|
||||
-- a non-clock timer event, check watchdogs
|
||||
svsessions.check_all_watchdogs(param1)
|
||||
|
||||
-- notify timer callback dispatcher
|
||||
tcd.handle(param1)
|
||||
elseif event == "modem_message" then
|
||||
-- got a packet
|
||||
local packet = superv_comms.parse_packet(param1, param2, param3, param4, param5)
|
||||
if packet then superv_comms.handle_packet(packet) end
|
||||
elseif event == "mouse_click" or event == "mouse_up" or event == "mouse_drag" or event == "mouse_scroll" or
|
||||
event == "double_click" then
|
||||
-- handle a mouse event
|
||||
renderer.handle_mouse(core.events.new_mouse_event(event, param1, param2, param3))
|
||||
elseif event == "peripheral_detach" then
|
||||
local type, device = ppm.handle_unmount(param1)
|
||||
if type ~= nil and device ~= nil then
|
||||
backplane.detach(param1, type, device, println_ts)
|
||||
end
|
||||
end
|
||||
|
||||
-- check for termination request
|
||||
|
||||
Reference in New Issue
Block a user