#140 partial build packet updates

This commit is contained in:
Mikayla Fischler 2023-02-20 00:49:37 -05:00
parent c4f6c1b289
commit 1be57aaf13
17 changed files with 128 additions and 81 deletions

View File

@ -465,11 +465,15 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, range
end
elseif packet.type == SCADA_CRDN_TYPES.UNIT_BUILDS then
-- record builds
if iocontrol.record_unit_builds(packet.data) then
-- acknowledge receipt of builds
_send_sv(PROTOCOLS.SCADA_CRDN, SCADA_CRDN_TYPES.UNIT_BUILDS, {})
if packet.length == 1 then
if iocontrol.record_unit_builds(packet.data[1]) then
-- acknowledge receipt of builds
_send_sv(PROTOCOLS.SCADA_CRDN, SCADA_CRDN_TYPES.UNIT_BUILDS, {})
else
log.error("received invalid UNIT_BUILDS packet")
end
else
log.error("received invalid UNIT_BUILDS packet")
log.debug("UNIT_BUILDS packet length mismatch")
end
elseif packet.type == SCADA_CRDN_TYPES.UNIT_STATUSES then
-- update statuses

View File

@ -19,7 +19,7 @@ local iocontrol = require("coordinator.iocontrol")
local renderer = require("coordinator.renderer")
local sounder = require("coordinator.sounder")
local COORDINATOR_VERSION = "beta-v0.9.16"
local COORDINATOR_VERSION = "beta-v0.10.0"
local print = util.print
local println = util.println

View File

@ -4,8 +4,8 @@
"comms": "1.3.3",
"reactor-plc": "beta-v0.10.11",
"rtu": "beta-v0.11.1",
"supervisor": "beta-v0.11.13",
"coordinator": "beta-v0.9.16",
"supervisor": "beta-v0.12.0",
"coordinator": "beta-v0.10.0",
"pocket": "alpha-v0.0.0"
},
"files": {
@ -180,10 +180,10 @@
"common": 88049,
"graphics": 99360,
"lockbox": 100797,
"reactor-plc": 75956,
"reactor-plc": 75915,
"rtu": 81676,
"supervisor": 261745,
"coordinator": 180622,
"supervisor": 265030,
"coordinator": 180849,
"pocket": 335
}
}

View File

@ -814,13 +814,16 @@ function facility.new(num_reactors, cooling_conf)
-- READ STATES/PROPERTIES --
-- get build properties of all machines
function public.get_build()
---@param inc_imatrix boolean? true/nil to include induction matrix build, false to exclude
function public.get_build(inc_imatrix)
local build = {}
build.induction = {}
for i = 1, #self.induction do
local matrix = self.induction[i] ---@type unit_session
build.induction[matrix.get_device_idx()] = { matrix.get_db().formed, matrix.get_db().build }
if inc_imatrix ~= false then
build.induction = {}
for i = 1, #self.induction do
local matrix = self.induction[i] ---@type unit_session
build.induction[matrix.get_device_idx()] = { matrix.get_db().formed, matrix.get_db().build }
end
end
return build

View File

