#580 RTU gateway multi-modem wired/wireless failover networking

This commit is contained in:
Mikayla Fischler 2025-10-18 17:23:06 -04:00
parent fe9ee313f9
commit 1fcc91e98b
6 changed files with 162 additions and 42 deletions

View File

@ -134,7 +134,7 @@ local function main()
-- get the configured modem -- get the configured modem
if smem_dev.modem_wired then if smem_dev.modem_wired then
smem_dev.modem = ppm.get_wired_modem(smem_dev.modem_iface) smem_dev.modem = ppm.get_modem(smem_dev.modem_iface)
else smem_dev.modem = ppm.get_wireless_modem() end else smem_dev.modem = ppm.get_wireless_modem() end
-- initial state evaluation -- initial state evaluation

View File

@ -41,7 +41,7 @@ function backplane.init(config, __shared_memory)
-- init wired NIC -- init wired NIC
if _bp.lan_en then if _bp.lan_en then
local modem = ppm.get_wired_modem(_bp.lan_iface) local modem = ppm.get_modem(_bp.lan_iface)
if modem then if modem then
_bp.wd_nic = network.nic(modem) _bp.wd_nic = network.nic(modem)
@ -62,7 +62,7 @@ function backplane.init(config, __shared_memory)
-- grab the preferred active NIC -- grab the preferred active NIC
if _bp.wlan_pref then if _bp.wlan_pref then
_bp.wl_act = true _bp.wl_act = true
_bp.act_nic = _bp.wl_nics[1] _bp.act_nic = _bp.wl_nic
else else
_bp.wl_act = false _bp.wl_act = false
_bp.act_nic = _bp.wd_nic _bp.act_nic = _bp.wd_nic
@ -110,11 +110,11 @@ function backplane.detach(type, device, iface)
local was_wl = wl_nic and wl_nic.is_modem(device) local was_wl = wl_nic and wl_nic.is_modem(device)
if wd_nic and was_wd then if wd_nic and was_wd then
log.info("BKPLN: WIRED PHY_DOWN " .. iface)
wd_nic.disconnect() wd_nic.disconnect()
log.info("BKPLN: WIRED PHY_DOWN " .. iface)
elseif wl_nic and was_wl then elseif wl_nic and was_wl then
log.info("BKPLN: WIRELESS PHY_DOWN " .. iface)
wl_nic.disconnect() wl_nic.disconnect()
log.info("BKPLN: WIRELESS PHY_DOWN " .. iface)
end end
-- we only care if this is our active comms modem -- we only care if this is our active comms modem

View File

