mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
Merge branch 'pocket-alpha-dev' of https://github.com/MikaylaFischler/cc-mek-scada into pocket-alpha-dev
This commit is contained in:
commit
0365ea5e8a
@ -44,7 +44,8 @@ local RIGHT = core.ALIGN.RIGHT
|
|||||||
-- changes to the config data/format to let the user know
|
-- changes to the config data/format to let the user know
|
||||||
local changes = {
|
local changes = {
|
||||||
{ "v1.2.4", { "Added temperature scale options" } },
|
{ "v1.2.4", { "Added temperature scale options" } },
|
||||||
{ "v1.2.12", { "Added main UI theme", "Added front panel UI theme", "Added color accessibility modes" } }
|
{ "v1.2.12", { "Added main UI theme", "Added front panel UI theme", "Added color accessibility modes" } },
|
||||||
|
{ "v1.3.3", { "Added standard with black off state color mode", "Added blue indicator color modes" } }
|
||||||
}
|
}
|
||||||
|
|
||||||
---@class crd_configurator
|
---@class crd_configurator
|
||||||
@ -358,7 +359,7 @@ local function config_view(display)
|
|||||||
end
|
end
|
||||||
|
|
||||||
PushButton{parent=main_page,x=2,y=17,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=btn_act_fg_bg}
|
PushButton{parent=main_page,x=2,y=17,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=btn_act_fg_bg}
|
||||||
tool_ctl.color_cfg = PushButton{parent=main_page,x=23,y=17,min_width=15,text="Color Options",callback=jump_color,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
tool_ctl.color_cfg = PushButton{parent=main_page,x=23,y=17,min_width=15,text="Color Options",callback=jump_color,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg,dis_fg_bg=cpair(colors.lightGray,colors.white)}
|
||||||
PushButton{parent=main_page,x=39,y=17,min_width=12,text="Change Log",callback=function()main_pane.set_value(10)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
PushButton{parent=main_page,x=39,y=17,min_width=12,text="Change Log",callback=function()main_pane.set_value(10)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||||
|
|
||||||
if not tool_ctl.has_config then
|
if not tool_ctl.has_config then
|
||||||
@ -824,12 +825,27 @@ local function config_view(display)
|
|||||||
TextBox{parent=clr_c_1,x=18,y=7,height=1,text="Front Panel Theme"}
|
TextBox{parent=clr_c_1,x=18,y=7,height=1,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,callback=function()end,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
local fp_theme = RadioButton{parent=clr_c_1,x=18,y=8,default=ini_cfg.FrontPanelTheme,options=themes.FP_THEME_NAMES,callback=function()end,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||||
|
|
||||||
TextBox{parent=clr_c_2,x=1,y=1,height=6,text="By default, this project uses green/red heavily to distinguish ok and not, with some indicators also using multiple colors. By selecting a color blindness below, blues will be used instead of greens on indicators and multi-color indicators will be split up as space permits."}
|
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,x=21,y=7,height=1,text="Preview"}
|
||||||
|
local _ = IndLight{parent=clr_c_2,x=21,y=8,label="Good",colors=cpair(colors.black,colors.green)}
|
||||||
|
_ = IndLight{parent=clr_c_2,x=21,y=9,label="Warning",colors=cpair(colors.black,colors.yellow)}
|
||||||
|
_ = IndLight{parent=clr_c_2,x=21,y=10,label="Bad",colors=cpair(colors.black,colors.red)}
|
||||||
|
local b_off = IndLight{parent=clr_c_2,x=21,y=11,label="Off",colors=cpair(colors.black,colors.black),hidden=true}
|
||||||
|
local g_off = IndLight{parent=clr_c_2,x=21,y=11,label="Off",colors=cpair(colors.gray,colors.gray),hidden=true}
|
||||||
|
|
||||||
local function recolor(value)
|
local function recolor(value)
|
||||||
local c = themes.smooth_stone.color_modes[value]
|
local c = themes.smooth_stone.color_modes[value]
|
||||||
|
|
||||||
if value == 1 then
|
if value == themes.COLOR_MODE.STANDARD or value == themes.COLOR_MODE.BLUE_IND then
|
||||||
|
b_off.hide()
|
||||||
|
g_off.show()
|
||||||
|
else
|
||||||
|
g_off.hide()
|
||||||
|
b_off.show()
|
||||||
|
end
|
||||||
|
|
||||||
|
if #c == 0 then
|
||||||
for i = 1, #style.colors do term.setPaletteColor(style.colors[i].c, style.colors[i].hex) end
|
for i = 1, #style.colors do term.setPaletteColor(style.colors[i].c, style.colors[i].hex) end
|
||||||
else
|
else
|
||||||
term.setPaletteColor(colors.green, c[1].hex)
|
term.setPaletteColor(colors.green, c[1].hex)
|
||||||
@ -838,15 +854,10 @@ local function config_view(display)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
TextBox{parent=clr_c_2,x=1,y=8,height=1,text="Color Mode"}
|
TextBox{parent=clr_c_2,x=1,y=7,height=1,width=10,text="Color Mode"}
|
||||||
local c_mode = RadioButton{parent=clr_c_2,x=1,y=9,default=ini_cfg.ColorMode,options=themes.COLOR_MODE_NAMES,callback=recolor,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
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,x=20,y=8,height=1,text="Preview"}
|
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}
|
||||||
local _ = IndLight{parent=clr_c_2,x=20,y=9,label="Good",colors=cpair(colors.black,colors.green)}
|
|
||||||
_ = IndLight{parent=clr_c_2,x=20,y=10,label="Warning",colors=cpair(colors.black,colors.yellow)}
|
|
||||||
_ = IndLight{parent=clr_c_2,x=20,y=11,label="Bad",colors=cpair(colors.black,colors.red)}
|
|
||||||
|
|
||||||
TextBox{parent=clr_c_2,x=1,y=14,height=6,text="Note: exact color varies by theme.",fg_bg=g_lg_fg_bg}
|
|
||||||
|
|
||||||
PushButton{parent=clr_c_2,x=44,y=14,min_width=6,text="Done",callback=function()clr_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
PushButton{parent=clr_c_2,x=44,y=14,min_width=6,text="Done",callback=function()clr_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||||
|
|
||||||
@ -1235,6 +1246,10 @@ local function config_view(display)
|
|||||||
function tool_ctl.gen_mon_list()
|
function tool_ctl.gen_mon_list()
|
||||||
mon_list.remove_all()
|
mon_list.remove_all()
|
||||||
|
|
||||||
|
local missing = { main = tmp_cfg.MainDisplay ~= nil, flow = tmp_cfg.FlowDisplay ~= nil, unit = {} }
|
||||||
|
for i = 1, tmp_cfg.UnitCount do missing.unit[i] = tmp_cfg.UnitDisplays[i] ~= nil end
|
||||||
|
|
||||||
|
-- list connected monitors
|
||||||
local monitors = ppm.get_monitor_list()
|
local monitors = ppm.get_monitor_list()
|
||||||
for iface, device in pairs(monitors) do
|
for iface, device in pairs(monitors) do
|
||||||
local dev = device.dev
|
local dev = device.dev
|
||||||
@ -1254,11 +1269,14 @@ local function config_view(display)
|
|||||||
|
|
||||||
if tmp_cfg.MainDisplay == iface then
|
if tmp_cfg.MainDisplay == iface then
|
||||||
assignment = "Main"
|
assignment = "Main"
|
||||||
|
missing.main = false
|
||||||
elseif tmp_cfg.FlowDisplay == iface then
|
elseif tmp_cfg.FlowDisplay == iface then
|
||||||
assignment = "Flow"
|
assignment = "Flow"
|
||||||
|
missing.flow = false
|
||||||
else
|
else
|
||||||
for i = 1, tmp_cfg.UnitCount do
|
for i = 1, tmp_cfg.UnitCount do
|
||||||
if tmp_cfg.UnitDisplays[i] == iface then
|
if tmp_cfg.UnitDisplays[i] == iface then
|
||||||
|
missing.unit[i] = false
|
||||||
assignment = "Unit " .. i
|
assignment = "Unit " .. i
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
@ -1283,6 +1301,31 @@ local function config_view(display)
|
|||||||
|
|
||||||
if assignment == "Unused" then unset.disable() end
|
if assignment == "Unused" then unset.disable() end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local dc_list = {} -- disconnected monitor list
|
||||||
|
|
||||||
|
if missing.main then table.insert(dc_list, { "Main", tmp_cfg.MainDisplay }) end
|
||||||
|
if missing.flow then table.insert(dc_list, { "Flow", tmp_cfg.FlowDisplay }) end
|
||||||
|
for i = 1, tmp_cfg.UnitCount do
|
||||||
|
if missing.unit[i] then table.insert(dc_list, { "Unit " .. i, tmp_cfg.UnitDisplays[i] }) end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 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}
|
||||||
|
|
||||||
|
TextBox{parent=line,x=1,y=1,width=6,height=1,text=dc_list[i][1],fg_bg=cpair(colors.blue,colors.white)}
|
||||||
|
TextBox{parent=line,x=8,y=1,height=1,text="disconnected",fg_bg=cpair(colors.red,colors.white)}
|
||||||
|
|
||||||
|
local function unset_mon()
|
||||||
|
purge_assignments(dc_list[i][2])
|
||||||
|
tool_ctl.gen_mon_list()
|
||||||
|
end
|
||||||
|
|
||||||
|
TextBox{parent=line,x=33,y=1,width=4,height=1,text="?x?",fg_bg=cpair(colors.black,colors.white)}
|
||||||
|
PushButton{parent=line,x=37,y=1,min_width=5,height=1,text="SET",callback=function()end,dis_fg_bg=cpair(colors.black,colors.gray)}.disable()
|
||||||
|
PushButton{parent=line,x=42,y=1,min_width=7,height=1,text="UNSET",callback=unset_mon,fg_bg=cpair(colors.black,colors.red),active_fg_bg=btn_act_fg_bg,dis_fg_bg=cpair(colors.black,colors.gray)}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- expose the auth key on the summary page
|
-- expose the auth key on the summary page
|
||||||
|
@ -4,6 +4,8 @@ local ppm = require("scada-common.ppm")
|
|||||||
local util = require("scada-common.util")
|
local util = require("scada-common.util")
|
||||||
local types = require("scada-common.types")
|
local types = require("scada-common.types")
|
||||||
|
|
||||||
|
local themes = require("graphics.themes")
|
||||||
|
|
||||||
local iocontrol = require("coordinator.iocontrol")
|
local iocontrol = require("coordinator.iocontrol")
|
||||||
local process = require("coordinator.process")
|
local process = require("coordinator.process")
|
||||||
|
|
||||||
@ -100,7 +102,7 @@ function coordinator.load_config()
|
|||||||
cfv.assert_type_int(config.FrontPanelTheme)
|
cfv.assert_type_int(config.FrontPanelTheme)
|
||||||
cfv.assert_range(config.FrontPanelTheme, 1, 2)
|
cfv.assert_range(config.FrontPanelTheme, 1, 2)
|
||||||
cfv.assert_type_int(config.ColorMode)
|
cfv.assert_type_int(config.ColorMode)
|
||||||
cfv.assert_range(config.ColorMode, 1, 4)
|
cfv.assert_range(config.ColorMode, 1, themes.COLOR_MODE.NUM_MODES)
|
||||||
|
|
||||||
-- Monitor Setup
|
-- Monitor Setup
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ local sounder = require("coordinator.sounder")
|
|||||||
|
|
||||||
local apisessions = require("coordinator.session.apisessions")
|
local apisessions = require("coordinator.session.apisessions")
|
||||||
|
|
||||||
local COORDINATOR_VERSION = "v1.3.0"
|
local COORDINATOR_VERSION = "v1.3.5"
|
||||||
|
|
||||||
local CHUNK_LOAD_DELAY_S = 30.0
|
local CHUNK_LOAD_DELAY_S = 30.0
|
||||||
|
|
||||||
@ -103,6 +103,7 @@ log.info("========================================")
|
|||||||
println(">> SCADA Coordinator " .. COORDINATOR_VERSION .. " <<")
|
println(">> SCADA Coordinator " .. COORDINATOR_VERSION .. " <<")
|
||||||
|
|
||||||
crash.set_env("coordinator", COORDINATOR_VERSION)
|
crash.set_env("coordinator", COORDINATOR_VERSION)
|
||||||
|
crash.dbg_log_env()
|
||||||
|
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
-- main application
|
-- main application
|
||||||
|
@ -34,7 +34,8 @@ local function new_view(root, x, y, data, ps, id)
|
|||||||
|
|
||||||
local matrix = Div{parent=root,fg_bg=style.root,width=33,height=24,x=x,y=y}
|
local matrix = Div{parent=root,fg_bg=style.root,width=33,height=24,x=x,y=y}
|
||||||
|
|
||||||
local cutout_fg_bg = cpair(style.theme.bg, colors.gray)
|
-- 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,height=1,x=1,y=1,fg_bg=cutout_fg_bg}
|
TextBox{parent=matrix,text=" ",width=33,height=1,x=1,y=1,fg_bg=cutout_fg_bg}
|
||||||
TextBox{parent=matrix,text=title,alignment=ALIGN.CENTER,width=33,height=1,x=1,y=2,fg_bg=cutout_fg_bg}
|
TextBox{parent=matrix,text=title,alignment=ALIGN.CENTER,width=33,height=1,x=1,y=2,fg_bg=cutout_fg_bg}
|
||||||
|
@ -61,12 +61,12 @@ local function init(panel, num_units)
|
|||||||
local modem = LED{parent=system,label="MODEM",colors=led_grn}
|
local modem = LED{parent=system,label="MODEM",colors=led_grn}
|
||||||
|
|
||||||
if not style.colorblind then
|
if not style.colorblind then
|
||||||
local network = RGBLED{parent=system,label="NETWORK",colors={colors.green,colors.red,colors.orange,colors.yellow,colors.gray}}
|
local network = RGBLED{parent=system,label="NETWORK",colors={colors.green,colors.red,colors.orange,colors.yellow,style.fp_ind_bkg}}
|
||||||
network.update(types.PANEL_LINK_STATE.DISCONNECTED)
|
network.update(types.PANEL_LINK_STATE.DISCONNECTED)
|
||||||
network.register(ps, "link_state", network.update)
|
network.register(ps, "link_state", network.update)
|
||||||
else
|
else
|
||||||
local nt_lnk = LEDPair{parent=system,label="NT LINKED",off=colors.red_off,c1=colors.red,c2=colors.green}
|
local nt_lnk = LEDPair{parent=system,label="NT LINKED",off=style.fp_ind_bkg,c1=colors.red,c2=colors.green}
|
||||||
local nt_ver = LEDPair{parent=system,label="NT VERSION",off=colors.red_off,c1=colors.red,c2=colors.green}
|
local nt_ver = LEDPair{parent=system,label="NT VERSION",off=style.fp_ind_bkg,c1=colors.red,c2=colors.green}
|
||||||
|
|
||||||
nt_lnk.register(ps, "link_state", function (state)
|
nt_lnk.register(ps, "link_state", function (state)
|
||||||
local value = 2
|
local value = 2
|
||||||
|
@ -88,17 +88,19 @@ style.theme = smooth_stone
|
|||||||
---@param fp FP_THEME front panel theme
|
---@param fp FP_THEME front panel theme
|
||||||
---@param color_mode COLOR_MODE the color mode to use
|
---@param color_mode COLOR_MODE the color mode to use
|
||||||
function style.set_themes(main, fp, color_mode)
|
function style.set_themes(main, fp, color_mode)
|
||||||
local colorblind = color_mode ~= themes.COLOR_MODE.STANDARD
|
local colorblind = color_mode ~= themes.COLOR_MODE.STANDARD and color_mode ~= themes.COLOR_MODE.STD_ON_BLACK
|
||||||
|
local gray_ind_off = color_mode == themes.COLOR_MODE.STANDARD or color_mode == themes.COLOR_MODE.BLUE_IND
|
||||||
|
|
||||||
style.ind_bkg = colors.gray
|
style.ind_bkg = colors.gray
|
||||||
style.ind_hi_box_bg = util.trinary(colorblind, colors.black, colors.gray)
|
style.fp_ind_bkg = util.trinary(gray_ind_off, colors.gray, colors.black)
|
||||||
|
style.ind_hi_box_bg = util.trinary(gray_ind_off, colors.gray, colors.black)
|
||||||
|
|
||||||
if main == themes.UI_THEME.SMOOTH_STONE then
|
if main == themes.UI_THEME.SMOOTH_STONE then
|
||||||
style.theme = smooth_stone
|
style.theme = smooth_stone
|
||||||
style.ind_bkg = util.trinary(colorblind, colors.black, colors.gray)
|
style.ind_bkg = util.trinary(gray_ind_off, colors.gray, colors.black)
|
||||||
elseif main == themes.UI_THEME.DEEPSLATE then
|
elseif main == themes.UI_THEME.DEEPSLATE then
|
||||||
style.theme = deepslate
|
style.theme = deepslate
|
||||||
style.ind_hi_box_bg = util.trinary(colorblind, colors.black, colors.lightGray)
|
style.ind_hi_box_bg = util.trinary(gray_ind_off, colors.lightGray, colors.black)
|
||||||
end
|
end
|
||||||
|
|
||||||
style.colorblind = colorblind
|
style.colorblind = colorblind
|
||||||
|
@ -54,14 +54,21 @@ themes.COLOR_MODE = {
|
|||||||
STANDARD = 1,
|
STANDARD = 1,
|
||||||
DEUTERANOPIA = 2,
|
DEUTERANOPIA = 2,
|
||||||
PROTANOPIA = 3,
|
PROTANOPIA = 3,
|
||||||
TRITANOPIA = 4
|
TRITANOPIA = 4,
|
||||||
|
BLUE_IND = 5,
|
||||||
|
STD_ON_BLACK = 6,
|
||||||
|
BLUE_ON_BLACK = 7,
|
||||||
|
NUM_MODES = 8
|
||||||
}
|
}
|
||||||
|
|
||||||
themes.COLOR_MODE_NAMES = {
|
themes.COLOR_MODE_NAMES = {
|
||||||
"Standard",
|
"Standard",
|
||||||
"Deuteranopia",
|
"Deuteranopia",
|
||||||
"Protanopia",
|
"Protanopia",
|
||||||
"Tritanopia"
|
"Tritanopia",
|
||||||
|
"Blue for 'Good'",
|
||||||
|
"Standard + Black",
|
||||||
|
"Blue + Black"
|
||||||
}
|
}
|
||||||
|
|
||||||
-- attempts to get the string name of a color mode
|
-- attempts to get the string name of a color mode
|
||||||
@ -72,7 +79,10 @@ function themes.color_mode_name(id)
|
|||||||
if id == themes.COLOR_MODE.STANDARD or
|
if id == themes.COLOR_MODE.STANDARD or
|
||||||
id == themes.COLOR_MODE.DEUTERANOPIA or
|
id == themes.COLOR_MODE.DEUTERANOPIA or
|
||||||
id == themes.COLOR_MODE.PROTANOPIA or
|
id == themes.COLOR_MODE.PROTANOPIA or
|
||||||
id == themes.COLOR_MODE.TRITANOPIA then
|
id == themes.COLOR_MODE.TRITANOPIA or
|
||||||
|
id == themes.COLOR_MODE.BLUE_IND or
|
||||||
|
id == themes.COLOR_MODE.STD_ON_BLACK or
|
||||||
|
id == themes.COLOR_MODE.BLUE_ON_BLACK then
|
||||||
return themes.COLOR_MODE_NAMES[id]
|
return themes.COLOR_MODE_NAMES[id]
|
||||||
else return nil end
|
else return nil end
|
||||||
end
|
end
|
||||||
@ -147,6 +157,26 @@ themes.sandstone = {
|
|||||||
{ c = colors.yellow_off, hex = 0x141414 },
|
{ c = colors.yellow_off, hex = 0x141414 },
|
||||||
{ c = colors.red, hex = 0xff0000 },
|
{ c = colors.red, hex = 0xff0000 },
|
||||||
{ c = colors.red_off, hex = 0x141414 }
|
{ c = colors.red_off, hex = 0x141414 }
|
||||||
|
},
|
||||||
|
-- blue indicators
|
||||||
|
{
|
||||||
|
{ c = colors.green, hex = 0x1081ff },
|
||||||
|
{ c = colors.green_hc, hex = 0x1081ff },
|
||||||
|
{ c = colors.green_off, hex = 0x053466 },
|
||||||
|
},
|
||||||
|
-- standard, black backgrounds
|
||||||
|
{
|
||||||
|
{ c = colors.green_off, hex = 0x141414 },
|
||||||
|
{ c = colors.yellow_off, hex = 0x141414 },
|
||||||
|
{ c = colors.red_off, hex = 0x141414 }
|
||||||
|
},
|
||||||
|
-- blue indicators, black backgrounds
|
||||||
|
{
|
||||||
|
{ c = colors.green, hex = 0x1081ff },
|
||||||
|
{ c = colors.green_hc, hex = 0x1081ff },
|
||||||
|
{ c = colors.green_off, hex = 0x141414 },
|
||||||
|
{ c = colors.yellow_off, hex = 0x141414 },
|
||||||
|
{ c = colors.red_off, hex = 0x141414 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -180,8 +210,8 @@ themes.basalt = {
|
|||||||
{ c = colors.white, hex = 0xbfbfbf },
|
{ c = colors.white, hex = 0xbfbfbf },
|
||||||
{ c = colors.lightGray, hex = 0x848794 },
|
{ c = colors.lightGray, hex = 0x848794 },
|
||||||
{ c = colors.gray, hex = 0x5c5f68 },
|
{ c = colors.gray, hex = 0x5c5f68 },
|
||||||
{ c = colors.black, hex = 0x262626 },
|
{ c = colors.black, hex = 0x333333 },
|
||||||
{ c = colors.red_off, hex = 0x653839 }
|
{ c = colors.red_off, hex = 0x512d2d }
|
||||||
},
|
},
|
||||||
|
|
||||||
color_modes = {
|
color_modes = {
|
||||||
@ -216,6 +246,26 @@ themes.basalt = {
|
|||||||
{ c = colors.yellow_off, hex = 0x333333 },
|
{ c = colors.yellow_off, hex = 0x333333 },
|
||||||
{ c = colors.red, hex = 0xdf4949 },
|
{ c = colors.red, hex = 0xdf4949 },
|
||||||
{ c = colors.red_off, hex = 0x333333 }
|
{ c = colors.red_off, hex = 0x333333 }
|
||||||
|
},
|
||||||
|
-- blue indicators
|
||||||
|
{
|
||||||
|
{ c = colors.green, hex = 0x65aeff },
|
||||||
|
{ c = colors.green_hc, hex = 0x99c9ff },
|
||||||
|
{ c = colors.green_off, hex = 0x365e8a },
|
||||||
|
},
|
||||||
|
-- standard, black backgrounds
|
||||||
|
{
|
||||||
|
{ c = colors.green_off, hex = 0x333333 },
|
||||||
|
{ c = colors.yellow_off, hex = 0x333333 },
|
||||||
|
{ c = colors.red_off, hex = 0x333333 }
|
||||||
|
},
|
||||||
|
-- blue indicators, black backgrounds
|
||||||
|
{
|
||||||
|
{ c = colors.green, hex = 0x65aeff },
|
||||||
|
{ c = colors.green_hc, hex = 0x99c9ff },
|
||||||
|
{ c = colors.green_off, hex = 0x333333 },
|
||||||
|
{ c = colors.yellow_off, hex = 0x333333 },
|
||||||
|
{ c = colors.red_off, hex = 0x333333 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -272,19 +322,33 @@ themes.smooth_stone = {
|
|||||||
{
|
{
|
||||||
{ c = colors.blue, hex = 0x1081ff },
|
{ c = colors.blue, hex = 0x1081ff },
|
||||||
{ c = colors.yellow, hex = 0xf7c311 },
|
{ c = colors.yellow, hex = 0xf7c311 },
|
||||||
{ c = colors.red, hex = 0xfb5615 },
|
{ c = colors.red, hex = 0xfb5615 }
|
||||||
},
|
},
|
||||||
-- protanopia
|
-- protanopia
|
||||||
{
|
{
|
||||||
{ c = colors.blue, hex = 0x1081ff },
|
{ c = colors.blue, hex = 0x1081ff },
|
||||||
{ c = colors.yellow, hex = 0xf5e633 },
|
{ c = colors.yellow, hex = 0xf5e633 },
|
||||||
{ c = colors.red, hex = 0xff521a },
|
{ c = colors.red, hex = 0xff521a }
|
||||||
},
|
},
|
||||||
-- tritanopia
|
-- tritanopia
|
||||||
{
|
{
|
||||||
{ c = colors.blue, hex = 0x40cbd7 },
|
{ c = colors.blue, hex = 0x40cbd7 },
|
||||||
{ c = colors.yellow, hex = 0xffbc00 },
|
{ c = colors.yellow, hex = 0xffbc00 },
|
||||||
{ c = colors.red, hex = 0xff0000 },
|
{ c = colors.red, hex = 0xff0000 }
|
||||||
|
},
|
||||||
|
-- blue indicators
|
||||||
|
{
|
||||||
|
{ c = colors.blue, hex = 0x1081ff },
|
||||||
|
{ c = colors.yellow, hex = 0xfffc79 },
|
||||||
|
{ c = colors.red, hex = 0xdf4949 }
|
||||||
|
},
|
||||||
|
-- standard, black backgrounds
|
||||||
|
{},
|
||||||
|
-- blue indicators, black backgrounds
|
||||||
|
{
|
||||||
|
{ c = colors.blue, hex = 0x1081ff },
|
||||||
|
{ c = colors.yellow, hex = 0xfffc79 },
|
||||||
|
{ c = colors.red, hex = 0xdf4949 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -318,19 +382,33 @@ themes.deepslate = {
|
|||||||
{
|
{
|
||||||
{ c = colors.blue, hex = 0x65aeff },
|
{ c = colors.blue, hex = 0x65aeff },
|
||||||
{ c = colors.yellow, hex = 0xf7c311 },
|
{ c = colors.yellow, hex = 0xf7c311 },
|
||||||
{ c = colors.red, hex = 0xfb5615 },
|
{ c = colors.red, hex = 0xfb5615 }
|
||||||
},
|
},
|
||||||
-- protanopia
|
-- protanopia
|
||||||
{
|
{
|
||||||
{ c = colors.blue, hex = 0x65aeff },
|
{ c = colors.blue, hex = 0x65aeff },
|
||||||
{ c = colors.yellow, hex = 0xf5e633 },
|
{ c = colors.yellow, hex = 0xf5e633 },
|
||||||
{ c = colors.red, hex = 0xff8058 },
|
{ c = colors.red, hex = 0xff8058 }
|
||||||
},
|
},
|
||||||
-- tritanopia
|
-- tritanopia
|
||||||
{
|
{
|
||||||
{ c = colors.blue, hex = 0x00ecff },
|
{ c = colors.blue, hex = 0x00ecff },
|
||||||
{ c = colors.yellow, hex = 0xffbc00 },
|
{ c = colors.yellow, hex = 0xffbc00 },
|
||||||
{ c = colors.red, hex = 0xdf4949 },
|
{ c = colors.red, hex = 0xdf4949 }
|
||||||
|
},
|
||||||
|
-- blue indicators
|
||||||
|
{
|
||||||
|
{ c = colors.blue, hex = 0x65aeff },
|
||||||
|
{ c = colors.yellow, hex = 0xd9cf81 },
|
||||||
|
{ c = colors.red, hex = 0xeb6a6c }
|
||||||
|
},
|
||||||
|
-- standard, black backgrounds
|
||||||
|
{},
|
||||||
|
-- blue indicators, black backgrounds
|
||||||
|
{
|
||||||
|
{ c = colors.blue, hex = 0x65aeff },
|
||||||
|
{ c = colors.yellow, hex = 0xd9cf81 },
|
||||||
|
{ c = colors.red, hex = 0xeb6a6c }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ local iocontrol = require("pocket.iocontrol")
|
|||||||
local pocket = require("pocket.pocket")
|
local pocket = require("pocket.pocket")
|
||||||
local renderer = require("pocket.renderer")
|
local renderer = require("pocket.renderer")
|
||||||
|
|
||||||
local POCKET_VERSION = "v0.7.2-alpha"
|
local POCKET_VERSION = "v0.7.4-alpha"
|
||||||
|
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local println_ts = util.println_ts
|
local println_ts = util.println_ts
|
||||||
@ -54,6 +54,7 @@ log.info("BOOTING pocket.startup " .. POCKET_VERSION)
|
|||||||
log.info("========================================")
|
log.info("========================================")
|
||||||
|
|
||||||
crash.set_env("pocket", POCKET_VERSION)
|
crash.set_env("pocket", POCKET_VERSION)
|
||||||
|
crash.dbg_log_env()
|
||||||
|
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
-- main application
|
-- main application
|
||||||
|
@ -39,7 +39,8 @@ local RIGHT = core.ALIGN.RIGHT
|
|||||||
local changes = {
|
local changes = {
|
||||||
{ "v1.6.2", { "AuthKey minimum length is now 8 (if set)" } },
|
{ "v1.6.2", { "AuthKey minimum length is now 8 (if set)" } },
|
||||||
{ "v1.6.8", { "ConnTimeout can now have a fractional part" } },
|
{ "v1.6.8", { "ConnTimeout can now have a fractional part" } },
|
||||||
{ "v1.6.15", { "Added front panel UI theme", "Added color accessibility modes" } }
|
{ "v1.6.15", { "Added front panel UI theme", "Added color accessibility modes" } },
|
||||||
|
{ "v1.7.3", { "Added standard with black off state color mode", "Added blue indicator color modes" } }
|
||||||
}
|
}
|
||||||
|
|
||||||
---@class plc_configurator
|
---@class plc_configurator
|
||||||
@ -215,7 +216,7 @@ local function config_view(display)
|
|||||||
end
|
end
|
||||||
|
|
||||||
PushButton{parent=main_page,x=2,y=17,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=btn_act_fg_bg}
|
PushButton{parent=main_page,x=2,y=17,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=btn_act_fg_bg}
|
||||||
tool_ctl.color_cfg = PushButton{parent=main_page,x=23,y=17,min_width=15,text="Color Options",callback=jump_color,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
tool_ctl.color_cfg = PushButton{parent=main_page,x=23,y=17,min_width=15,text="Color Options",callback=jump_color,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg,dis_fg_bg=cpair(colors.lightGray,colors.white)}
|
||||||
PushButton{parent=main_page,x=39,y=17,min_width=12,text="Change Log",callback=function()main_pane.set_value(7)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
PushButton{parent=main_page,x=39,y=17,min_width=12,text="Change Log",callback=function()main_pane.set_value(7)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||||
|
|
||||||
if not tool_ctl.has_config then
|
if not tool_ctl.has_config then
|
||||||
@ -462,12 +463,27 @@ local function config_view(display)
|
|||||||
TextBox{parent=clr_c_1,x=1,y=7,height=1,text="Front Panel Theme"}
|
TextBox{parent=clr_c_1,x=1,y=7,height=1,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,callback=function()end,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
local fp_theme = RadioButton{parent=clr_c_1,x=1,y=8,default=ini_cfg.FrontPanelTheme,options=themes.FP_THEME_NAMES,callback=function()end,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||||
|
|
||||||
TextBox{parent=clr_c_2,x=1,y=1,height=6,text="By default, this project uses green/red heavily to distinguish ok and not, with some indicators also using multiple colors. By selecting a color blindness below, blues will be used instead of greens on indicators and multi-color indicators will be split up as space permits."}
|
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,x=21,y=7,height=1,text="Preview"}
|
||||||
|
local _ = IndLight{parent=clr_c_2,x=21,y=8,label="Good",colors=cpair(colors.black,colors.green)}
|
||||||
|
_ = IndLight{parent=clr_c_2,x=21,y=9,label="Warning",colors=cpair(colors.black,colors.yellow)}
|
||||||
|
_ = IndLight{parent=clr_c_2,x=21,y=10,label="Bad",colors=cpair(colors.black,colors.red)}
|
||||||
|
local b_off = IndLight{parent=clr_c_2,x=21,y=11,label="Off",colors=cpair(colors.black,colors.black),hidden=true}
|
||||||
|
local g_off = IndLight{parent=clr_c_2,x=21,y=11,label="Off",colors=cpair(colors.gray,colors.gray),hidden=true}
|
||||||
|
|
||||||
local function recolor(value)
|
local function recolor(value)
|
||||||
local c = themes.smooth_stone.color_modes[value]
|
local c = themes.smooth_stone.color_modes[value]
|
||||||
|
|
||||||
if value == 1 then
|
if value == themes.COLOR_MODE.STANDARD or value == themes.COLOR_MODE.BLUE_IND then
|
||||||
|
b_off.hide()
|
||||||
|
g_off.show()
|
||||||
|
else
|
||||||
|
g_off.hide()
|
||||||
|
b_off.show()
|
||||||
|
end
|
||||||
|
|
||||||
|
if #c == 0 then
|
||||||
for i = 1, #style.colors do term.setPaletteColor(style.colors[i].c, style.colors[i].hex) end
|
for i = 1, #style.colors do term.setPaletteColor(style.colors[i].c, style.colors[i].hex) end
|
||||||
else
|
else
|
||||||
term.setPaletteColor(colors.green, c[1].hex)
|
term.setPaletteColor(colors.green, c[1].hex)
|
||||||
@ -476,15 +492,10 @@ local function config_view(display)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
TextBox{parent=clr_c_2,x=1,y=8,height=1,text="Color Mode"}
|
TextBox{parent=clr_c_2,x=1,y=7,height=1,width=10,text="Color Mode"}
|
||||||
local c_mode = RadioButton{parent=clr_c_2,x=1,y=9,default=ini_cfg.ColorMode,options=themes.COLOR_MODE_NAMES,callback=recolor,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
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,x=20,y=8,height=1,text="Preview"}
|
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}
|
||||||
local _ = IndLight{parent=clr_c_2,x=20,y=9,label="Good",colors=cpair(colors.black,colors.green)}
|
|
||||||
_ = IndLight{parent=clr_c_2,x=20,y=10,label="Warning",colors=cpair(colors.black,colors.yellow)}
|
|
||||||
_ = IndLight{parent=clr_c_2,x=20,y=11,label="Bad",colors=cpair(colors.black,colors.red)}
|
|
||||||
|
|
||||||
TextBox{parent=clr_c_2,x=1,y=14,height=6,text="Note: exact color varies by theme.",fg_bg=g_lg_fg_bg}
|
|
||||||
|
|
||||||
PushButton{parent=clr_c_2,x=44,y=14,min_width=6,text="Done",callback=function()clr_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
PushButton{parent=clr_c_2,x=44,y=14,min_width=6,text="Done",callback=function()clr_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||||
|
|
||||||
|
@ -60,12 +60,12 @@ local function init(panel)
|
|||||||
local modem = LED{parent=system,label="MODEM",colors=ind_grn}
|
local modem = LED{parent=system,label="MODEM",colors=ind_grn}
|
||||||
|
|
||||||
if not style.colorblind then
|
if not style.colorblind then
|
||||||
local network = RGBLED{parent=system,label="NETWORK",colors={colors.green,colors.red,colors.orange,colors.yellow,colors.gray}}
|
local network = RGBLED{parent=system,label="NETWORK",colors={colors.green,colors.red,colors.orange,colors.yellow,style.ind_bkg}}
|
||||||
network.update(types.PANEL_LINK_STATE.DISCONNECTED)
|
network.update(types.PANEL_LINK_STATE.DISCONNECTED)
|
||||||
network.register(databus.ps, "link_state", network.update)
|
network.register(databus.ps, "link_state", network.update)
|
||||||
else
|
else
|
||||||
local nt_lnk = LEDPair{parent=system,label="NT LINKED",off=colors.red_off,c1=colors.red,c2=colors.green}
|
local nt_lnk = LEDPair{parent=system,label="NT LINKED",off=style.ind_bkg,c1=colors.red,c2=colors.green}
|
||||||
local nt_ver = LEDPair{parent=system,label="NT VERSION",off=colors.red_off,c1=colors.red,c2=colors.green}
|
local nt_ver = LEDPair{parent=system,label="NT VERSION",off=style.ind_bkg,c1=colors.red,c2=colors.green}
|
||||||
local nt_col = LED{parent=system,label="NT COLLISION",colors=ind_red}
|
local nt_col = LED{parent=system,label="NT COLLISION",colors=ind_red}
|
||||||
|
|
||||||
nt_lnk.register(databus.ps, "link_state", function (state)
|
nt_lnk.register(databus.ps, "link_state", function (state)
|
||||||
|
@ -29,7 +29,13 @@ function style.set_theme(fp, color_mode)
|
|||||||
|
|
||||||
style.fp = themes.get_fp_style(style.theme)
|
style.fp = themes.get_fp_style(style.theme)
|
||||||
|
|
||||||
style.colorblind = color_mode ~= themes.COLOR_MODE.STANDARD
|
style.colorblind = color_mode ~= themes.COLOR_MODE.STANDARD and color_mode ~= themes.COLOR_MODE.STD_ON_BLACK
|
||||||
|
|
||||||
|
if color_mode == themes.COLOR_MODE.STANDARD or color_mode == themes.COLOR_MODE.BLUE_IND then
|
||||||
|
style.ind_bkg = colors.gray
|
||||||
|
else
|
||||||
|
style.ind_bkg = colors.black
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return style
|
return style
|
||||||
|
@ -6,6 +6,8 @@ local rsio = require("scada-common.rsio")
|
|||||||
local types = require("scada-common.types")
|
local types = require("scada-common.types")
|
||||||
local util = require("scada-common.util")
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
|
local themes = require("graphics.themes")
|
||||||
|
|
||||||
local databus = require("reactor-plc.databus")
|
local databus = require("reactor-plc.databus")
|
||||||
|
|
||||||
local plc = {}
|
local plc = {}
|
||||||
@ -84,7 +86,7 @@ function plc.load_config()
|
|||||||
cfv.assert_type_int(config.FrontPanelTheme)
|
cfv.assert_type_int(config.FrontPanelTheme)
|
||||||
cfv.assert_range(config.FrontPanelTheme, 1, 2)
|
cfv.assert_range(config.FrontPanelTheme, 1, 2)
|
||||||
cfv.assert_type_int(config.ColorMode)
|
cfv.assert_type_int(config.ColorMode)
|
||||||
cfv.assert_range(config.ColorMode, 1, 4)
|
cfv.assert_range(config.ColorMode, 1, themes.COLOR_MODE.NUM_MODES)
|
||||||
|
|
||||||
-- check emergency coolant configuration if enabled
|
-- check emergency coolant configuration if enabled
|
||||||
if config.EmerCoolEnable then
|
if config.EmerCoolEnable then
|
||||||
@ -144,9 +146,9 @@ function plc.rps_init(reactor, is_formed)
|
|||||||
local function _check_and_handle_ppm_call(result)
|
local function _check_and_handle_ppm_call(result)
|
||||||
if result == ppm.ACCESS_FAULT then
|
if result == ppm.ACCESS_FAULT then
|
||||||
_set_fault()
|
_set_fault()
|
||||||
elseif result == ppm.UNDEFINED_FIELD then
|
|
||||||
_set_fault()
|
-- if undefined, then the reactor isn't formed
|
||||||
self.formed = false
|
if reactor.__p_last_fault() == ppm.UNDEFINED_FIELD then self.formed = false end
|
||||||
else return true end
|
else return true end
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc")
|
|||||||
local renderer = require("reactor-plc.renderer")
|
local renderer = require("reactor-plc.renderer")
|
||||||
local threads = require("reactor-plc.threads")
|
local threads = require("reactor-plc.threads")
|
||||||
|
|
||||||
local R_PLC_VERSION = "v1.7.0"
|
local R_PLC_VERSION = "v1.7.4"
|
||||||
|
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local println_ts = util.println_ts
|
local println_ts = util.println_ts
|
||||||
@ -55,6 +55,7 @@ log.info("========================================")
|
|||||||
println(">> Reactor PLC " .. R_PLC_VERSION .. " <<")
|
println(">> Reactor PLC " .. R_PLC_VERSION .. " <<")
|
||||||
|
|
||||||
crash.set_env("reactor-plc", R_PLC_VERSION)
|
crash.set_env("reactor-plc", R_PLC_VERSION)
|
||||||
|
crash.dbg_log_env()
|
||||||
|
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
-- main application
|
-- main application
|
||||||
@ -144,13 +145,6 @@ local function main()
|
|||||||
println("init> fission reactor is not formed")
|
println("init> fission reactor is not formed")
|
||||||
log.warning("init> reactor logic adapter present, but reactor is not formed")
|
log.warning("init> reactor logic adapter present, but reactor is not formed")
|
||||||
|
|
||||||
plc_state.degraded = true
|
|
||||||
plc_state.reactor_formed = false
|
|
||||||
elseif smem_dev.reactor.getStatus() == ppm.UNDEFINED_FIELD then
|
|
||||||
-- reactor formed after ppm.mount_all was called
|
|
||||||
println("init> fission reactor was not formed")
|
|
||||||
log.warning("init> reactor reported formed, but multiblock functions are not available")
|
|
||||||
|
|
||||||
plc_state.degraded = true
|
plc_state.degraded = true
|
||||||
plc_state.reactor_formed = false
|
plc_state.reactor_formed = false
|
||||||
end
|
end
|
||||||
@ -185,6 +179,7 @@ local function main()
|
|||||||
local message
|
local message
|
||||||
plc_state.fp_ok, message = renderer.try_start_ui(config.FrontPanelTheme, config.ColorMode)
|
plc_state.fp_ok, message = renderer.try_start_ui(config.FrontPanelTheme, config.ColorMode)
|
||||||
|
|
||||||
|
-- ...or not
|
||||||
if not plc_state.fp_ok then
|
if not plc_state.fp_ok then
|
||||||
println_ts(util.c("UI error: ", message))
|
println_ts(util.c("UI error: ", message))
|
||||||
println("init> running without front panel")
|
println("init> running without front panel")
|
||||||
|
@ -77,7 +77,8 @@ assert(#PORT_DSGN == rsio.NUM_PORTS)
|
|||||||
-- changes to the config data/format to let the user know
|
-- changes to the config data/format to let the user know
|
||||||
local changes = {
|
local changes = {
|
||||||
{ "v1.7.9", { "ConnTimeout can now have a fractional part" } },
|
{ "v1.7.9", { "ConnTimeout can now have a fractional part" } },
|
||||||
{ "v1.7.15", { "Added front panel UI theme", "Added color accessibility modes" } }
|
{ "v1.7.15", { "Added front panel UI theme", "Added color accessibility modes" } },
|
||||||
|
{ "v1.9.2", { "Added standard with black off state color mode", "Added blue indicator color modes" } }
|
||||||
}
|
}
|
||||||
|
|
||||||
---@class rtu_rs_definition
|
---@class rtu_rs_definition
|
||||||
@ -321,7 +322,7 @@ local function config_view(display)
|
|||||||
end
|
end
|
||||||
|
|
||||||
PushButton{parent=main_page,x=2,y=17,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=btn_act_fg_bg}
|
PushButton{parent=main_page,x=2,y=17,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=btn_act_fg_bg}
|
||||||
tool_ctl.color_cfg = PushButton{parent=main_page,x=23,y=17,min_width=15,text="Color Options",callback=jump_color,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
tool_ctl.color_cfg = PushButton{parent=main_page,x=23,y=17,min_width=15,text="Color Options",callback=jump_color,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg,dis_fg_bg=cpair(colors.lightGray,colors.white)}
|
||||||
PushButton{parent=main_page,x=39,y=17,min_width=12,text="Change Log",callback=function()main_pane.set_value(7)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
PushButton{parent=main_page,x=39,y=17,min_width=12,text="Change Log",callback=function()main_pane.set_value(7)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||||
|
|
||||||
if not tool_ctl.has_config then
|
if not tool_ctl.has_config then
|
||||||
@ -517,12 +518,27 @@ local function config_view(display)
|
|||||||
TextBox{parent=clr_c_1,x=1,y=7,height=1,text="Front Panel Theme"}
|
TextBox{parent=clr_c_1,x=1,y=7,height=1,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,callback=function()end,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
local fp_theme = RadioButton{parent=clr_c_1,x=1,y=8,default=ini_cfg.FrontPanelTheme,options=themes.FP_THEME_NAMES,callback=function()end,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||||
|
|
||||||
TextBox{parent=clr_c_2,x=1,y=1,height=6,text="By default, this project uses green/red heavily to distinguish ok and not, with some indicators also using multiple colors. By selecting a color blindness below, blues will be used instead of greens on indicators and multi-color indicators will be split up as space permits."}
|
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,x=21,y=7,height=1,text="Preview"}
|
||||||
|
local _ = IndLight{parent=clr_c_2,x=21,y=8,label="Good",colors=cpair(colors.black,colors.green)}
|
||||||
|
_ = IndLight{parent=clr_c_2,x=21,y=9,label="Warning",colors=cpair(colors.black,colors.yellow)}
|
||||||
|
_ = IndLight{parent=clr_c_2,x=21,y=10,label="Bad",colors=cpair(colors.black,colors.red)}
|
||||||
|
local b_off = IndLight{parent=clr_c_2,x=21,y=11,label="Off",colors=cpair(colors.black,colors.black),hidden=true}
|
||||||
|
local g_off = IndLight{parent=clr_c_2,x=21,y=11,label="Off",colors=cpair(colors.gray,colors.gray),hidden=true}
|
||||||
|
|
||||||
local function recolor(value)
|
local function recolor(value)
|
||||||
local c = themes.smooth_stone.color_modes[value]
|
local c = themes.smooth_stone.color_modes[value]
|
||||||
|
|
||||||
if value == 1 then
|
if value == themes.COLOR_MODE.STANDARD or value == themes.COLOR_MODE.BLUE_IND then
|
||||||
|
b_off.hide()
|
||||||
|
g_off.show()
|
||||||
|
else
|
||||||
|
g_off.hide()
|
||||||
|
b_off.show()
|
||||||
|
end
|
||||||
|
|
||||||
|
if #c == 0 then
|
||||||
for i = 1, #style.colors do term.setPaletteColor(style.colors[i].c, style.colors[i].hex) end
|
for i = 1, #style.colors do term.setPaletteColor(style.colors[i].c, style.colors[i].hex) end
|
||||||
else
|
else
|
||||||
term.setPaletteColor(colors.green, c[1].hex)
|
term.setPaletteColor(colors.green, c[1].hex)
|
||||||
@ -531,15 +547,10 @@ local function config_view(display)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
TextBox{parent=clr_c_2,x=1,y=8,height=1,text="Color Mode"}
|
TextBox{parent=clr_c_2,x=1,y=7,height=1,width=10,text="Color Mode"}
|
||||||
local c_mode = RadioButton{parent=clr_c_2,x=1,y=9,default=ini_cfg.ColorMode,options=themes.COLOR_MODE_NAMES,callback=recolor,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
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,x=20,y=8,height=1,text="Preview"}
|
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}
|
||||||
local _ = IndLight{parent=clr_c_2,x=20,y=9,label="Good",colors=cpair(colors.black,colors.green)}
|
|
||||||
_ = IndLight{parent=clr_c_2,x=20,y=10,label="Warning",colors=cpair(colors.black,colors.yellow)}
|
|
||||||
_ = IndLight{parent=clr_c_2,x=20,y=11,label="Bad",colors=cpair(colors.black,colors.red)}
|
|
||||||
|
|
||||||
TextBox{parent=clr_c_2,x=1,y=14,height=6,text="Note: exact color varies by theme.",fg_bg=g_lg_fg_bg}
|
|
||||||
|
|
||||||
PushButton{parent=clr_c_2,x=44,y=14,min_width=6,text="Done",callback=function()clr_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
PushButton{parent=clr_c_2,x=44,y=14,min_width=6,text="Done",callback=function()clr_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||||
|
|
||||||
|
@ -9,58 +9,49 @@ local boilerv_rtu = {}
|
|||||||
function boilerv_rtu.new(boiler)
|
function boilerv_rtu.new(boiler)
|
||||||
local unit = rtu.init_unit(boiler)
|
local unit = rtu.init_unit(boiler)
|
||||||
|
|
||||||
-- disable auto fault clearing
|
|
||||||
boiler.__p_clear_fault()
|
|
||||||
boiler.__p_disable_afc()
|
|
||||||
|
|
||||||
-- discrete inputs --
|
-- discrete inputs --
|
||||||
unit.connect_di(boiler.isFormed)
|
unit.connect_di("isFormed")
|
||||||
|
|
||||||
-- coils --
|
-- coils --
|
||||||
-- none
|
-- none
|
||||||
|
|
||||||
-- input registers --
|
-- input registers --
|
||||||
-- multiblock properties
|
-- multiblock properties
|
||||||
unit.connect_input_reg(boiler.getLength)
|
unit.connect_input_reg("getLength")
|
||||||
unit.connect_input_reg(boiler.getWidth)
|
unit.connect_input_reg("getWidth")
|
||||||
unit.connect_input_reg(boiler.getHeight)
|
unit.connect_input_reg("getHeight")
|
||||||
unit.connect_input_reg(boiler.getMinPos)
|
unit.connect_input_reg("getMinPos")
|
||||||
unit.connect_input_reg(boiler.getMaxPos)
|
unit.connect_input_reg("getMaxPos")
|
||||||
-- build properties
|
-- build properties
|
||||||
unit.connect_input_reg(boiler.getBoilCapacity)
|
unit.connect_input_reg("getBoilCapacity")
|
||||||
unit.connect_input_reg(boiler.getSteamCapacity)
|
unit.connect_input_reg("getSteamCapacity")
|
||||||
unit.connect_input_reg(boiler.getWaterCapacity)
|
unit.connect_input_reg("getWaterCapacity")
|
||||||
unit.connect_input_reg(boiler.getHeatedCoolantCapacity)
|
unit.connect_input_reg("getHeatedCoolantCapacity")
|
||||||
unit.connect_input_reg(boiler.getCooledCoolantCapacity)
|
unit.connect_input_reg("getCooledCoolantCapacity")
|
||||||
unit.connect_input_reg(boiler.getSuperheaters)
|
unit.connect_input_reg("getSuperheaters")
|
||||||
unit.connect_input_reg(boiler.getMaxBoilRate)
|
unit.connect_input_reg("getMaxBoilRate")
|
||||||
-- current state
|
-- current state
|
||||||
unit.connect_input_reg(boiler.getTemperature)
|
unit.connect_input_reg("getTemperature")
|
||||||
unit.connect_input_reg(boiler.getBoilRate)
|
unit.connect_input_reg("getBoilRate")
|
||||||
unit.connect_input_reg(boiler.getEnvironmentalLoss)
|
unit.connect_input_reg("getEnvironmentalLoss")
|
||||||
-- tanks
|
-- tanks
|
||||||
unit.connect_input_reg(boiler.getSteam)
|
unit.connect_input_reg("getSteam")
|
||||||
unit.connect_input_reg(boiler.getSteamNeeded)
|
unit.connect_input_reg("getSteamNeeded")
|
||||||
unit.connect_input_reg(boiler.getSteamFilledPercentage)
|
unit.connect_input_reg("getSteamFilledPercentage")
|
||||||
unit.connect_input_reg(boiler.getWater)
|
unit.connect_input_reg("getWater")
|
||||||
unit.connect_input_reg(boiler.getWaterNeeded)
|
unit.connect_input_reg("getWaterNeeded")
|
||||||
unit.connect_input_reg(boiler.getWaterFilledPercentage)
|
unit.connect_input_reg("getWaterFilledPercentage")
|
||||||
unit.connect_input_reg(boiler.getHeatedCoolant)
|
unit.connect_input_reg("getHeatedCoolant")
|
||||||
unit.connect_input_reg(boiler.getHeatedCoolantNeeded)
|
unit.connect_input_reg("getHeatedCoolantNeeded")
|
||||||
unit.connect_input_reg(boiler.getHeatedCoolantFilledPercentage)
|
unit.connect_input_reg("getHeatedCoolantFilledPercentage")
|
||||||
unit.connect_input_reg(boiler.getCooledCoolant)
|
unit.connect_input_reg("getCooledCoolant")
|
||||||
unit.connect_input_reg(boiler.getCooledCoolantNeeded)
|
unit.connect_input_reg("getCooledCoolantNeeded")
|
||||||
unit.connect_input_reg(boiler.getCooledCoolantFilledPercentage)
|
unit.connect_input_reg("getCooledCoolantFilledPercentage")
|
||||||
|
|
||||||
-- holding registers --
|
-- holding registers --
|
||||||
-- none
|
-- none
|
||||||
|
|
||||||
-- check if any calls faulted
|
return unit.interface(), false
|
||||||
local faulted = boiler.__p_is_faulted()
|
|
||||||
boiler.__p_clear_fault()
|
|
||||||
boiler.__p_enable_afc()
|
|
||||||
|
|
||||||
return unit.interface(), faulted
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return boilerv_rtu
|
return boilerv_rtu
|
||||||
|
@ -9,12 +9,8 @@ local dynamicv_rtu = {}
|
|||||||
function dynamicv_rtu.new(dynamic_tank)
|
function dynamicv_rtu.new(dynamic_tank)
|
||||||
local unit = rtu.init_unit(dynamic_tank)
|
local unit = rtu.init_unit(dynamic_tank)
|
||||||
|
|
||||||
-- disable auto fault clearing
|
|
||||||
dynamic_tank.__p_clear_fault()
|
|
||||||
dynamic_tank.__p_disable_afc()
|
|
||||||
|
|
||||||
-- discrete inputs --
|
-- discrete inputs --
|
||||||
unit.connect_di(dynamic_tank.isFormed)
|
unit.connect_di("isFormed")
|
||||||
|
|
||||||
-- coils --
|
-- coils --
|
||||||
unit.connect_coil(function () dynamic_tank.incrementContainerEditMode() end, function () end)
|
unit.connect_coil(function () dynamic_tank.incrementContainerEditMode() end, function () end)
|
||||||
@ -22,27 +18,22 @@ function dynamicv_rtu.new(dynamic_tank)
|
|||||||
|
|
||||||
-- input registers --
|
-- input registers --
|
||||||
-- multiblock properties
|
-- multiblock properties
|
||||||
unit.connect_input_reg(dynamic_tank.getLength)
|
unit.connect_input_reg("getLength")
|
||||||
unit.connect_input_reg(dynamic_tank.getWidth)
|
unit.connect_input_reg("getWidth")
|
||||||
unit.connect_input_reg(dynamic_tank.getHeight)
|
unit.connect_input_reg("getHeight")
|
||||||
unit.connect_input_reg(dynamic_tank.getMinPos)
|
unit.connect_input_reg("getMinPos")
|
||||||
unit.connect_input_reg(dynamic_tank.getMaxPos)
|
unit.connect_input_reg("getMaxPos")
|
||||||
-- build properties
|
-- build properties
|
||||||
unit.connect_input_reg(dynamic_tank.getTankCapacity)
|
unit.connect_input_reg("getTankCapacity")
|
||||||
unit.connect_input_reg(dynamic_tank.getChemicalTankCapacity)
|
unit.connect_input_reg("getChemicalTankCapacity")
|
||||||
-- tanks/containers
|
-- tanks/containers
|
||||||
unit.connect_input_reg(dynamic_tank.getStored)
|
unit.connect_input_reg("getStored")
|
||||||
unit.connect_input_reg(dynamic_tank.getFilledPercentage)
|
unit.connect_input_reg("getFilledPercentage")
|
||||||
|
|
||||||
-- holding registers --
|
-- holding registers --
|
||||||
unit.connect_holding_reg(dynamic_tank.getContainerEditMode, dynamic_tank.setContainerEditMode)
|
unit.connect_holding_reg("getContainerEditMode", "setContainerEditMode")
|
||||||
|
|
||||||
-- check if any calls faulted
|
return unit.interface(), false
|
||||||
local faulted = dynamic_tank.__p_is_faulted()
|
|
||||||
dynamic_tank.__p_clear_fault()
|
|
||||||
dynamic_tank.__p_enable_afc()
|
|
||||||
|
|
||||||
return unit.interface(), faulted
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return dynamicv_rtu
|
return dynamicv_rtu
|
||||||
|
@ -9,45 +9,36 @@ local imatrix_rtu = {}
|
|||||||
function imatrix_rtu.new(imatrix)
|
function imatrix_rtu.new(imatrix)
|
||||||
local unit = rtu.init_unit(imatrix)
|
local unit = rtu.init_unit(imatrix)
|
||||||
|
|
||||||
-- disable auto fault clearing
|
|
||||||
imatrix.__p_clear_fault()
|
|
||||||
imatrix.__p_disable_afc()
|
|
||||||
|
|
||||||
-- discrete inputs --
|
-- discrete inputs --
|
||||||
unit.connect_di(imatrix.isFormed)
|
unit.connect_di("isFormed")
|
||||||
|
|
||||||
-- coils --
|
-- coils --
|
||||||
-- none
|
-- none
|
||||||
|
|
||||||
-- input registers --
|
-- input registers --
|
||||||
-- multiblock properties
|
-- multiblock properties
|
||||||
unit.connect_input_reg(imatrix.getLength)
|
unit.connect_input_reg("getLength")
|
||||||
unit.connect_input_reg(imatrix.getWidth)
|
unit.connect_input_reg("getWidth")
|
||||||
unit.connect_input_reg(imatrix.getHeight)
|
unit.connect_input_reg("getHeight")
|
||||||
unit.connect_input_reg(imatrix.getMinPos)
|
unit.connect_input_reg("getMinPos")
|
||||||
unit.connect_input_reg(imatrix.getMaxPos)
|
unit.connect_input_reg("getMaxPos")
|
||||||
-- build properties
|
-- build properties
|
||||||
unit.connect_input_reg(imatrix.getMaxEnergy)
|
unit.connect_input_reg("getMaxEnergy")
|
||||||
unit.connect_input_reg(imatrix.getTransferCap)
|
unit.connect_input_reg("getTransferCap")
|
||||||
unit.connect_input_reg(imatrix.getInstalledCells)
|
unit.connect_input_reg("getInstalledCells")
|
||||||
unit.connect_input_reg(imatrix.getInstalledProviders)
|
unit.connect_input_reg("getInstalledProviders")
|
||||||
-- I/O rates
|
-- I/O rates
|
||||||
unit.connect_input_reg(imatrix.getLastInput)
|
unit.connect_input_reg("getLastInput")
|
||||||
unit.connect_input_reg(imatrix.getLastOutput)
|
unit.connect_input_reg("getLastOutput")
|
||||||
-- tanks
|
-- tanks
|
||||||
unit.connect_input_reg(imatrix.getEnergy)
|
unit.connect_input_reg("getEnergy")
|
||||||
unit.connect_input_reg(imatrix.getEnergyNeeded)
|
unit.connect_input_reg("getEnergyNeeded")
|
||||||
unit.connect_input_reg(imatrix.getEnergyFilledPercentage)
|
unit.connect_input_reg("getEnergyFilledPercentage")
|
||||||
|
|
||||||
-- holding registers --
|
-- holding registers --
|
||||||
-- none
|
-- none
|
||||||
|
|
||||||
-- check if any calls faulted
|
return unit.interface(), false
|
||||||
local faulted = imatrix.__p_is_faulted()
|
|
||||||
imatrix.__p_clear_fault()
|
|
||||||
imatrix.__p_enable_afc()
|
|
||||||
|
|
||||||
return unit.interface(), faulted
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return imatrix_rtu
|
return imatrix_rtu
|
||||||
|
@ -9,50 +9,41 @@ local sps_rtu = {}
|
|||||||
function sps_rtu.new(sps)
|
function sps_rtu.new(sps)
|
||||||
local unit = rtu.init_unit(sps)
|
local unit = rtu.init_unit(sps)
|
||||||
|
|
||||||
-- disable auto fault clearing
|
|
||||||
sps.__p_clear_fault()
|
|
||||||
sps.__p_disable_afc()
|
|
||||||
|
|
||||||
-- discrete inputs --
|
-- discrete inputs --
|
||||||
unit.connect_di(sps.isFormed)
|
unit.connect_di("isFormed")
|
||||||
|
|
||||||
-- coils --
|
-- coils --
|
||||||
-- none
|
-- none
|
||||||
|
|
||||||
-- input registers --
|
-- input registers --
|
||||||
-- multiblock properties
|
-- multiblock properties
|
||||||
unit.connect_input_reg(sps.getLength)
|
unit.connect_input_reg("getLength")
|
||||||
unit.connect_input_reg(sps.getWidth)
|
unit.connect_input_reg("getWidth")
|
||||||
unit.connect_input_reg(sps.getHeight)
|
unit.connect_input_reg("getHeight")
|
||||||
unit.connect_input_reg(sps.getMinPos)
|
unit.connect_input_reg("getMinPos")
|
||||||
unit.connect_input_reg(sps.getMaxPos)
|
unit.connect_input_reg("getMaxPos")
|
||||||
-- build properties
|
-- build properties
|
||||||
unit.connect_input_reg(sps.getCoils)
|
unit.connect_input_reg("getCoils")
|
||||||
unit.connect_input_reg(sps.getInputCapacity)
|
unit.connect_input_reg("getInputCapacity")
|
||||||
unit.connect_input_reg(sps.getOutputCapacity)
|
unit.connect_input_reg("getOutputCapacity")
|
||||||
unit.connect_input_reg(sps.getMaxEnergy)
|
unit.connect_input_reg("getMaxEnergy")
|
||||||
-- current state
|
-- current state
|
||||||
unit.connect_input_reg(sps.getProcessRate)
|
unit.connect_input_reg("getProcessRate")
|
||||||
-- tanks
|
-- tanks
|
||||||
unit.connect_input_reg(sps.getInput)
|
unit.connect_input_reg("getInput")
|
||||||
unit.connect_input_reg(sps.getInputNeeded)
|
unit.connect_input_reg("getInputNeeded")
|
||||||
unit.connect_input_reg(sps.getInputFilledPercentage)
|
unit.connect_input_reg("getInputFilledPercentage")
|
||||||
unit.connect_input_reg(sps.getOutput)
|
unit.connect_input_reg("getOutput")
|
||||||
unit.connect_input_reg(sps.getOutputNeeded)
|
unit.connect_input_reg("getOutputNeeded")
|
||||||
unit.connect_input_reg(sps.getOutputFilledPercentage)
|
unit.connect_input_reg("getOutputFilledPercentage")
|
||||||
unit.connect_input_reg(sps.getEnergy)
|
unit.connect_input_reg("getEnergy")
|
||||||
unit.connect_input_reg(sps.getEnergyNeeded)
|
unit.connect_input_reg("getEnergyNeeded")
|
||||||
unit.connect_input_reg(sps.getEnergyFilledPercentage)
|
unit.connect_input_reg("getEnergyFilledPercentage")
|
||||||
|
|
||||||
-- holding registers --
|
-- holding registers --
|
||||||
-- none
|
-- none
|
||||||
|
|
||||||
-- check if any calls faulted
|
return unit.interface(), false
|
||||||
local faulted = sps.__p_is_faulted()
|
|
||||||
sps.__p_clear_fault()
|
|
||||||
sps.__p_enable_afc()
|
|
||||||
|
|
||||||
return unit.interface(), faulted
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return sps_rtu
|
return sps_rtu
|
||||||
|
@ -9,12 +9,8 @@ local turbinev_rtu = {}
|
|||||||
function turbinev_rtu.new(turbine)
|
function turbinev_rtu.new(turbine)
|
||||||
local unit = rtu.init_unit(turbine)
|
local unit = rtu.init_unit(turbine)
|
||||||
|
|
||||||
-- disable auto fault clearing
|
|
||||||
turbine.__p_clear_fault()
|
|
||||||
turbine.__p_disable_afc()
|
|
||||||
|
|
||||||
-- discrete inputs --
|
-- discrete inputs --
|
||||||
unit.connect_di(turbine.isFormed)
|
unit.connect_di("isFormed")
|
||||||
|
|
||||||
-- coils --
|
-- coils --
|
||||||
unit.connect_coil(function () turbine.incrementDumpingMode() end, function () end)
|
unit.connect_coil(function () turbine.incrementDumpingMode() end, function () end)
|
||||||
@ -22,44 +18,39 @@ function turbinev_rtu.new(turbine)
|
|||||||
|
|
||||||
-- input registers --
|
-- input registers --
|
||||||
-- multiblock properties
|
-- multiblock properties
|
||||||
unit.connect_input_reg(turbine.getLength)
|
unit.connect_input_reg("getLength")
|
||||||
unit.connect_input_reg(turbine.getWidth)
|
unit.connect_input_reg("getWidth")
|
||||||
unit.connect_input_reg(turbine.getHeight)
|
unit.connect_input_reg("getHeight")
|
||||||
unit.connect_input_reg(turbine.getMinPos)
|
unit.connect_input_reg("getMinPos")
|
||||||
unit.connect_input_reg(turbine.getMaxPos)
|
unit.connect_input_reg("getMaxPos")
|
||||||
-- build properties
|
-- build properties
|
||||||
unit.connect_input_reg(turbine.getBlades)
|
unit.connect_input_reg("getBlades")
|
||||||
unit.connect_input_reg(turbine.getCoils)
|
unit.connect_input_reg("getCoils")
|
||||||
unit.connect_input_reg(turbine.getVents)
|
unit.connect_input_reg("getVents")
|
||||||
unit.connect_input_reg(turbine.getDispersers)
|
unit.connect_input_reg("getDispersers")
|
||||||
unit.connect_input_reg(turbine.getCondensers)
|
unit.connect_input_reg("getCondensers")
|
||||||
unit.connect_input_reg(turbine.getSteamCapacity)
|
unit.connect_input_reg("getSteamCapacity")
|
||||||
unit.connect_input_reg(turbine.getMaxEnergy)
|
unit.connect_input_reg("getMaxEnergy")
|
||||||
unit.connect_input_reg(turbine.getMaxFlowRate)
|
unit.connect_input_reg("getMaxFlowRate")
|
||||||
unit.connect_input_reg(turbine.getMaxProduction)
|
unit.connect_input_reg("getMaxProduction")
|
||||||
unit.connect_input_reg(turbine.getMaxWaterOutput)
|
unit.connect_input_reg("getMaxWaterOutput")
|
||||||
-- current state
|
-- current state
|
||||||
unit.connect_input_reg(turbine.getFlowRate)
|
unit.connect_input_reg("getFlowRate")
|
||||||
unit.connect_input_reg(turbine.getProductionRate)
|
unit.connect_input_reg("getProductionRate")
|
||||||
unit.connect_input_reg(turbine.getLastSteamInputRate)
|
unit.connect_input_reg("getLastSteamInputRate")
|
||||||
unit.connect_input_reg(turbine.getDumpingMode)
|
unit.connect_input_reg("getDumpingMode")
|
||||||
-- tanks/containers
|
-- tanks/containers
|
||||||
unit.connect_input_reg(turbine.getSteam)
|
unit.connect_input_reg("getSteam")
|
||||||
unit.connect_input_reg(turbine.getSteamNeeded)
|
unit.connect_input_reg("getSteamNeeded")
|
||||||
unit.connect_input_reg(turbine.getSteamFilledPercentage)
|
unit.connect_input_reg("getSteamFilledPercentage")
|
||||||
unit.connect_input_reg(turbine.getEnergy)
|
unit.connect_input_reg("getEnergy")
|
||||||
unit.connect_input_reg(turbine.getEnergyNeeded)
|
unit.connect_input_reg("getEnergyNeeded")
|
||||||
unit.connect_input_reg(turbine.getEnergyFilledPercentage)
|
unit.connect_input_reg("getEnergyFilledPercentage")
|
||||||
|
|
||||||
-- holding registers --
|
-- holding registers --
|
||||||
unit.connect_holding_reg(turbine.getDumpingMode, turbine.setDumpingMode)
|
unit.connect_holding_reg("getDumpingMode", "setDumpingMode")
|
||||||
|
|
||||||
-- check if any calls faulted
|
return unit.interface(), false
|
||||||
local faulted = turbine.__p_is_faulted()
|
|
||||||
turbine.__p_clear_fault()
|
|
||||||
turbine.__p_enable_afc()
|
|
||||||
|
|
||||||
return unit.interface(), faulted
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return turbinev_rtu
|
return turbinev_rtu
|
||||||
|
@ -53,12 +53,12 @@ local function init(panel, units)
|
|||||||
local modem = LED{parent=system,label="MODEM",colors=ind_grn}
|
local modem = LED{parent=system,label="MODEM",colors=ind_grn}
|
||||||
|
|
||||||
if not style.colorblind then
|
if not style.colorblind then
|
||||||
local network = RGBLED{parent=system,label="NETWORK",colors={colors.green,colors.red,colors.orange,colors.yellow,colors.gray}}
|
local network = RGBLED{parent=system,label="NETWORK",colors={colors.green,colors.red,colors.orange,colors.yellow,style.ind_bkg}}
|
||||||
network.update(types.PANEL_LINK_STATE.DISCONNECTED)
|
network.update(types.PANEL_LINK_STATE.DISCONNECTED)
|
||||||
network.register(databus.ps, "link_state", network.update)
|
network.register(databus.ps, "link_state", network.update)
|
||||||
else
|
else
|
||||||
local nt_lnk = LEDPair{parent=system,label="NT LINKED",off=colors.red_off,c1=colors.red,c2=colors.green}
|
local nt_lnk = LEDPair{parent=system,label="NT LINKED",off=style.ind_bkg,c1=colors.red,c2=colors.green}
|
||||||
local nt_ver = LEDPair{parent=system,label="NT VERSION",off=colors.red_off,c1=colors.red,c2=colors.green}
|
local nt_ver = LEDPair{parent=system,label="NT VERSION",off=style.ind_bkg,c1=colors.red,c2=colors.green}
|
||||||
|
|
||||||
nt_lnk.register(databus.ps, "link_state", function (state)
|
nt_lnk.register(databus.ps, "link_state", function (state)
|
||||||
local value = 2
|
local value = 2
|
||||||
|
@ -28,7 +28,13 @@ function style.set_theme(fp, color_mode)
|
|||||||
|
|
||||||
style.fp = themes.get_fp_style(style.theme)
|
style.fp = themes.get_fp_style(style.theme)
|
||||||
|
|
||||||
style.colorblind = color_mode ~= themes.COLOR_MODE.STANDARD
|
style.colorblind = color_mode ~= themes.COLOR_MODE.STANDARD and color_mode ~= themes.COLOR_MODE.STD_ON_BLACK
|
||||||
|
|
||||||
|
if color_mode == themes.COLOR_MODE.STANDARD or color_mode == themes.COLOR_MODE.BLUE_IND then
|
||||||
|
style.ind_bkg = colors.gray
|
||||||
|
else
|
||||||
|
style.ind_bkg = colors.black
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return style
|
return style
|
||||||
|
39
rtu/rtu.lua
39
rtu/rtu.lua
@ -5,6 +5,8 @@ local log = require("scada-common.log")
|
|||||||
local types = require("scada-common.types")
|
local types = require("scada-common.types")
|
||||||
local util = require("scada-common.util")
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
|
local themes = require("graphics.themes")
|
||||||
|
|
||||||
local databus = require("rtu.databus")
|
local databus = require("rtu.databus")
|
||||||
local modbus = require("rtu.modbus")
|
local modbus = require("rtu.modbus")
|
||||||
|
|
||||||
@ -69,7 +71,7 @@ function rtu.load_config()
|
|||||||
cfv.assert_type_int(config.FrontPanelTheme)
|
cfv.assert_type_int(config.FrontPanelTheme)
|
||||||
cfv.assert_range(config.FrontPanelTheme, 1, 2)
|
cfv.assert_range(config.FrontPanelTheme, 1, 2)
|
||||||
cfv.assert_type_int(config.ColorMode)
|
cfv.assert_type_int(config.ColorMode)
|
||||||
cfv.assert_range(config.ColorMode, 1, 4)
|
cfv.assert_range(config.ColorMode, 1, themes.COLOR_MODE.NUM_MODES)
|
||||||
|
|
||||||
cfv.assert_type_table(config.Peripherals)
|
cfv.assert_type_table(config.Peripherals)
|
||||||
cfv.assert_type_table(config.Redstone)
|
cfv.assert_type_table(config.Redstone)
|
||||||
@ -92,6 +94,8 @@ function rtu.init_unit(device)
|
|||||||
|
|
||||||
local insert = table.insert
|
local insert = table.insert
|
||||||
|
|
||||||
|
local stub = function () log.warning("tried to call an RTU function stub") end
|
||||||
|
|
||||||
---@class rtu_device
|
---@class rtu_device
|
||||||
local public = {}
|
local public = {}
|
||||||
|
|
||||||
@ -113,13 +117,26 @@ function rtu.init_unit(device)
|
|||||||
return self.io_count_cache[1], self.io_count_cache[2], self.io_count_cache[3], self.io_count_cache[4]
|
return self.io_count_cache[1], self.io_count_cache[2], self.io_count_cache[3], self.io_count_cache[4]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- pass a function through or generate one to call a function by name from the device
|
||||||
|
---@param f function|string function or device function name
|
||||||
|
local function _as_func(f)
|
||||||
|
if type(f) == "string" then
|
||||||
|
local name = f
|
||||||
|
if device then
|
||||||
|
f = function (...) return device[name](...) end
|
||||||
|
else f = stub end
|
||||||
|
end
|
||||||
|
|
||||||
|
return f
|
||||||
|
end
|
||||||
|
|
||||||
-- discrete inputs: single bit read-only
|
-- discrete inputs: single bit read-only
|
||||||
|
|
||||||
-- connect discrete input
|
-- connect discrete input
|
||||||
---@param f function
|
---@param f function|string function or function name
|
||||||
---@return integer count count of discrete inputs
|
---@return integer count count of discrete inputs
|
||||||
function protected.connect_di(f)
|
function protected.connect_di(f)
|
||||||
insert(self.discrete_inputs, { read = f })
|
insert(self.discrete_inputs, { read = _as_func(f) })
|
||||||
_count_io()
|
_count_io()
|
||||||
return #self.discrete_inputs
|
return #self.discrete_inputs
|
||||||
end
|
end
|
||||||
@ -135,11 +152,11 @@ function rtu.init_unit(device)
|
|||||||
-- coils: single bit read-write
|
-- coils: single bit read-write
|
||||||
|
|
||||||
-- connect coil
|
-- connect coil
|
||||||
---@param f_read function
|
---@param f_read function|string function or function name
|
||||||
---@param f_write function
|
---@param f_write function|string function or function name
|
||||||
---@return integer count count of coils
|
---@return integer count count of coils
|
||||||
function protected.connect_coil(f_read, f_write)
|
function protected.connect_coil(f_read, f_write)
|
||||||
insert(self.coils, { read = f_read, write = f_write })
|
insert(self.coils, { read = _as_func(f_read), write = _as_func(f_write) })
|
||||||
_count_io()
|
_count_io()
|
||||||
return #self.coils
|
return #self.coils
|
||||||
end
|
end
|
||||||
@ -164,10 +181,10 @@ function rtu.init_unit(device)
|
|||||||
-- input registers: multi-bit read-only
|
-- input registers: multi-bit read-only
|
||||||
|
|
||||||
-- connect input register
|
-- connect input register
|
||||||
---@param f function
|
---@param f function|string function or function name
|
||||||
---@return integer count count of input registers
|
---@return integer count count of input registers
|
||||||
function protected.connect_input_reg(f)
|
function protected.connect_input_reg(f)
|
||||||
insert(self.input_regs, { read = f })
|
insert(self.input_regs, { read = _as_func(f) })
|
||||||
_count_io()
|
_count_io()
|
||||||
return #self.input_regs
|
return #self.input_regs
|
||||||
end
|
end
|
||||||
@ -183,11 +200,11 @@ function rtu.init_unit(device)
|
|||||||
-- holding registers: multi-bit read-write
|
-- holding registers: multi-bit read-write
|
||||||
|
|
||||||
-- connect holding register
|
-- connect holding register
|
||||||
---@param f_read function
|
---@param f_read function|string function or function name
|
||||||
---@param f_write function
|
---@param f_write function|string function or function name
|
||||||
---@return integer count count of holding registers
|
---@return integer count count of holding registers
|
||||||
function protected.connect_holding_reg(f_read, f_write)
|
function protected.connect_holding_reg(f_read, f_write)
|
||||||
insert(self.holding_regs, { read = f_read, write = f_write })
|
insert(self.holding_regs, { read = _as_func(f_read), write = _as_func(f_write) })
|
||||||
_count_io()
|
_count_io()
|
||||||
return #self.holding_regs
|
return #self.holding_regs
|
||||||
end
|
end
|
||||||
|
@ -31,7 +31,7 @@ local sna_rtu = require("rtu.dev.sna_rtu")
|
|||||||
local sps_rtu = require("rtu.dev.sps_rtu")
|
local sps_rtu = require("rtu.dev.sps_rtu")
|
||||||
local turbinev_rtu = require("rtu.dev.turbinev_rtu")
|
local turbinev_rtu = require("rtu.dev.turbinev_rtu")
|
||||||
|
|
||||||
local RTU_VERSION = "v1.8.0"
|
local RTU_VERSION = "v1.9.3"
|
||||||
|
|
||||||
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
||||||
local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE
|
local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE
|
||||||
@ -71,6 +71,7 @@ log.info("========================================")
|
|||||||
println(">> RTU GATEWAY " .. RTU_VERSION .. " <<")
|
println(">> RTU GATEWAY " .. RTU_VERSION .. " <<")
|
||||||
|
|
||||||
crash.set_env("rtu", RTU_VERSION)
|
crash.set_env("rtu", RTU_VERSION)
|
||||||
|
crash.dbg_log_env()
|
||||||
|
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
-- main application
|
-- main application
|
||||||
@ -342,7 +343,7 @@ local function main()
|
|||||||
is_multiblock = true
|
is_multiblock = true
|
||||||
formed = device.isFormed()
|
formed = device.isFormed()
|
||||||
|
|
||||||
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
if formed == ppm.ACCESS_FAULT then
|
||||||
println_ts(util.c("sys_config> failed to check if '", name, "' is formed"))
|
println_ts(util.c("sys_config> failed to check if '", name, "' is formed"))
|
||||||
log.fatal(util.c("sys_config> failed to check if '", name, "' is a formed boiler multiblock"))
|
log.fatal(util.c("sys_config> failed to check if '", name, "' is a formed boiler multiblock"))
|
||||||
return false
|
return false
|
||||||
@ -357,7 +358,7 @@ local function main()
|
|||||||
is_multiblock = true
|
is_multiblock = true
|
||||||
formed = device.isFormed()
|
formed = device.isFormed()
|
||||||
|
|
||||||
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
if formed == ppm.ACCESS_FAULT then
|
||||||
println_ts(util.c("sys_config> failed to check if '", name, "' is formed"))
|
println_ts(util.c("sys_config> failed to check if '", name, "' is formed"))
|
||||||
log.fatal(util.c("sys_config> failed to check if '", name, "' is a formed turbine multiblock"))
|
log.fatal(util.c("sys_config> failed to check if '", name, "' is a formed turbine multiblock"))
|
||||||
return false
|
return false
|
||||||
@ -377,7 +378,7 @@ local function main()
|
|||||||
is_multiblock = true
|
is_multiblock = true
|
||||||
formed = device.isFormed()
|
formed = device.isFormed()
|
||||||
|
|
||||||
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
if formed == ppm.ACCESS_FAULT then
|
||||||
println_ts(util.c("sys_config> failed to check if '", name, "' is formed"))
|
println_ts(util.c("sys_config> failed to check if '", name, "' is formed"))
|
||||||
log.fatal(util.c("sys_config> failed to check if '", name, "' is a formed dynamic tank multiblock"))
|
log.fatal(util.c("sys_config> failed to check if '", name, "' is a formed dynamic tank multiblock"))
|
||||||
return false
|
return false
|
||||||
@ -391,7 +392,7 @@ local function main()
|
|||||||
is_multiblock = true
|
is_multiblock = true
|
||||||
formed = device.isFormed()
|
formed = device.isFormed()
|
||||||
|
|
||||||
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
if formed == ppm.ACCESS_FAULT then
|
||||||
println_ts(util.c("sys_config> failed to check if '", name, "' is formed"))
|
println_ts(util.c("sys_config> failed to check if '", name, "' is formed"))
|
||||||
log.fatal(util.c("sys_config> failed to check if '", name, "' is a formed induction matrix multiblock"))
|
log.fatal(util.c("sys_config> failed to check if '", name, "' is a formed induction matrix multiblock"))
|
||||||
return false
|
return false
|
||||||
@ -405,7 +406,7 @@ local function main()
|
|||||||
is_multiblock = true
|
is_multiblock = true
|
||||||
formed = device.isFormed()
|
formed = device.isFormed()
|
||||||
|
|
||||||
if formed == ppm.UNDEFINED_FIELD or formed == ppm.ACCESS_FAULT then
|
if formed == ppm.ACCESS_FAULT then
|
||||||
println_ts(util.c("sys_config> failed to check if '", name, "' is formed"))
|
println_ts(util.c("sys_config> failed to check if '", name, "' is formed"))
|
||||||
log.fatal(util.c("sys_config> failed to check if '", name, "' is a formed SPS multiblock"))
|
log.fatal(util.c("sys_config> failed to check if '", name, "' is a formed SPS multiblock"))
|
||||||
return false
|
return false
|
||||||
@ -471,7 +472,8 @@ local function main()
|
|||||||
for_message = util.c("reactor ", for_reactor)
|
for_message = util.c("reactor ", for_reactor)
|
||||||
end
|
end
|
||||||
|
|
||||||
log.info(util.c("sys_config> initialized RTU unit #", #units, ": ", name, " (", types.rtu_type_to_string(rtu_type), ") [", index, "] for ", for_message))
|
local index_str = util.trinary(index ~= nil, util.c(" [", index, "]"), "")
|
||||||
|
log.info(util.c("sys_config> initialized RTU unit #", #units, ": ", name, " (", types.rtu_type_to_string(rtu_type), ")", index_str, " for ", for_message))
|
||||||
|
|
||||||
rtu_unit.uid = #units
|
rtu_unit.uid = #units
|
||||||
|
|
||||||
|
@ -517,82 +517,23 @@ function threads.thread__unit_comms(smem, unit)
|
|||||||
|
|
||||||
-- check if multiblock is still formed if this is a multiblock
|
-- check if multiblock is still formed if this is a multiblock
|
||||||
if unit.is_multiblock and (util.time_ms() - last_f_check > 250) then
|
if unit.is_multiblock and (util.time_ms() - last_f_check > 250) then
|
||||||
local is_formed = unit.device.isFormed()
|
|
||||||
|
|
||||||
last_f_check = util.time_ms()
|
last_f_check = util.time_ms()
|
||||||
|
|
||||||
|
local is_formed = unit.device.isFormed()
|
||||||
|
|
||||||
if unit.formed == nil then
|
if unit.formed == nil then
|
||||||
unit.formed = is_formed
|
unit.formed = is_formed
|
||||||
if is_formed then unit.hw_state = UNIT_HW_STATE.OK end
|
if is_formed then unit.hw_state = UNIT_HW_STATE.OK end
|
||||||
end
|
elseif not unit.formed then
|
||||||
|
|
||||||
if not unit.formed then unit.hw_state = UNIT_HW_STATE.UNFORMED end
|
|
||||||
|
|
||||||
if (not unit.formed) and is_formed then
|
|
||||||
-- newly re-formed
|
|
||||||
local iface = ppm.get_iface(unit.device)
|
|
||||||
if iface then
|
|
||||||
log.info(util.c("unmounting and remounting reformed RTU unit ", detail_name))
|
|
||||||
|
|
||||||
ppm.unmount(unit.device)
|
|
||||||
|
|
||||||
local type, device = ppm.mount(iface)
|
|
||||||
local faulted = false
|
|
||||||
|
|
||||||
if device ~= nil then
|
|
||||||
if type == "boilerValve" and unit.type == RTU_UNIT_TYPE.BOILER_VALVE then
|
|
||||||
-- boiler multiblock
|
|
||||||
unit.device = device
|
|
||||||
unit.rtu, faulted = boilerv_rtu.new(device)
|
|
||||||
unit.formed = device.isFormed()
|
|
||||||
unit.modbus_io = modbus.new(unit.rtu, true)
|
|
||||||
elseif type == "turbineValve" and unit.type == RTU_UNIT_TYPE.TURBINE_VALVE then
|
|
||||||
-- turbine multiblock
|
|
||||||
unit.device = device
|
|
||||||
unit.rtu, faulted = turbinev_rtu.new(device)
|
|
||||||
unit.formed = device.isFormed()
|
|
||||||
unit.modbus_io = modbus.new(unit.rtu, true)
|
|
||||||
elseif type == "dynamicValve" and unit.type == RTU_UNIT_TYPE.DYNAMIC_VALVE then
|
|
||||||
-- dynamic tank multiblock
|
|
||||||
unit.device = device
|
|
||||||
unit.rtu, faulted = dynamicv_rtu.new(device)
|
|
||||||
unit.formed = device.isFormed()
|
|
||||||
unit.modbus_io = modbus.new(unit.rtu, true)
|
|
||||||
elseif type == "inductionPort" and unit.type == RTU_UNIT_TYPE.IMATRIX then
|
|
||||||
-- induction matrix multiblock
|
|
||||||
unit.device = device
|
|
||||||
unit.rtu, faulted = imatrix_rtu.new(device)
|
|
||||||
unit.formed = device.isFormed()
|
|
||||||
unit.modbus_io = modbus.new(unit.rtu, true)
|
|
||||||
elseif type == "spsPort" and unit.type == RTU_UNIT_TYPE.SPS then
|
|
||||||
-- SPS multiblock
|
|
||||||
unit.device = device
|
|
||||||
unit.rtu, faulted = sps_rtu.new(device)
|
|
||||||
unit.formed = device.isFormed()
|
|
||||||
unit.modbus_io = modbus.new(unit.rtu, true)
|
|
||||||
else
|
|
||||||
log.error("illegal remount of non-multiblock RTU or type change attempted for " .. short_name, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
if unit.formed and faulted then
|
|
||||||
-- something is still wrong = can't mark as formed yet
|
|
||||||
unit.formed = false
|
|
||||||
unit.hw_state = UNIT_HW_STATE.UNFORMED
|
unit.hw_state = UNIT_HW_STATE.UNFORMED
|
||||||
log.info(util.c("assuming ", unit.name, " is not formed due to PPM faults while initializing"))
|
|
||||||
else
|
|
||||||
unit.hw_state = UNIT_HW_STATE.OK
|
|
||||||
rtu_comms.send_remounted(unit.uid)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local type_name = types.rtu_type_to_string(unit.type)
|
if (is_formed == true) and not unit.formed then
|
||||||
log.info(util.c("reconnected the ", type_name, " on interface ", unit.name))
|
unit.hw_state = UNIT_HW_STATE.OK
|
||||||
else
|
log.info(util.c(detail_name, " is now formed"))
|
||||||
-- fully lost the peripheral now :(
|
rtu_comms.send_remounted(unit.uid)
|
||||||
log.error(util.c(unit.name, " lost (failed reconnect)"))
|
elseif (is_formed == false) and unit.formed then
|
||||||
end
|
log.warning(util.c(detail_name, " is no longer formed"))
|
||||||
else
|
|
||||||
log.error("failed to get interface of previously connected RTU unit " .. detail_name, true)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
unit.formed = is_formed
|
unit.formed = is_formed
|
||||||
|
@ -24,6 +24,21 @@ function crash.set_env(application, version)
|
|||||||
ver = version
|
ver = version
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- log environment versions
|
||||||
|
---@param log_msg function log function to use
|
||||||
|
local function log_versions(log_msg)
|
||||||
|
log_msg(util.c("RUNTIME: ", _HOST))
|
||||||
|
log_msg(util.c("LUA VERSION: ", _VERSION))
|
||||||
|
log_msg(util.c("APPLICATION: ", app))
|
||||||
|
log_msg(util.c("FIRMWARE VERSION: ", ver))
|
||||||
|
log_msg(util.c("COMMS VERSION: ", comms.version))
|
||||||
|
if has_graphics then log_msg(util.c("GRAPHICS VERSION: ", core.version)) end
|
||||||
|
if has_lockbox then log_msg(util.c("LOCKBOX VERSION: ", lockbox.version)) end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- when running with debug logs, log the useful information that the crash handler knows
|
||||||
|
function crash.dbg_log_env() log_versions(log.debug) end
|
||||||
|
|
||||||
-- handle a crash error
|
-- handle a crash error
|
||||||
---@param error string error message
|
---@param error string error message
|
||||||
function crash.handler(error)
|
function crash.handler(error)
|
||||||
@ -31,13 +46,7 @@ function crash.handler(error)
|
|||||||
log.info("=====> FATAL SOFTWARE FAULT <=====")
|
log.info("=====> FATAL SOFTWARE FAULT <=====")
|
||||||
log.fatal(error)
|
log.fatal(error)
|
||||||
log.info("----------------------------------")
|
log.info("----------------------------------")
|
||||||
log.info(util.c("RUNTIME: ", _HOST))
|
log_versions(log.info)
|
||||||
log.info(util.c("LUA VERSION: ", _VERSION))
|
|
||||||
log.info(util.c("APPLICATION: ", app))
|
|
||||||
log.info(util.c("FIRMWARE VERSION: ", ver))
|
|
||||||
log.info(util.c("COMMS VERSION: ", comms.version))
|
|
||||||
if has_graphics then log.info(util.c("GRAPHICS VERSION: ", core.version)) end
|
|
||||||
if has_lockbox then log.info(util.c("LOCKBOX VERSION: ", lockbox.version)) end
|
|
||||||
log.info("----------------------------------")
|
log.info("----------------------------------")
|
||||||
log.info(debug.traceback("--- begin debug trace ---", 1))
|
log.info(debug.traceback("--- begin debug trace ---", 1))
|
||||||
log.info("--- end debug trace ---")
|
log.info("--- end debug trace ---")
|
||||||
|
@ -51,11 +51,13 @@ local function peri_init(iface)
|
|||||||
self.device = peripheral.wrap(iface)
|
self.device = peripheral.wrap(iface)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- initialization process (re-map)
|
-- create a protected version of a peripheral function call
|
||||||
|
---@nodiscard
|
||||||
for key, func in pairs(self.device) do
|
---@param key string function name
|
||||||
self.fault_counts[key] = 0
|
---@param func function function
|
||||||
self.device[key] = function (...)
|
---@return function method protected version of the function
|
||||||
|
local function protect_peri_function(key, func)
|
||||||
|
return function (...)
|
||||||
local return_table = table.pack(pcall(func, ...))
|
local return_table = table.pack(pcall(func, ...))
|
||||||
|
|
||||||
local status = return_table[1]
|
local status = return_table[1]
|
||||||
@ -85,18 +87,22 @@ local function peri_init(iface)
|
|||||||
count_str = " [" .. self.fault_counts[key] .. " total faults]"
|
count_str = " [" .. self.fault_counts[key] .. " total faults]"
|
||||||
end
|
end
|
||||||
|
|
||||||
log.error(util.c("PPM: protected ", key, "() -> ", result, count_str))
|
log.error(util.c("PPM: [@", iface, "] protected ", key, "() -> ", result, count_str))
|
||||||
end
|
end
|
||||||
|
|
||||||
self.fault_counts[key] = self.fault_counts[key] + 1
|
self.fault_counts[key] = self.fault_counts[key] + 1
|
||||||
|
|
||||||
if result == "Terminated" then
|
if result == "Terminated" then ppm_sys.terminate = true end
|
||||||
ppm_sys.terminate = true
|
|
||||||
|
return ACCESS_FAULT, result
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return ACCESS_FAULT
|
-- initialization process (re-map)
|
||||||
end
|
for key, func in pairs(self.device) do
|
||||||
end
|
self.fault_counts[key] = 0
|
||||||
|
self.device[key] = protect_peri_function(key, func)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- fault management & monitoring functions
|
-- fault management & monitoring functions
|
||||||
@ -131,12 +137,21 @@ local function peri_init(iface)
|
|||||||
|
|
||||||
local mt = {
|
local mt = {
|
||||||
__index = function (_, key)
|
__index = function (_, key)
|
||||||
|
-- try to find the function in case it was added (multiblock formed)
|
||||||
|
local funcs = peripheral.wrap(iface)
|
||||||
|
if (type(funcs) == "table") and (type(funcs[key]) == "function") then
|
||||||
|
-- add this function then return it
|
||||||
|
self.device[key] = protect_peri_function(key, funcs[key])
|
||||||
|
log.info(util.c("PPM: [@", iface, "] initialized previously undefined field ", key, "()"))
|
||||||
|
|
||||||
|
return self.device[key]
|
||||||
|
end
|
||||||
|
|
||||||
|
-- function still missing, return an undefined function handler
|
||||||
|
-- note: code should avoid storing functions for multiblocks and instead try to index them again
|
||||||
return (function ()
|
return (function ()
|
||||||
-- this will continuously be counting calls here as faults
|
-- this will continuously be counting calls here as faults
|
||||||
-- unlike other functions, faults here can't be cleared as it is just not defined
|
if self.fault_counts[key] == nil then self.fault_counts[key] = 0 end
|
||||||
if self.fault_counts[key] == nil then
|
|
||||||
self.fault_counts[key] = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
-- function failed
|
-- function failed
|
||||||
self.faulted = true
|
self.faulted = true
|
||||||
@ -151,12 +166,12 @@ local function peri_init(iface)
|
|||||||
count_str = " [" .. self.fault_counts[key] .. " total calls]"
|
count_str = " [" .. self.fault_counts[key] .. " total calls]"
|
||||||
end
|
end
|
||||||
|
|
||||||
log.error(util.c("PPM: caught undefined function ", key, "()", count_str))
|
log.error(util.c("PPM: [@", iface, "] caught undefined function ", key, "()", count_str))
|
||||||
end
|
end
|
||||||
|
|
||||||
self.fault_counts[key] = self.fault_counts[key] + 1
|
self.fault_counts[key] = self.fault_counts[key] + 1
|
||||||
|
|
||||||
return UNDEFINED_FIELD
|
return ACCESS_FAULT, UNDEFINED_FIELD
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ local t_pack = table.pack
|
|||||||
local util = {}
|
local util = {}
|
||||||
|
|
||||||
-- scada-common version
|
-- scada-common version
|
||||||
util.version = "1.1.19"
|
util.version = "1.2.0"
|
||||||
|
|
||||||
util.TICK_TIME_S = 0.05
|
util.TICK_TIME_S = 0.05
|
||||||
util.TICK_TIME_MS = 50
|
util.TICK_TIME_MS = 50
|
||||||
|
@ -36,7 +36,8 @@ local RIGHT = core.ALIGN.RIGHT
|
|||||||
|
|
||||||
-- changes to the config data/format to let the user know
|
-- changes to the config data/format to let the user know
|
||||||
local changes = {
|
local changes = {
|
||||||
{ "v1.2.12", { "Added front panel UI theme", "Added color accessibility modes" } }
|
{ "v1.2.12", { "Added front panel UI theme", "Added color accessibility modes" } },
|
||||||
|
{ "v1.3.2", { "Added standard with black off state color mode", "Added blue indicator color modes" } }
|
||||||
}
|
}
|
||||||
|
|
||||||
---@class svr_configurator
|
---@class svr_configurator
|
||||||
@ -205,7 +206,7 @@ local function config_view(display)
|
|||||||
end
|
end
|
||||||
|
|
||||||
PushButton{parent=main_page,x=2,y=17,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=btn_act_fg_bg}
|
PushButton{parent=main_page,x=2,y=17,min_width=6,text="Exit",callback=exit,fg_bg=cpair(colors.black,colors.red),active_fg_bg=btn_act_fg_bg}
|
||||||
tool_ctl.color_cfg = PushButton{parent=main_page,x=23,y=17,min_width=15,text="Color Options",callback=jump_color,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
tool_ctl.color_cfg = PushButton{parent=main_page,x=23,y=17,min_width=15,text="Color Options",callback=jump_color,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg,dis_fg_bg=cpair(colors.lightGray,colors.white)}
|
||||||
PushButton{parent=main_page,x=39,y=17,min_width=12,text="Change Log",callback=function()main_pane.set_value(7)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
PushButton{parent=main_page,x=39,y=17,min_width=12,text="Change Log",callback=function()main_pane.set_value(7)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||||
|
|
||||||
if not tool_ctl.has_config then
|
if not tool_ctl.has_config then
|
||||||
@ -761,12 +762,27 @@ local function config_view(display)
|
|||||||
TextBox{parent=clr_c_1,x=1,y=7,height=1,text="Front Panel Theme"}
|
TextBox{parent=clr_c_1,x=1,y=7,height=1,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,callback=function()end,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
local fp_theme = RadioButton{parent=clr_c_1,x=1,y=8,default=ini_cfg.FrontPanelTheme,options=themes.FP_THEME_NAMES,callback=function()end,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
||||||
|
|
||||||
TextBox{parent=clr_c_2,x=1,y=1,height=6,text="By default, this project uses green/red heavily to distinguish ok and not, with some indicators also using multiple colors. By selecting a color blindness below, blues will be used instead of greens on indicators and multi-color indicators will be split up as space permits."}
|
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,x=21,y=7,height=1,text="Preview"}
|
||||||
|
local _ = IndLight{parent=clr_c_2,x=21,y=8,label="Good",colors=cpair(colors.black,colors.green)}
|
||||||
|
_ = IndLight{parent=clr_c_2,x=21,y=9,label="Warning",colors=cpair(colors.black,colors.yellow)}
|
||||||
|
_ = IndLight{parent=clr_c_2,x=21,y=10,label="Bad",colors=cpair(colors.black,colors.red)}
|
||||||
|
local b_off = IndLight{parent=clr_c_2,x=21,y=11,label="Off",colors=cpair(colors.black,colors.black),hidden=true}
|
||||||
|
local g_off = IndLight{parent=clr_c_2,x=21,y=11,label="Off",colors=cpair(colors.gray,colors.gray),hidden=true}
|
||||||
|
|
||||||
local function recolor(value)
|
local function recolor(value)
|
||||||
local c = themes.smooth_stone.color_modes[value]
|
local c = themes.smooth_stone.color_modes[value]
|
||||||
|
|
||||||
if value == 1 then
|
if value == themes.COLOR_MODE.STANDARD or value == themes.COLOR_MODE.BLUE_IND then
|
||||||
|
b_off.hide()
|
||||||
|
g_off.show()
|
||||||
|
else
|
||||||
|
g_off.hide()
|
||||||
|
b_off.show()
|
||||||
|
end
|
||||||
|
|
||||||
|
if #c == 0 then
|
||||||
for i = 1, #style.colors do term.setPaletteColor(style.colors[i].c, style.colors[i].hex) end
|
for i = 1, #style.colors do term.setPaletteColor(style.colors[i].c, style.colors[i].hex) end
|
||||||
else
|
else
|
||||||
term.setPaletteColor(colors.green, c[1].hex)
|
term.setPaletteColor(colors.green, c[1].hex)
|
||||||
@ -775,15 +791,10 @@ local function config_view(display)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
TextBox{parent=clr_c_2,x=1,y=8,height=1,text="Color Mode"}
|
TextBox{parent=clr_c_2,x=1,y=7,height=1,width=10,text="Color Mode"}
|
||||||
local c_mode = RadioButton{parent=clr_c_2,x=1,y=9,default=ini_cfg.ColorMode,options=themes.COLOR_MODE_NAMES,callback=recolor,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.magenta}
|
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,x=20,y=8,height=1,text="Preview"}
|
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}
|
||||||
local _ = IndLight{parent=clr_c_2,x=20,y=9,label="Good",colors=cpair(colors.black,colors.green)}
|
|
||||||
_ = IndLight{parent=clr_c_2,x=20,y=10,label="Warning",colors=cpair(colors.black,colors.yellow)}
|
|
||||||
_ = IndLight{parent=clr_c_2,x=20,y=11,label="Bad",colors=cpair(colors.black,colors.red)}
|
|
||||||
|
|
||||||
TextBox{parent=clr_c_2,x=1,y=14,height=6,text="Note: exact color varies by theme.",fg_bg=g_lg_fg_bg}
|
|
||||||
|
|
||||||
PushButton{parent=clr_c_2,x=44,y=14,min_width=6,text="Done",callback=function()clr_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
PushButton{parent=clr_c_2,x=44,y=14,min_width=6,text="Done",callback=function()clr_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ function style.set_theme(fp, color_mode)
|
|||||||
|
|
||||||
style.fp = themes.get_fp_style(style.theme)
|
style.fp = themes.get_fp_style(style.theme)
|
||||||
|
|
||||||
style.colorblind = color_mode ~= themes.COLOR_MODE.STANDARD
|
style.colorblind = color_mode ~= themes.COLOR_MODE.STANDARD and color_mode ~= themes.COLOR_MODE.STD_ON_BLACK
|
||||||
end
|
end
|
||||||
|
|
||||||
return style
|
return style
|
||||||
|
@ -21,7 +21,7 @@ local supervisor = require("supervisor.supervisor")
|
|||||||
|
|
||||||
local svsessions = require("supervisor.session.svsessions")
|
local svsessions = require("supervisor.session.svsessions")
|
||||||
|
|
||||||
local SUPERVISOR_VERSION = "v1.3.0"
|
local SUPERVISOR_VERSION = "v1.3.4"
|
||||||
|
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local println_ts = util.println_ts
|
local println_ts = util.println_ts
|
||||||
@ -86,6 +86,7 @@ log.info("========================================")
|
|||||||
println(">> SCADA Supervisor " .. SUPERVISOR_VERSION .. " <<")
|
println(">> SCADA Supervisor " .. SUPERVISOR_VERSION .. " <<")
|
||||||
|
|
||||||
crash.set_env("supervisor", SUPERVISOR_VERSION)
|
crash.set_env("supervisor", SUPERVISOR_VERSION)
|
||||||
|
crash.dbg_log_env()
|
||||||
|
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
-- main application
|
-- main application
|
||||||
|
@ -2,6 +2,8 @@ local comms = require("scada-common.comms")
|
|||||||
local log = require("scada-common.log")
|
local log = require("scada-common.log")
|
||||||
local util = require("scada-common.util")
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
|
local themes = require("graphics.themes")
|
||||||
|
|
||||||
local svsessions = require("supervisor.session.svsessions")
|
local svsessions = require("supervisor.session.svsessions")
|
||||||
|
|
||||||
local supervisor = {}
|
local supervisor = {}
|
||||||
@ -87,7 +89,7 @@ function supervisor.load_config()
|
|||||||
cfv.assert_type_int(config.FrontPanelTheme)
|
cfv.assert_type_int(config.FrontPanelTheme)
|
||||||
cfv.assert_range(config.FrontPanelTheme, 1, 2)
|
cfv.assert_range(config.FrontPanelTheme, 1, 2)
|
||||||
cfv.assert_type_int(config.ColorMode)
|
cfv.assert_type_int(config.ColorMode)
|
||||||
cfv.assert_range(config.ColorMode, 1, 4)
|
cfv.assert_range(config.ColorMode, 1, themes.COLOR_MODE.NUM_MODES)
|
||||||
|
|
||||||
return cfv.valid()
|
return cfv.valid()
|
||||||
end
|
end
|
||||||
|
@ -730,6 +730,8 @@ end
|
|||||||
function logic.handle_redstone(self)
|
function logic.handle_redstone(self)
|
||||||
local AISTATE = self.types.AISTATE
|
local AISTATE = self.types.AISTATE
|
||||||
local annunc = self.db.annunciator
|
local annunc = self.db.annunciator
|
||||||
|
local cache = self.plc_cache
|
||||||
|
local rps = cache.rps_status
|
||||||
|
|
||||||
-- check if an alarm is active (tripped or ack'd)
|
-- check if an alarm is active (tripped or ack'd)
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
@ -741,18 +743,18 @@ function logic.handle_redstone(self)
|
|||||||
|
|
||||||
-- reactor controls
|
-- reactor controls
|
||||||
if self.plc_s ~= nil then
|
if self.plc_s ~= nil then
|
||||||
if (not self.plc_cache.rps_status.manual) and self.io_ctl.digital_read(IO.R_SCRAM) then
|
if (not rps.manual) and self.io_ctl.digital_read(IO.R_SCRAM) then
|
||||||
-- reactor SCRAM requested but not yet done; perform it
|
-- reactor SCRAM requested but not yet done; perform it
|
||||||
self.plc_s.in_queue.push_command(PLC_S_CMDS.SCRAM)
|
self.plc_s.in_queue.push_command(PLC_S_CMDS.SCRAM)
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.plc_cache.rps_trip and self.io_ctl.digital_read(IO.R_RESET) then
|
if cache.rps_trip and self.io_ctl.digital_read(IO.R_RESET) then
|
||||||
-- reactor RPS reset requested but not yet done; perform it
|
-- reactor RPS reset requested but not yet done; perform it
|
||||||
self.plc_s.in_queue.push_command(PLC_S_CMDS.RPS_RESET)
|
self.plc_s.in_queue.push_command(PLC_S_CMDS.RPS_RESET)
|
||||||
end
|
end
|
||||||
|
|
||||||
if (not self.auto_engaged) and (not self.plc_cache.active) and
|
if (not self.auto_engaged) and (not cache.active) and
|
||||||
(not self.plc_cache.rps_trip) and self.io_ctl.digital_read(IO.R_ENABLE) then
|
(not cache.rps_trip) and self.io_ctl.digital_read(IO.R_ENABLE) then
|
||||||
-- reactor enable requested and allowable, but not yet done; perform it
|
-- reactor enable requested and allowable, but not yet done; perform it
|
||||||
self.plc_s.in_queue.push_command(PLC_S_CMDS.ENABLE)
|
self.plc_s.in_queue.push_command(PLC_S_CMDS.ENABLE)
|
||||||
end
|
end
|
||||||
@ -761,25 +763,23 @@ function logic.handle_redstone(self)
|
|||||||
-- check for request to ack all alarms
|
-- check for request to ack all alarms
|
||||||
if self.io_ctl.digital_read(IO.U_ACK) then
|
if self.io_ctl.digital_read(IO.U_ACK) then
|
||||||
for i = 1, #self.db.alarm_states do
|
for i = 1, #self.db.alarm_states do
|
||||||
if self.db.alarm_states[i] == ALARM_STATE.TRIPPED then
|
if self.db.alarm_states[i] == ALARM_STATE.TRIPPED then self.db.alarm_states[i] = ALARM_STATE.ACKED end
|
||||||
self.db.alarm_states[i] = ALARM_STATE.ACKED
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- write reactor status outputs
|
-- write reactor status outputs
|
||||||
self.io_ctl.digital_write(IO.R_ACTIVE, self.plc_cache.active)
|
self.io_ctl.digital_write(IO.R_ACTIVE, cache.active)
|
||||||
self.io_ctl.digital_write(IO.R_AUTO_CTRL, self.auto_engaged)
|
self.io_ctl.digital_write(IO.R_AUTO_CTRL, self.auto_engaged)
|
||||||
self.io_ctl.digital_write(IO.R_SCRAMMED, self.plc_cache.rps_trip)
|
self.io_ctl.digital_write(IO.R_SCRAMMED, cache.rps_trip)
|
||||||
self.io_ctl.digital_write(IO.R_AUTO_SCRAM, self.plc_cache.rps_status.automatic)
|
self.io_ctl.digital_write(IO.R_AUTO_SCRAM, rps.automatic)
|
||||||
self.io_ctl.digital_write(IO.R_HIGH_DMG, self.plc_cache.rps_status.high_dmg)
|
self.io_ctl.digital_write(IO.R_HIGH_DMG, rps.high_dmg)
|
||||||
self.io_ctl.digital_write(IO.R_HIGH_TEMP, self.plc_cache.rps_status.high_temp)
|
self.io_ctl.digital_write(IO.R_HIGH_TEMP, rps.high_temp)
|
||||||
self.io_ctl.digital_write(IO.R_LOW_COOLANT, self.plc_cache.rps_status.low_cool)
|
self.io_ctl.digital_write(IO.R_LOW_COOLANT, rps.low_cool)
|
||||||
self.io_ctl.digital_write(IO.R_EXCESS_HC, self.plc_cache.rps_status.ex_hcool)
|
self.io_ctl.digital_write(IO.R_EXCESS_HC, rps.ex_hcool)
|
||||||
self.io_ctl.digital_write(IO.R_EXCESS_WS, self.plc_cache.rps_status.ex_waste)
|
self.io_ctl.digital_write(IO.R_EXCESS_WS, rps.ex_waste)
|
||||||
self.io_ctl.digital_write(IO.R_INSUFF_FUEL, self.plc_cache.rps_status.no_fuel)
|
self.io_ctl.digital_write(IO.R_INSUFF_FUEL, rps.no_fuel)
|
||||||
self.io_ctl.digital_write(IO.R_PLC_FAULT, self.plc_cache.rps_status.fault)
|
self.io_ctl.digital_write(IO.R_PLC_FAULT, rps.fault)
|
||||||
self.io_ctl.digital_write(IO.R_PLC_TIMEOUT, self.plc_cache.rps_status.timeout)
|
self.io_ctl.digital_write(IO.R_PLC_TIMEOUT, rps.timeout)
|
||||||
|
|
||||||
-- write unit outputs
|
-- write unit outputs
|
||||||
|
|
||||||
@ -797,13 +797,28 @@ function logic.handle_redstone(self)
|
|||||||
-- Emergency Coolant --
|
-- Emergency Coolant --
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
local enable_emer_cool = self.plc_cache.rps_status.low_cool or
|
local boiler_water_low = false
|
||||||
(self.auto_engaged and annunc.CoolantLevelLow and is_active(self.alarms.ReactorOverTemp))
|
for i = 1, #annunc.WaterLevelLow do boiler_water_low = boiler_water_low or annunc.WaterLevelLow[i] end
|
||||||
|
|
||||||
|
local enable_emer_cool = rps.low_cool or
|
||||||
|
(self.auto_engaged and
|
||||||
|
(annunc.CoolantLevelLow or (boiler_water_low and rps.ex_hcool)) and
|
||||||
|
is_active(self.alarms.ReactorOverTemp))
|
||||||
|
|
||||||
|
if enable_emer_cool and not self.emcool_opened then
|
||||||
|
log.debug(util.c(">> Emergency Coolant Enable Detail Report (Unit ", self.r_id, ") <<"))
|
||||||
|
log.debug(util.c("| CoolantLevelLow[", annunc.CoolantLevelLow, "] CoolantLevelLowLow[", rps.low_cool, "] ExcessHeatedCoolant[", rps.ex_hcool, "]"))
|
||||||
|
log.debug(util.c("| ReactorOverTemp[", AISTATE_NAMES[self.alarms.ReactorOverTemp.state], "]"))
|
||||||
|
|
||||||
|
for i = 1, #annunc.WaterLevelLow do
|
||||||
|
log.debug(util.c("| WaterLevelLow(", i, ")[", annunc.WaterLevelLow[i], "]"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- don't turn off emergency coolant on sufficient coolant level since it might drop again
|
-- don't turn off emergency coolant on sufficient coolant level since it might drop again
|
||||||
-- turn off once system is OK again
|
-- turn off once system is OK again
|
||||||
-- if auto control is engaged, alarm check will SCRAM on reactor over temp so that's covered
|
-- if auto control is engaged, alarm check will SCRAM on reactor over temp so that's covered
|
||||||
if not self.plc_cache.rps_trip then
|
if not cache.rps_trip then
|
||||||
-- set turbines to not dump steam
|
-- set turbines to not dump steam
|
||||||
for i = 1, #self.turbines do
|
for i = 1, #self.turbines do
|
||||||
local session = self.turbines[i] ---@type unit_session
|
local session = self.turbines[i] ---@type unit_session
|
||||||
|
Loading…
Reference in New Issue
Block a user