@ -12,6 +12,7 @@ local SCADA_MGMT_TYPES = comms.SCADA_MGMT_TYPES
local SCADA_CRDN_TYPES = comms.SCADA_CRDN_TYPES
local UNIT_COMMANDS = comms.UNIT_COMMANDS
local FAC_COMMANDS = comms.FAC_COMMANDS
local RTU_UNIT_TYPES = comms.RTU_UNIT_TYPES
local SV_Q_CMDS = svqtypes.SV_Q_CMDS
local SV_Q_DATA = svqtypes.SV_Q_DATA
@ -24,13 +25,15 @@ local println_ts = util.println_ts
-- retry time constants in ms
local INITIAL_WAIT = 1500
local RETRY_PERIOD = 1000
local PARTIAL_RETRY_PERIOD = 2000
local CRD_S_CMDS = {
RESEND_BUILDS = 1
}
local CRD_S_DATA = {
CMD_ACK = 1
CMD_ACK = 1,
RESEND_PLC_BUILD = 2,
RESEND_RTU_BUILD = 3
}
coordinator.CRD_S_CMDS = CRD_S_CMDS
@ -129,7 +132,7 @@ function coordinator.new_session(id, in_queue, out_queue, timeout, facility)
builds[unit.get_id()] = unit.get_build()
end
_send(SCADA_CRDN_TYPES.UNIT_BUILDS, builds)
_send(SCADA_CRDN_TYPES.UNIT_BUILDS, { builds })
end
-- send facility status
@ -350,15 +353,6 @@ function coordinator.new_session(id, in_queue, out_queue, timeout, facility)
_handle_packet(message.message)
elseif message.qtype == mqueue.TYPE.COMMAND then
-- handle instruction
local cmd = message.message
if cmd == CRD_S_CMDS.RESEND_BUILDS then
-- re-send builds
self.retry_times.builds_packet = util.time() + RETRY_PERIOD
_send_fac_builds()
_send_unit_builds()
else
log.warning(log_header .. "unsupported command received in in_queue (this is a bug)")
end
elseif message.qtype == mqueue.TYPE.DATA then
-- instruction with body
local cmd = message.message ---@type queue_data
@ -366,6 +360,41 @@ function coordinator.new_session(id, in_queue, out_queue, timeout, facility)
if cmd.key == CRD_S_DATA.CMD_ACK then
local ack = cmd.val ---@type coord_ack
_send(SCADA_CRDN_TYPES.UNIT_CMD, { ack.cmd, ack.unit, ack.ack })
elseif cmd.key == CRD_S_DATA.RESEND_PLC_BUILD then
-- re-send PLC build
-- retry logic will be kept as-is, so as long as no retry is needed, this will be a small update
self.retry_times.builds_packet = util.time() + PARTIAL_RETRY_PERIOD
self.acks.unit_builds = false
local unit_id = cmd.val
local builds = {}
local unit = self.units[unit_id] ---@type reactor_unit
builds[unit_id] = unit.get_build(true, false, false)
_send(SCADA_CRDN_TYPES.UNIT_BUILDS, { builds })
elseif cmd.key == CRD_S_DATA.RESEND_RTU_BUILD then
local unit_id = cmd.val.unit
if unit_id > 0 then
-- re-send unit RTU builds
-- retry logic will be kept as-is, so as long as no retry is needed, this will be a small update
self.retry_times.u_builds_packet = util.time() + PARTIAL_RETRY_PERIOD
self.acks.unit_builds = false
local builds = {}
local unit = self.units[unit_id] ---@type reactor_unit
builds[unit_id] = unit.get_build(false, cmd.val.type == RTU_UNIT_TYPES.BOILER_VALVE, cmd.val.type == RTU_UNIT_TYPES.TURBINE_VALVE)
_send(SCADA_CRDN_TYPES.UNIT_BUILDS, { builds })
else
-- re-send facility RTU builds
-- retry logic will be kept as-is, so as long as no retry is needed, this will be a small update
self.retry_times.f_builds_packet = util.time() + PARTIAL_RETRY_PERIOD
self.acks.fac_builds = false
_send(SCADA_CRDN_TYPES.FAC_BUILDS, { facility.get_build(cmd.val.type == RTU_UNIT_TYPES.IMATRIX) })
end
else
log.warning(log_header .. "unsupported data command received in in_queue (this is a bug)")
end

View File

@ -342,7 +342,7 @@ function plc.new_session(id, for_reactor, in_queue, out_queue, timeout)
if status then
-- copied in structure data OK
self.received_struct = true
self.out_q.push_command(svqtypes.SV_Q_CMDS.BUILD_CHANGED)
self.out_q.push_data(svqtypes.SV_Q_DATA.PLC_BUILD_CHANGED, for_reactor)
else
-- error copying structure data
log.error(log_header .. "failed to parse struct packet data")

View File

@ -385,12 +385,12 @@ function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facili
_send_modbus(msg.message)
elseif msg.qtype == mqueue.TYPE.COMMAND then
-- handle instruction
local cmd = msg.message
if cmd == unit_session.RTU_US_CMDS.BUILD_CHANGED then
self.out_q.push_command(svqtypes.SV_Q_CMDS.BUILD_CHANGED)
end
elseif msg.qtype == mqueue.TYPE.DATA then
-- instruction with body
local cmd = msg.message ---@type queue_data
if cmd.key == unit_session.RTU_US_DATA.BUILD_CHANGED then
self.out_q.push_data(svqtypes.SV_Q_DATA.RTU_BUILD_CHANGED, cmd.val)
end
end
end
end

View File