@ -90,22 +90,73 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
local net_c_1 = Div{parent=net_cfg,x=2,y=4,width=49} local net_c_1 = Div{parent=net_cfg,x=2,y=4,width=49}
local net_c_2 = Div{parent=net_cfg,x=2,y=4,width=49} local net_c_2 = Div{parent=net_cfg,x=2,y=4,width=49}
local net_c_3 = Div{parent=net_cfg,x=2,y=4,width=49} local net_c_3 = Div{parent=net_cfg,x=2,y=4,width=49}
local net_c_4 = Div{parent=net_cfg,x=2,y=4,width=49}
local net_pane = MultiPane{parent=net_cfg,x=1,y=4,panes={net_c_1,net_c_2,net_c_3}} local net_pane = MultiPane{parent=net_cfg,x=1,y=4,panes={net_c_1,net_c_2,net_c_3,net_c_4}}
TextBox{parent=net_cfg,x=1,y=2,text=" Network Configuration",fg_bg=cpair(colors.black,colors.lightBlue)} TextBox{parent=net_cfg,x=1,y=2,text=" Network Configuration",fg_bg=cpair(colors.black,colors.lightBlue)}
TextBox{parent=net_c_1,x=1,y=1,text="Please set the network channels below."} TextBox{parent=net_c_1,x=1,y=1,text="Please select the network interface(s)."}
TextBox{parent=net_c_1,x=1,y=3,height=4,text="Each of the 5 uniquely named channels, including the 2 below, must be the same for each device in this SCADA network. For multiplayer servers, it is recommended to not use the default channels.",fg_bg=g_lg_fg_bg} TextBox{parent=net_c_1,x=41,y=1,text="new!",fg_bg=cpair(colors.red,colors._INHERIT)} ---@todo remove NEW tag on next revision
TextBox{parent=net_c_1,x=1,y=8,text="Supervisor Channel"} local wl_pref = Checkbox{parent=net_c_1,x=30,y=3,label="Prefer Wireless",default=ini_cfg.PreferWireless,box_fg_bg=cpair(colors.lightBlue,colors.black),disable_fg_bg=g_lg_fg_bg,callback=function()end}
local svr_chan = NumberField{parent=net_c_1,x=1,y=9,width=7,default=ini_cfg.SVR_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
TextBox{parent=net_c_1,x=9,y=9,height=4,text="[SVR_CHANNEL]",fg_bg=g_lg_fg_bg}
TextBox{parent=net_c_1,x=1,y=11,text="RTU Channel"}
local rtu_chan = NumberField{parent=net_c_1,x=1,y=12,width=7,default=ini_cfg.RTU_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
TextBox{parent=net_c_1,x=9,y=12,height=4,text="[RTU_CHANNEL]",fg_bg=g_lg_fg_bg}
local chan_err = TextBox{parent=net_c_1,x=8,y=14,width=35,text="",fg_bg=cpair(colors.red,colors.lightGray),hidden=true} local function dis_pref(value)
if not value then
wl_pref.set_value(false)
wl_pref.disable()
else wl_pref.enable() end
end
dis_pref(ini_cfg.WirelessModem)
local function on_wired_change(value)
tool_ctl.gen_modem_list(value)
end
local wireless = Checkbox{parent=net_c_1,x=1,y=3,label="Wireless/Ender Modem",default=ini_cfg.WirelessModem,box_fg_bg=cpair(colors.lightBlue,colors.black),callback=dis_pref}
local wired = Checkbox{parent=net_c_1,x=1,y=5,label="Wired Modem",default=ini_cfg.WiredModem~=false,box_fg_bg=cpair(colors.lightBlue,colors.black),callback=on_wired_change}
TextBox{parent=net_c_1,x=3,y=6,text="MUST ONLY connect to SCADA computers",fg_bg=cpair(colors.red,colors._INHERIT)}
TextBox{parent=net_c_1,x=3,y=7,text="connecting to peripherals will cause problems",fg_bg=g_lg_fg_bg}
local modem_list = ListBox{parent=net_c_1,x=1,y=8,height=5,width=49,scroll_height=100,fg_bg=bw_fg_bg,nav_fg_bg=g_lg_fg_bg,nav_active=cpair(colors.black,colors.gray)}
local modem_err = TextBox{parent=net_c_1,x=8,y=14,width=35,text="",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
local function submit_interfaces()
tmp_cfg.WirelessModem = wireless.get_value()
tmp_cfg.PreferWireless = wl_pref.get_value()
if not wired.get_value() then
tmp_cfg.WiredModem = false
tool_ctl.gen_modem_list()
end
if not (wired.get_value() or wireless.get_value()) then
modem_err.set_value("Please select a modem type.")
modem_err.show()
elseif wired.get_value() and type(tmp_cfg.WiredModem) ~= "string" then
modem_err.set_value("Please select a wired modem.")
modem_err.show()
else
net_pane.set_value(2)
modem_err.hide(true)
end
end
PushButton{parent=net_c_1,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
PushButton{parent=net_c_1,x=44,y=14,text="Next \x1a",callback=submit_interfaces,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
TextBox{parent=net_c_2,x=1,y=1,text="Please set the network channels below."}
TextBox{parent=net_c_2,x=1,y=3,height=4,text="Each of the 5 uniquely named channels, including the 2 below, must be the same for each device in this SCADA network. For multiplayer servers, it is recommended to not use the default channels.",fg_bg=g_lg_fg_bg}
TextBox{parent=net_c_2,x=1,y=8,text="Supervisor Channel"}
local svr_chan = NumberField{parent=net_c_2,x=1,y=9,width=7,default=ini_cfg.SVR_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
TextBox{parent=net_c_2,x=9,y=9,height=4,text="[SVR_CHANNEL]",fg_bg=g_lg_fg_bg}
TextBox{parent=net_c_2,x=1,y=11,text="RTU Channel"}
local rtu_chan = NumberField{parent=net_c_2,x=1,y=12,width=7,default=ini_cfg.RTU_Channel,min=1,max=65535,fg_bg=bw_fg_bg}
TextBox{parent=net_c_2,x=9,y=12,height=4,text="[RTU_CHANNEL]",fg_bg=g_lg_fg_bg}
local chan_err = TextBox{parent=net_c_2,x=8,y=14,width=35,text="",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
local function submit_channels() local function submit_channels()
local svr_c = tonumber(svr_chan.get_value()) local svr_c = tonumber(svr_chan.get_value())
@ -113,7 +164,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
if svr_c ~= nil and rtu_c ~= nil then if svr_c ~= nil and rtu_c ~= nil then
tmp_cfg.SVR_Channel = svr_c tmp_cfg.SVR_Channel = svr_c
tmp_cfg.RTU_Channel = rtu_c tmp_cfg.RTU_Channel = rtu_c
net_pane.set_value(2) net_pane.set_value(3)
chan_err.hide(true) chan_err.hide(true)
elseif svr_c == nil then elseif svr_c == nil then
chan_err.set_value("Please set the supervisor channel.") chan_err.set_value("Please set the supervisor channel.")
@ -124,19 +175,19 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
end end
end end
PushButton{parent=net_c_1,x=1,y=14,text="\x1b Back",callback=function()main_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} PushButton{parent=net_c_2,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
PushButton{parent=net_c_1,x=44,y=14,text="Next \x1a",callback=submit_channels,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} PushButton{parent=net_c_2,x=44,y=14,text="Next \x1a",callback=submit_channels,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
TextBox{parent=net_c_2,x=1,y=1,text="Connection Timeout"} TextBox{parent=net_c_3,x=1,y=1,text="Connection Timeout"}
local timeout = NumberField{parent=net_c_2,x=1,y=2,width=7,default=ini_cfg.ConnTimeout,min=2,max=25,max_chars=6,max_frac_digits=2,allow_decimal=true,fg_bg=bw_fg_bg} local timeout = NumberField{parent=net_c_3,x=1,y=2,width=7,default=ini_cfg.ConnTimeout,min=2,max=25,max_chars=6,max_frac_digits=2,allow_decimal=true,fg_bg=bw_fg_bg}
TextBox{parent=net_c_2,x=9,y=2,height=2,text="seconds (default 5)",fg_bg=g_lg_fg_bg} TextBox{parent=net_c_3,x=9,y=2,height=2,text="seconds (default 5)",fg_bg=g_lg_fg_bg}
TextBox{parent=net_c_2,x=1,y=3,height=4,text="You generally do not want or need to modify this. On slow servers, you can increase this to make the system wait longer before assuming a disconnection.",fg_bg=g_lg_fg_bg} TextBox{parent=net_c_3,x=1,y=3,height=4,text="You generally do not want or need to modify this. On slow servers, you can increase this to make the system wait longer before assuming a disconnection.",fg_bg=g_lg_fg_bg}
TextBox{parent=net_c_2,x=1,y=8,text="Trusted Range"} TextBox{parent=net_c_3,x=1,y=8,text="Trusted Range (Wireless Only)"}
local range = NumberField{parent=net_c_2,x=1,y=9,width=10,default=ini_cfg.TrustedRange,min=0,max_chars=20,allow_decimal=true,fg_bg=bw_fg_bg} local range = NumberField{parent=net_c_3,x=1,y=9,width=10,default=ini_cfg.TrustedRange,min=0,max_chars=20,allow_decimal=true,fg_bg=bw_fg_bg}
TextBox{parent=net_c_2,x=1,y=10,height=4,text="Setting this to a value larger than 0 prevents connections with devices that many meters (blocks) away in any direction.",fg_bg=g_lg_fg_bg} TextBox{parent=net_c_3,x=1,y=10,height=4,text="Setting this to a value larger than 0 prevents connections with devices that many meters (blocks) away in any direction.",fg_bg=g_lg_fg_bg}
local p2_err = TextBox{parent=net_c_2,x=8,y=14,width=35,text="",fg_bg=cpair(colors.red,colors.lightGray),hidden=true} local p2_err = TextBox{parent=net_c_3,x=8,y=14,width=35,text="",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
local function submit_ct_tr() local function submit_ct_tr()
local timeout_val = tonumber(timeout.get_value()) local timeout_val = tonumber(timeout.get_value())
@ -144,7 +195,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
if timeout_val ~= nil and range_val ~= nil then if timeout_val ~= nil and range_val ~= nil then
tmp_cfg.ConnTimeout = timeout_val tmp_cfg.ConnTimeout = timeout_val
tmp_cfg.TrustedRange = range_val tmp_cfg.TrustedRange = range_val
net_pane.set_value(3) net_pane.set_value(4)
p2_err.hide(true) p2_err.hide(true)
elseif timeout_val == nil then elseif timeout_val == nil then
p2_err.set_value("Please set the connection timeout.") p2_err.set_value("Please set the connection timeout.")
@ -155,23 +206,23 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
end end
end end
PushButton{parent=net_c_2,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(1)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} PushButton{parent=net_c_3,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
PushButton{parent=net_c_2,x=44,y=14,text="Next \x1a",callback=submit_ct_tr,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} PushButton{parent=net_c_3,x=44,y=14,text="Next \x1a",callback=submit_ct_tr,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
TextBox{parent=net_c_3,x=1,y=1,height=2,text="Optionally, set the facility authentication key below. Do NOT use one of your passwords."} TextBox{parent=net_c_4,x=1,y=1,height=2,text="Optionally, set the facility authentication key below. Do NOT use one of your passwords."}
TextBox{parent=net_c_3,x=1,y=4,height=6,text="This enables verifying that messages are authentic, so it is intended for security on multiplayer servers. All devices on the same network MUST use the same key if any device has a key. This does result in some extra computation (can slow things down).",fg_bg=g_lg_fg_bg} TextBox{parent=net_c_4,x=1,y=4,height=6,text="This enables verifying that messages are authentic, so it is intended for wireless security on multiplayer servers. All devices on the same wireless network MUST use the same key if any device has a key. This does result in some extra computation (can slow things down).",fg_bg=g_lg_fg_bg}
TextBox{parent=net_c_3,x=1,y=11,text="Facility Auth Key"} TextBox{parent=net_c_4,x=1,y=11,text="Auth Key (Wireless Only, Not Used when Wired)"}
local key, _ = TextField{parent=net_c_3,x=1,y=12,max_len=64,value=ini_cfg.AuthKey,width=32,height=1,fg_bg=bw_fg_bg} local key, _ = TextField{parent=net_c_4,x=1,y=12,max_len=64,value=ini_cfg.AuthKey,width=32,height=1,fg_bg=bw_fg_bg}
local function censor_key(enable) key.censor(tri(enable, "*", nil)) end local function censor_key(enable) key.censor(tri(enable, "*", nil)) end
local hide_key = Checkbox{parent=net_c_3,x=34,y=12,label="Hide",box_fg_bg=cpair(colors.lightBlue,colors.black),callback=censor_key} local hide_key = Checkbox{parent=net_c_4,x=34,y=12,label="Hide",box_fg_bg=cpair(colors.lightBlue,colors.black),callback=censor_key}
hide_key.set_value(true) hide_key.set_value(true)
censor_key(true) censor_key(true)
local key_err = TextBox{parent=net_c_3,x=8,y=14,width=35,text="Key must be at least 8 characters.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true} local key_err = TextBox{parent=net_c_4,x=8,y=14,width=35,text="Key must be at least 8 characters.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
local function submit_auth() local function submit_auth()
local v = key.get_value() local v = key.get_value()
@ -182,8 +233,8 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
else key_err.show() end else key_err.show() end
end end
PushButton{parent=net_c_3,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(2)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} PushButton{parent=net_c_4,x=1,y=14,text="\x1b Back",callback=function()net_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
PushButton{parent=net_c_3,x=44,y=14,text="Next \x1a",callback=submit_auth,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} PushButton{parent=net_c_4,x=44,y=14,text="Next \x1a",callback=submit_auth,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
--#endregion --#endregion
@ -382,6 +433,9 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
load_settings(ini_cfg) load_settings(ini_cfg)
try_set(s_vol, ini_cfg.SpeakerVolume) try_set(s_vol, ini_cfg.SpeakerVolume)
try_set(wireless, ini_cfg.WirelessModem)
try_set(wired, ini_cfg.WiredModem ~= false)
try_set(wl_pref, ini_cfg.PreferWireless)
try_set(svr_chan, ini_cfg.SVR_Channel) try_set(svr_chan, ini_cfg.SVR_Channel)
try_set(rtu_chan, ini_cfg.RTU_Channel) try_set(rtu_chan, ini_cfg.RTU_Channel)
try_set(timeout, ini_cfg.ConnTimeout) try_set(timeout, ini_cfg.ConnTimeout)
@ -665,6 +719,60 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, ext, style)
end end
end end
-- generate the list of available/assigned wired modems
function tool_ctl.gen_modem_list(enable)
modem_list.remove_all()
local function select(iface)
tmp_cfg.WiredModem = iface
tool_ctl.gen_modem_list(true)
end
local modems = ppm.get_wired_modem_list()
local missing = { tmp = true, ini = true }
for iface, _ in pairs(modems) do
if ini_cfg.WiredModem == iface then
missing.ini = false
elseif tmp_cfg.WiredModem == iface then
missing.tmp = false
end
end
if missing.tmp and tmp_cfg.WiredModem then
local line = Div{parent=modem_list,x=1,y=1,height=1}
TextBox{parent=line,x=1,y=1,width=4,text="Used",fg_bg=cpair(tri(enable,colors.blue,colors.gray),colors.white)}
PushButton{parent=line,x=6,y=1,min_width=8,height=1,text="SELECT",callback=function()end,fg_bg=cpair(colors.black,colors.lightBlue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=g_lg_fg_bg}.disable()
TextBox{parent=line,x=15,y=1,text="[missing]",fg_bg=cpair(colors.red,colors.white)}
TextBox{parent=line,x=25,y=1,text=tmp_cfg.WiredModem}
end
if missing.ini and ini_cfg.WiredModem and (tmp_cfg.WiredModem ~= ini_cfg.WiredModem) then
local line = Div{parent=modem_list,x=1,y=1,height=1}
local used = tmp_cfg.WiredModem == ini_cfg.WiredModem
TextBox{parent=line,x=1,y=1,width=4,text=tri(used,"Used","----"),fg_bg=cpair(tri(used and enable,colors.blue,colors.gray),colors.white)}
local select_btn = PushButton{parent=line,x=6,y=1,min_width=8,height=1,text="SELECT",callback=function()select(ini_cfg.WiredModem)end,fg_bg=cpair(colors.black,colors.lightBlue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=g_lg_fg_bg}
TextBox{parent=line,x=15,y=1,text="[missing]",fg_bg=cpair(colors.red,colors.white)}
TextBox{parent=line,x=25,y=1,text=ini_cfg.WiredModem}
if used or not enable then select_btn.disable() end
end
-- list wired modems
for iface, _ in pairs(modems) do
local line = Div{parent=modem_list,x=1,y=1,height=1}
local used = tmp_cfg.WiredModem == iface
TextBox{parent=line,x=1,y=1,width=4,text=tri(used,"Used","----"),fg_bg=cpair(tri(used and enable,colors.blue,colors.gray),colors.white)}
local select_btn = PushButton{parent=line,x=6,y=1,min_width=8,height=1,text="SELECT",callback=function()select(iface)end,fg_bg=cpair(colors.black,colors.lightBlue),active_fg_bg=btn_act_fg_bg,dis_fg_bg=g_lg_fg_bg}
TextBox{parent=line,x=15,y=1,text=iface}
if used or not enable then select_btn.disable() end
end
end
--#endregion --#endregion
end end

View File

@ -37,7 +37,8 @@ local changes = {
{ "v1.9.2", { "Added standard with black off state color mode", "Added blue indicator color modes" } }, { "v1.9.2", { "Added standard with black off state color mode", "Added blue indicator color modes" } },
{ "v1.10.2", { "Re-organized peripheral configuration UI, resulting in some input fields being re-ordered" } }, { "v1.10.2", { "Re-organized peripheral configuration UI, resulting in some input fields being re-ordered" } },
{ "v1.11.8", { "Added advanced option to invert digital redstone signals" } }, { "v1.11.8", { "Added advanced option to invert digital redstone signals" } },
{ "v1.12.0", { "Added support for redstone relays" } } { "v1.12.0", { "Added support for redstone relays" } },
{ "v1.13.0", { "Added support for wired communications modems" } }
} }
---@class rtu_configurator ---@class rtu_configurator
@ -80,6 +81,8 @@ local tool_ctl = {
update_relay_list = nil, ---@type function update_relay_list = nil, ---@type function
gen_peri_summary = nil, ---@type function gen_peri_summary = nil, ---@type function
gen_rs_summary = nil, ---@type function gen_rs_summary = nil, ---@type function
gen_modem_list = function (_) end
} }
---@class rtu_config ---@class rtu_config
@ -112,7 +115,9 @@ local fields = {
{ "SVR_Channel", "SVR Channel", 16240 }, { "SVR_Channel", "SVR Channel", 16240 },
{ "RTU_Channel", "RTU Channel", 16242 }, { "RTU_Channel", "RTU Channel", 16242 },
{ "ConnTimeout", "Connection Timeout", 5 }, { "ConnTimeout", "Connection Timeout", 5 },
{ "WirelessModem", "Wireless Modem", true },
{ "WiredModem", "Wired Modem", false }, { "WiredModem", "Wired Modem", false },
{ "PreferWireless", "Prefer Wireless Modem", true },
{ "TrustedRange", "Trusted Range", 0 }, { "TrustedRange", "Trusted Range", 0 },
{ "AuthKey", "Facility Auth Key", "" }, { "AuthKey", "Facility Auth Key", "" },
{ "LogMode", "Log Mode", log.MODE.APPEND }, { "LogMode", "Log Mode", log.MODE.APPEND },
@ -317,8 +322,11 @@ function configurator.configure(ask_config)
load_settings(settings_cfg, true) load_settings(settings_cfg, true)
tool_ctl.has_config = load_settings(ini_cfg) tool_ctl.has_config = load_settings(ini_cfg)
-- set tmp_cfg so interface lists are correct
tmp_cfg.Peripherals = tool_ctl.deep_copy_peri(ini_cfg.Peripherals) tmp_cfg.Peripherals = tool_ctl.deep_copy_peri(ini_cfg.Peripherals)
tmp_cfg.Redstone = tool_ctl.deep_copy_rs(ini_cfg.Redstone) tmp_cfg.Redstone = tool_ctl.deep_copy_rs(ini_cfg.Redstone)
tmp_cfg.WiredModem = ini_cfg.WiredModem
reset_term() reset_term()
@ -333,6 +341,8 @@ function configurator.configure(ask_config)
local display = DisplayBox{window=term.current(),fg_bg=style.root} local display = DisplayBox{window=term.current(),fg_bg=style.root}
config_view(display) config_view(display)
tool_ctl.gen_modem_list(ini_cfg.WiredModem ~= false)
while true do while true do
local event, param1, param2, param3, param4, param5 = util.pull_event() local event, param1, param2, param3, param4, param5 = util.pull_event()
@ -354,11 +364,13 @@ function configurator.configure(ask_config)
ppm.handle_unmount(param1) ppm.handle_unmount(param1)
tool_ctl.update_peri_list() tool_ctl.update_peri_list()
tool_ctl.update_relay_list() tool_ctl.update_relay_list()
tool_ctl.gen_modem_list()
elseif event == "peripheral" then elseif event == "peripheral" then
---@diagnostic disable-next-line: discard-returns ---@diagnostic disable-next-line: discard-returns
ppm.mount(param1) ppm.mount(param1)
tool_ctl.update_peri_list() tool_ctl.update_peri_list()
tool_ctl.update_relay_list() tool_ctl.update_relay_list()
tool_ctl.gen_modem_list()
end end
if event == "terminate" then return end if event == "terminate" then return end

View File

@ -447,15 +447,15 @@ end
---@return table|nil reactor function table ---@return table|nil reactor function table
function ppm.get_fission_reactor() return ppm.get_device("fissionReactorLogicAdapter") end function ppm.get_fission_reactor() return ppm.get_device("fissionReactorLogicAdapter") end
-- get a wired modem by name -- get a modem by name
---@nodiscard ---@nodiscard
---@param iface string CC peripheral interface ---@param iface string CC peripheral interface
---@return Modem|nil modem function table ---@return Modem|nil modem function table
function ppm.get_wired_modem(iface) function ppm.get_modem(iface)
local modem = nil local modem = nil
local device = ppm_sys.mounts[iface] local device = ppm_sys.mounts[iface]
if device.type == "modem" then modem = device.dev end if device and device.type == "modem" then modem = device.dev end
return modem return modem
end end

View File

@ -68,7 +68,7 @@ function pcie_bus.init(config, println)
if type(config.WiredModem) == "string" then if type(config.WiredModem) == "string" then
bus.wired_modem = config.WiredModem bus.wired_modem = config.WiredModem
local wired_modem = ppm.get_wired_modem(bus.wired_modem) local wired_modem = ppm.get_modem(bus.wired_modem)
if not (wired_modem and bus.wired_modem) then if not (wired_modem and bus.wired_modem) then
println("startup> wired comms modem not found") println("startup> wired comms modem not found")