#105 single coordinator configuration

This commit is contained in:
Mikayla Fischler 2022-10-20 13:53:39 -04:00
parent 2f55ad76f2
commit 788fae44aa
6 changed files with 69 additions and 42 deletions

View File

@ -409,6 +409,8 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, sv_wa
else else
log.debug("supervisor conn establish packet length mismatch") log.debug("supervisor conn establish packet length mismatch")
end end
elseif packet.length == 1 and packet.data[1] == false then
log.debug("supervisor connection denied")
else else
log.debug("supervisor conn establish packet length mismatch") log.debug("supervisor conn establish packet length mismatch")
end end
@ -431,7 +433,7 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, sv_wa
local cmd = packet.data[1] local cmd = packet.data[1]
local unit = packet.data[2] local unit = packet.data[2]
local ack = packet.data[3] local ack = packet.data[3]
if cmd == CRDN_COMMANDS.SCRAM then if cmd == CRDN_COMMANDS.SCRAM then
elseif cmd == CRDN_COMMANDS.START then elseif cmd == CRDN_COMMANDS.START then
elseif cmd == CRDN_COMMANDS.RESET_RPS then elseif cmd == CRDN_COMMANDS.RESET_RPS then

View File

@ -16,7 +16,7 @@ local config = require("coordinator.config")
local coordinator = require("coordinator.coordinator") local coordinator = require("coordinator.coordinator")
local renderer = require("coordinator.renderer") local renderer = require("coordinator.renderer")
local COORDINATOR_VERSION = "alpha-v0.5.5" local COORDINATOR_VERSION = "alpha-v0.5.6"
local print = util.print local print = util.print
local println = util.println local println = util.println

View File

@ -38,7 +38,7 @@ local function hazard_button(args)
---@param accent color accent color ---@param accent color accent color
local function draw_border(accent) local function draw_border(accent)
-- top -- top
e.window.setTextColor(args.accent) e.window.setTextColor(accent)
e.window.setBackgroundColor(args.fg_bg.bkg) e.window.setBackgroundColor(args.fg_bg.bkg)
e.window.setCursorPos(1, 1) e.window.setCursorPos(1, 1)
e.window.write("\x99\x89\x89\x89\x89\x89\x89\x89\x99") e.window.write("\x99\x89\x89\x89\x89\x89\x89\x89\x99")
@ -46,17 +46,17 @@ local function hazard_button(args)
-- center left -- center left
e.window.setCursorPos(1, 2) e.window.setCursorPos(1, 2)
e.window.setTextColor(args.fg_bg.bkg) e.window.setTextColor(args.fg_bg.bkg)
e.window.setBackgroundColor(args.accent) e.window.setBackgroundColor(accent)
e.window.write("\x99") e.window.write("\x99")
-- center right -- center right
e.window.setTextColor(args.fg_bg.bkg) e.window.setTextColor(args.fg_bg.bkg)
e.window.setBackgroundColor(args.accent) e.window.setBackgroundColor(accent)
e.window.setCursorPos(9, 2) e.window.setCursorPos(9, 2)
e.window.write("\x99") e.window.write("\x99")
-- bottom -- bottom
e.window.setTextColor(args.accent) e.window.setTextColor(accent)
e.window.setBackgroundColor(args.fg_bg.bkg) e.window.setBackgroundColor(args.fg_bg.bkg)
e.window.setCursorPos(1, 3) e.window.setCursorPos(1, 3)
e.window.write("\x99\x98\x98\x98\x98\x98\x98\x98\x99") e.window.write("\x99\x98\x98\x98\x98\x98\x98\x98\x99")
@ -90,6 +90,10 @@ local function hazard_button(args)
if val then e.handle_touch(core.events.touch("", 1, 1)) end if val then e.handle_touch(core.events.touch("", 1, 1)) end
end end
-- initial draw of border
---@todo disabling will change border
draw_border(args.accent)
return e.get() return e.get()
end end

View File