@ -32,10 +32,10 @@ local PERIODICS = {
}
-- create a new boilerv rtu session runner
---@param session_id integer
---@param unit_id integer
---@param advert rtu_advertisement
---@param out_queue mqueue
---@param session_id integer RTU session ID
---@param unit_id integer RTU unit ID
---@param advert rtu_advertisement RTU advertisement table
---@param out_queue mqueue RTU unit message out queue
function boilerv.new(session_id, unit_id, advert, out_queue)
-- type check
if advert.type ~= RTU_UNIT_TYPES.BOILER_VALVE then
@ -161,7 +161,7 @@ function boilerv.new(session_id, unit_id, advert, out_queue)
self.db.build.max_boil_rate = m_pkt.data[12]
self.has_build = true
out_queue.push_command(unit_session.RTU_US_CMDS.BUILD_CHANGED)
out_queue.push_data(unit_session.RTU_US_DATA.BUILD_CHANGED, { unit = advert.reactor, type = advert.type })
else
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
end

View File

@ -32,10 +32,10 @@ local PERIODICS = {
}
-- create a new imatrix rtu session runner
---@param session_id integer
---@param unit_id integer
---@param advert rtu_advertisement
---@param out_queue mqueue
---@param session_id integer RTU session ID
---@param unit_id integer RTU unit ID
---@param advert rtu_advertisement RTU advertisement table
---@param out_queue mqueue RTU unit message out queue
function imatrix.new(session_id, unit_id, advert, out_queue)
-- type check
if advert.type ~= RTU_UNIT_TYPES.IMATRIX then
@ -145,7 +145,7 @@ function imatrix.new(session_id, unit_id, advert, out_queue)
self.db.build.providers = m_pkt.data[9]
self.has_build = true
out_queue.push_command(unit_session.RTU_US_CMDS.BUILD_CHANGED)
out_queue.push_data(unit_session.RTU_US_DATA.BUILD_CHANGED, { unit = advert.reactor, type = advert.type })
else
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
end

View File

@ -29,10 +29,10 @@ local PERIODICS = {
}
-- create a new sna rtu session runner
---@param session_id integer
---@param unit_id integer
---@param advert rtu_advertisement
---@param out_queue mqueue
---@param session_id integer RTU session ID
---@param unit_id integer RTU unit ID
---@param advert rtu_advertisement RTU advertisement table
---@param out_queue mqueue RTU unit message out queue
function sna.new(session_id, unit_id, advert, out_queue)
-- type check
if advert.type ~= RTU_UNIT_TYPES.SNA then
@ -113,7 +113,7 @@ function sna.new(session_id, unit_id, advert, out_queue)
self.db.build.output_cap = m_pkt.data[2]
self.has_build = true
out_queue.push_command(unit_session.RTU_US_CMDS.BUILD_CHANGED)
out_queue.push_data(unit_session.RTU_US_DATA.BUILD_CHANGED, { unit = advert.reactor, type = advert.type })
else
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
end

View File

@ -32,10 +32,10 @@ local PERIODICS = {
}
-- create a new sps rtu session runner
---@param session_id integer
---@param unit_id integer
---@param advert rtu_advertisement
---@param out_queue mqueue
---@param session_id integer RTU session ID
---@param unit_id integer RTU unit ID
---@param advert rtu_advertisement RTU advertisement table
---@param out_queue mqueue RTU unit message out queue
function sps.new(session_id, unit_id, advert, out_queue)
-- type check
if advert.type ~= RTU_UNIT_TYPES.SPS then
@ -150,7 +150,7 @@ function sps.new(session_id, unit_id, advert, out_queue)
self.db.build.max_energy = m_pkt.data[9]
self.has_build = true
out_queue.push_command(unit_session.RTU_US_CMDS.BUILD_CHANGED)
out_queue.push_data(unit_session.RTU_US_DATA.BUILD_CHANGED, { unit = advert.reactor, type = advert.type })
else
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
end

View File

@ -44,10 +44,10 @@ local PERIODICS = {
}
-- create a new turbinev rtu session runner
---@param session_id integer
---@param unit_id integer
---@param advert rtu_advertisement
---@param out_queue mqueue
---@param session_id integer RTU session ID
---@param unit_id integer RTU unit ID
---@param advert rtu_advertisement RTU advertisement table
---@param out_queue mqueue RTU unit message out queue
function turbinev.new(session_id, unit_id, advert, out_queue)
-- type check
if advert.type ~= RTU_UNIT_TYPES.TURBINE_VALVE then
@ -192,7 +192,7 @@ function turbinev.new(session_id, unit_id, advert, out_queue)
self.db.build.max_water_output = m_pkt.data[15]
self.has_build = true
out_queue.push_command(unit_session.RTU_US_CMDS.BUILD_CHANGED)
out_queue.push_data(unit_session.RTU_US_DATA.BUILD_CHANGED, { unit = advert.reactor, type = advert.type })
else
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
end

View File