@ -60,12 +60,9 @@ local function _sv_handle_outq(session)
elseif msg.qtype == mqueue.TYPE.COMMAND then elseif msg.qtype == mqueue.TYPE.COMMAND then
-- handle instruction/notification -- handle instruction/notification
local cmd = msg.message local cmd = msg.message
if cmd == SV_Q_CMDS.BUILD_CHANGED then if (cmd == SV_Q_CMDS.BUILD_CHANGED) and (svsessions.get_coord_session() ~= nil) then
-- notify coordinator(s) that a build has changed -- notify coordinator that a build has changed
for j = 1, #self.coord_sessions do svsessions.get_coord_session().in_queue.push_command(CRD_S_CMDS.RESEND_BUILDS)
local s = self.coord_sessions[j] ---@type coord_session_struct
s.in_queue.push_command(CRD_S_CMDS.RESEND_BUILDS)
end
end end
elseif msg.qtype == mqueue.TYPE.DATA then elseif msg.qtype == mqueue.TYPE.DATA then
-- instruction/notification with body -- instruction/notification with body
@ -243,6 +240,8 @@ function svsessions.find_device_session(remote_port)
end end
-- find a coordinator session by the remote port -- find a coordinator session by the remote port
--
-- only one coordinator is allowed, but this is kept to be consistent with all other session tables
---@param remote_port integer ---@param remote_port integer
---@return nil ---@return nil
function svsessions.find_coord_session(remote_port) function svsessions.find_coord_session(remote_port)
@ -251,6 +250,12 @@ function svsessions.find_coord_session(remote_port)
return _find_session(self.coord_sessions, remote_port) return _find_session(self.coord_sessions, remote_port)
end end
-- get the a coordinator session if exists
---@return coord_session_struct|nil
function svsessions.get_coord_session()
return self.coord_sessions[1]
end
-- get a session by reactor ID -- get a session by reactor ID
---@param reactor integer ---@param reactor integer
---@return plc_session_struct|nil session ---@return plc_session_struct|nil session
@ -342,27 +347,32 @@ end
---@param version string ---@param version string
---@return integer|false session_id ---@return integer|false session_id
function svsessions.establish_coord_session(local_port, remote_port, version) function svsessions.establish_coord_session(local_port, remote_port, version)
---@class coord_session_struct if svsessions.get_coord_session() == nil then
local coord_s = { ---@class coord_session_struct
s_type = "crd", local coord_s = {
open = true, s_type = "crd",
version = version, open = true,
l_port = local_port, version = version,
r_port = remote_port, l_port = local_port,
in_queue = mqueue.new(), r_port = remote_port,
out_queue = mqueue.new(), in_queue = mqueue.new(),
instance = nil ---@type coord_session out_queue = mqueue.new(),
} instance = nil ---@type coord_session
}
coord_s.instance = coordinator.new_session(self.next_coord_id, coord_s.in_queue, coord_s.out_queue, self.facility_units) coord_s.instance = coordinator.new_session(self.next_coord_id, coord_s.in_queue, coord_s.out_queue, self.facility_units)
table.insert(self.coord_sessions, coord_s) table.insert(self.coord_sessions, coord_s)
log.debug("established new coordinator session to " .. remote_port .. " with ID " .. self.next_coord_id) log.debug("established new coordinator session to " .. remote_port .. " with ID " .. self.next_coord_id)
self.next_coord_id = self.next_coord_id + 1 self.next_coord_id = self.next_coord_id + 1
-- success -- success
return coord_s.instance.get_id() return coord_s.instance.get_id()
else
-- we already have a coordinator linked
return false
end
end end
-- attempt to identify which session's watchdog timer fired -- attempt to identify which session's watchdog timer fired

View File

@ -13,7 +13,7 @@ local svsessions = require("supervisor.session.svsessions")
local config = require("supervisor.config") local config = require("supervisor.config")
local supervisor = require("supervisor.supervisor") local supervisor = require("supervisor.supervisor")
local SUPERVISOR_VERSION = "beta-v0.6.4" local SUPERVISOR_VERSION = "beta-v0.6.5"
local print = util.print local print = util.print
local println = util.println local println = util.println

View File