@ -13,10 +13,10 @@ local MODBUS_FCODE = types.MODBUS_FCODE
local MODBUS_EXCODE = types.MODBUS_EXCODE
local RTU_US_CMDS = {
BUILD_CHANGED = 1
}
local RTU_US_DATA = {
BUILD_CHANGED = 1
}
unit_session.RTU_US_CMDS = RTU_US_CMDS

View File

@ -1,7 +1,6 @@
local svqtypes = {}
local SV_Q_CMDS = {
BUILD_CHANGED = 1
}
local SV_Q_DATA = {
@ -10,7 +9,9 @@ local SV_Q_DATA = {
RESET_RPS = 3,
SET_BURN = 4,
__END_PLC_CMDS__ = 5,
CRDN_ACK = 6
CRDN_ACK = 6,
PLC_BUILD_CHANGED = 7,
RTU_BUILD_CHANGED = 8
}
---@class coord_ack

View File

@ -62,11 +62,6 @@ local function _sv_handle_outq(session)
self.modem.transmit(session.r_port, session.l_port, msg.message.raw_sendable())
elseif msg.qtype == mqueue.TYPE.COMMAND then
-- handle instruction/notification
local cmd = msg.message
if (cmd == SV_Q_CMDS.BUILD_CHANGED) and (svsessions.get_coord_session() ~= nil) then
-- notify coordinator that a build has changed
svsessions.get_coord_session().in_queue.push_command(CRD_S_CMDS.RESEND_BUILDS)
end
elseif msg.qtype == mqueue.TYPE.DATA then
-- instruction/notification with body
local cmd = msg.message ---@type queue_data
@ -89,11 +84,17 @@ local function _sv_handle_outq(session)
end
end
else
if cmd.key == SV_Q_DATA.CRDN_ACK then
-- ack to be sent to coordinator
local crd_s = svsessions.get_coord_session()
if crd_s ~= nil then
local crd_s = svsessions.get_coord_session()
if crd_s ~= nil then
if cmd.key == SV_Q_DATA.CRDN_ACK then
-- ack to be sent to coordinator
crd_s.in_queue.push_data(CRD_S_DATA.CMD_ACK, cmd.val)
elseif cmd.key == SV_Q_DATA.PLC_BUILD_CHANGED then
-- a PLC build has changed
crd_s.in_queue.push_data(CRD_S_DATA.RESEND_PLC_BUILD, cmd.val)
elseif cmd.key == SV_Q_DATA.RTU_BUILD_CHANGED then
-- an RTU build has changed
crd_s.in_queue.push_data(CRD_S_DATA.RESEND_RTU_BUILD, cmd.val)
end
end
end

View File

@ -14,7 +14,7 @@ local svsessions = require("supervisor.session.svsessions")
local config = require("supervisor.config")
local supervisor = require("supervisor.supervisor")
local SUPERVISOR_VERSION = "beta-v0.11.13"
local SUPERVISOR_VERSION = "beta-v0.12.0"
local print = util.print
local println = util.println

View File

@ -678,23 +678,32 @@ function unit.new(for_reactor, num_boilers, num_turbines)
end
-- get build properties of all machines
function public.get_build()
---@param inc_plc boolean? true/nil to include PLC build, false to exclude
---@param inc_boilers boolean? true/nil to include boiler builds, false to exclude
---@param inc_turbines boolean? true/nil to include turbine builds, false to exclude
function public.get_build(inc_plc, inc_boilers, inc_turbines)
local build = {}
if self.plc_i ~= nil then
build.reactor = self.plc_i.get_struct()
if inc_plc ~= false then
if self.plc_i ~= nil then
build.reactor = self.plc_i.get_struct()
end
end
build.boilers = {}
for i = 1, #self.boilers do
local boiler = self.boilers[i] ---@type unit_session
build.boilers[boiler.get_device_idx()] = { boiler.get_db().formed, boiler.get_db().build }
if inc_boilers ~= false then
build.boilers = {}
for i = 1, #self.boilers do
local boiler = self.boilers[i] ---@type unit_session
build.boilers[boiler.get_device_idx()] = { boiler.get_db().formed, boiler.get_db().build }
end
end
build.turbines = {}
for i = 1, #self.turbines do
local turbine = self.turbines[i] ---@type unit_session
build.turbines[turbine.get_device_idx()] = { turbine.get_db().formed, turbine.get_db().build }
if inc_turbines ~= false then
build.turbines = {}
for i = 1, #self.turbines do
local turbine = self.turbines[i] ---@type unit_session
build.turbines[turbine.get_device_idx()] = { turbine.get_db().formed, turbine.get_db().build }
end
end
return build