@ -80,15 +80,19 @@ function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen
-- send coordinator connection establish response -- send coordinator connection establish response
---@param seq_id integer ---@param seq_id integer
---@param dest integer ---@param dest integer
local function _send_crdn_establish(seq_id, dest) ---@param allow boolean
local function _send_crdn_establish(seq_id, dest, allow)
local s_pkt = comms.scada_packet() local s_pkt = comms.scada_packet()
local c_pkt = comms.crdn_packet() local c_pkt = comms.crdn_packet()
local config = { self.num_reactors } local config = { false }
for i = 1, #cooling_conf do if allow then
table.insert(config, cooling_conf[i].BOILERS) config = { self.num_reactors }
table.insert(config, cooling_conf[i].TURBINES) for i = 1, #cooling_conf do
table.insert(config, cooling_conf[i].BOILERS)
table.insert(config, cooling_conf[i].TURBINES)
end
end end
c_pkt.make(SCADA_CRDN_TYPES.ESTABLISH, config) c_pkt.make(SCADA_CRDN_TYPES.ESTABLISH, config)
@ -235,11 +239,14 @@ function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen
elseif packet.type == SCADA_MGMT_TYPES.RTU_ADVERT then elseif packet.type == SCADA_MGMT_TYPES.RTU_ADVERT then
if packet.length >= 1 then if packet.length >= 1 then
-- this is an RTU advertisement for a new session -- this is an RTU advertisement for a new session
println(util.c("connected to RTU (", packet.data[1], ") [:", r_port, "]")) local rtu_version = packet.data[1]
-- note: this function mutates packet.data
svsessions.establish_rtu_session(l_port, r_port, packet.data) svsessions.establish_rtu_session(l_port, r_port, packet.data)
println(util.c("connected to RTU (", rtu_version, ") [:", r_port, "]"))
log.debug("RTU_ADVERT: linked " .. r_port) log.debug("RTU_ADVERT: linked " .. r_port)
_send_remote_linked(packet.scada_frame.seq_num() + 1, r_port) _send_remote_linked(packet.scada_frame.seq_num() + 1, r_port)
else else
log.debug("RTU_ADVERT: advertisement packet empty") log.debug("RTU_ADVERT: advertisement packet empty")
@ -263,7 +270,7 @@ function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen
session.in_queue.push_packet(packet) session.in_queue.push_packet(packet)
else else
-- any other packet should be session related, discard it -- any other packet should be session related, discard it
log.debug(util.c(r_port, "->", l_port, ": discarding SCADA_MGMT packet without a known session")) log.debug(r_port .. "->" .. l_port .. ": discarding SCADA_MGMT packet without a known session")
end end
elseif protocol == PROTOCOLS.SCADA_CRDN then elseif protocol == PROTOCOLS.SCADA_CRDN then
-- coordinator packet -- coordinator packet
@ -273,18 +280,22 @@ function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen
elseif packet.type == SCADA_CRDN_TYPES.ESTABLISH then elseif packet.type == SCADA_CRDN_TYPES.ESTABLISH then
if packet.length == 1 then if packet.length == 1 then
-- this is an attempt to establish a new session -- this is an attempt to establish a new session
println(util.c("connected to coordinator (", packet.data[1], ") [:", r_port, "]")) local s_id = svsessions.establish_coord_session(l_port, r_port, packet.data[1])
svsessions.establish_coord_session(l_port, r_port, packet.data[1]) if s_id ~= false then
println(util.c("connected to coordinator (", packet.data[1], ") [:", r_port, "]"))
log.debug("CRDN_ESTABLISH: connected to " .. r_port)
else
log.debug("CRDN_ESTABLISH: denied new coordinator due to already being connected to another coordinator")
end
log.debug("CRDN_ESTABLISH: connected to " .. r_port) _send_crdn_establish(packet.scada_frame.seq_num() + 1, r_port, (s_id ~= false))
_send_crdn_establish(packet.scada_frame.seq_num() + 1, r_port)
else else
log.debug("CRDN_ESTABLISH: establish packet length mismatch") log.debug("CRDN_ESTABLISH: establish packet length mismatch")
end end
else else
-- any other packet should be session related, discard it -- any other packet should be session related, discard it
log.debug(util.c(r_port, "->", l_port, ": discarding SCADA_CRDN packet without a known session")) log.debug(r_port .. "->" .. l_port .. ": discarding SCADA_CRDN packet without a known session")
end end
else else
log.debug("illegal packet type " .. protocol .. " on coordinator listening channel") log.debug("illegal packet type " .. protocol .. " on coordinator listening channel")