diff --git a/pocket/iocontrol.lua b/pocket/iocontrol.lua index 38e642e..de69dd3 100644 --- a/pocket/iocontrol.lua +++ b/pocket/iocontrol.lua @@ -523,7 +523,10 @@ function iocontrol.record_unit_data(data) reactor_state = 6 -- SCRAM rps_status = 2 end - else rps_status = 4 end + else + rps_status = 4 + reactor_state = 4 + end -- update reactor/control status if unit.reactor_data.mek_status.status then diff --git a/reactor-plc/plc.lua b/reactor-plc/plc.lua index df116cf..3eead7e 100644 --- a/reactor-plc/plc.lua +++ b/reactor-plc/plc.lua @@ -570,33 +570,17 @@ function plc.comms(version, nic, reactor, rps, conn_watchdog) self.seq_num = self.seq_num + 1 end - -- variable reactor status information, excluding heating rate + -- dynamic reactor status information, excluding heating rate ---@return table data_table, boolean faulted - local function _reactor_status() + local function _get_reactor_status() local fuel = nil local waste = nil local coolant = nil local hcoolant = nil - local data_table = { - false, -- getStatus - 0, -- getBurnRate - 0, -- getActualBurnRate - 0, -- getTemperature - 0, -- getDamagePercent - 0, -- getBoilEfficiency - 0, -- getEnvironmentalLoss - 0, -- fuel_amnt - 0, -- getFuelFilledPercentage - 0, -- waste_amnt - 0, -- getWasteFilledPercentage - "", -- coolant_name - 0, -- coolant_amnt - 0, -- getCoolantFilledPercentage - "", -- hcoolant_name - 0, -- hcoolant_amnt - 0 -- getHeatedCoolantFilledPercentage - } + local data_table = {} + + reactor.__p_disable_afc() local tasks = { function () data_table[1] = reactor.getStatus() end, @@ -636,30 +620,32 @@ function plc.comms(version, nic, reactor, rps, conn_watchdog) data_table[16] = hcoolant.amount end + reactor.__p_enable_afc() + return data_table, reactor.__p_is_faulted() end -- update the status cache if changed ---@return boolean changed local function _update_status_cache() - local status, faulted = _reactor_status() + local status, faulted = _get_reactor_status() local changed = false - if self.status_cache ~= nil then - if not faulted then + if not faulted then + if self.status_cache ~= nil then for i = 1, #status do if status[i] ~= self.status_cache[i] then changed = true break end end + else + changed = true end - else - changed = true - end - if changed and not faulted then - self.status_cache = status + if changed then + self.status_cache = status + end end return changed @@ -678,9 +664,11 @@ function plc.comms(version, nic, reactor, rps, conn_watchdog) _send(msg_type, { status }) end - -- send structure properties (these should not change, server will cache these) + -- send static structure properties, cached by server local function _send_struct() - local mek_data = { false, 0, 0, 0, types.new_zero_coordinate(), types.new_zero_coordinate(), 0, 0, 0, 0, 0, 0, 0, 0 } + local mek_data = {} + + reactor.__p_disable_afc() local tasks = { function () mek_data[1] = reactor.getLength() end, @@ -704,6 +692,8 @@ function plc.comms(version, nic, reactor, rps, conn_watchdog) _send(RPLC_TYPE.MEK_STRUCT, mek_data) self.resend_build = false end + + reactor.__p_enable_afc() end -- PUBLIC FUNCTIONS -- diff --git a/supervisor/session/plc.lua b/supervisor/session/plc.lua index 63293e4..fb5ca1b 100644 --- a/supervisor/session/plc.lua +++ b/supervisor/session/plc.lua @@ -190,71 +190,111 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue, -- copy in the RPS status ---@param rps_status table local function _copy_rps_status(rps_status) - self.sDB.rps_tripped = rps_status[1] - self.sDB.rps_trip_cause = rps_status[2] - self.sDB.rps_status.high_dmg = rps_status[3] - self.sDB.rps_status.high_temp = rps_status[4] - self.sDB.rps_status.low_cool = rps_status[5] - self.sDB.rps_status.ex_waste = rps_status[6] - self.sDB.rps_status.ex_hcool = rps_status[7] - self.sDB.rps_status.no_fuel = rps_status[8] - self.sDB.rps_status.fault = rps_status[9] - self.sDB.rps_status.timeout = rps_status[10] - self.sDB.rps_status.manual = rps_status[11] - self.sDB.rps_status.automatic = rps_status[12] - self.sDB.rps_status.sys_fail = rps_status[13] - self.sDB.rps_status.force_dis = rps_status[14] + local rps = self.sDB.rps_status + + self.sDB.rps_tripped = rps_status[1] + self.sDB.rps_trip_cause = rps_status[2] + + rps.high_dmg = rps_status[3] + rps.high_temp = rps_status[4] + rps.low_cool = rps_status[5] + rps.ex_waste = rps_status[6] + rps.ex_hcool = rps_status[7] + rps.no_fuel = rps_status[8] + rps.fault = rps_status[9] + rps.timeout = rps_status[10] + rps.manual = rps_status[11] + rps.automatic = rps_status[12] + rps.sys_fail = rps_status[13] + rps.force_dis = rps_status[14] end -- copy in the reactor status ---@param mek_data table local function _copy_status(mek_data) + local stat = self.sDB.mek_status + local struct = self.sDB.mek_struct + -- copy status information - self.sDB.mek_status.status = mek_data[1] - self.sDB.mek_status.burn_rate = mek_data[2] - self.sDB.mek_status.act_burn_rate = mek_data[3] - self.sDB.mek_status.temp = mek_data[4] - self.sDB.mek_status.damage = mek_data[5] - self.sDB.mek_status.boil_eff = mek_data[6] - self.sDB.mek_status.env_loss = mek_data[7] + stat.status = mek_data[1] + stat.burn_rate = mek_data[2] + stat.act_burn_rate = mek_data[3] + stat.temp = mek_data[4] + stat.damage = mek_data[5] + stat.boil_eff = mek_data[6] + stat.env_loss = mek_data[7] -- copy container information - self.sDB.mek_status.fuel = mek_data[8] - self.sDB.mek_status.fuel_fill = mek_data[9] - self.sDB.mek_status.waste = mek_data[10] - self.sDB.mek_status.waste_fill = mek_data[11] - self.sDB.mek_status.ccool_type = mek_data[12] - self.sDB.mek_status.ccool_amnt = mek_data[13] - self.sDB.mek_status.ccool_fill = mek_data[14] - self.sDB.mek_status.hcool_type = mek_data[15] - self.sDB.mek_status.hcool_amnt = mek_data[16] - self.sDB.mek_status.hcool_fill = mek_data[17] + stat.fuel = mek_data[8] + stat.fuel_fill = mek_data[9] + stat.waste = mek_data[10] + stat.waste_fill = mek_data[11] + stat.ccool_type = mek_data[12] + stat.ccool_amnt = mek_data[13] + stat.ccool_fill = mek_data[14] + stat.hcool_type = mek_data[15] + stat.hcool_amnt = mek_data[16] + stat.hcool_fill = mek_data[17] -- update computable fields if we have our structure if self.received_struct then - self.sDB.mek_status.fuel_need = self.sDB.mek_struct.fuel_cap - self.sDB.mek_status.fuel_fill - self.sDB.mek_status.waste_need = self.sDB.mek_struct.waste_cap - self.sDB.mek_status.waste_fill - self.sDB.mek_status.cool_need = self.sDB.mek_struct.ccool_cap - self.sDB.mek_status.ccool_fill - self.sDB.mek_status.hcool_need = self.sDB.mek_struct.hcool_cap - self.sDB.mek_status.hcool_fill + stat.fuel_need = struct.fuel_cap - stat.fuel_fill + stat.waste_need = struct.waste_cap - stat.waste_fill + stat.cool_need = struct.ccool_cap - stat.ccool_fill + stat.hcool_need = struct.hcool_cap - stat.hcool_fill end end -- copy in the reactor structure ---@param mek_data table local function _copy_struct(mek_data) - self.sDB.mek_struct.length = mek_data[1] - self.sDB.mek_struct.width = mek_data[2] - self.sDB.mek_struct.height = mek_data[3] - self.sDB.mek_struct.min_pos = mek_data[4] - self.sDB.mek_struct.max_pos = mek_data[5] - self.sDB.mek_struct.heat_cap = mek_data[6] - self.sDB.mek_struct.fuel_asm = mek_data[7] - self.sDB.mek_struct.fuel_sa = mek_data[8] - self.sDB.mek_struct.fuel_cap = mek_data[9] - self.sDB.mek_struct.waste_cap = mek_data[10] - self.sDB.mek_struct.ccool_cap = mek_data[11] - self.sDB.mek_struct.hcool_cap = mek_data[12] - self.sDB.mek_struct.max_burn = mek_data[13] + local struct = self.sDB.mek_struct + + struct.length = mek_data[1] + struct.width = mek_data[2] + struct.height = mek_data[3] + struct.min_pos = mek_data[4] + struct.max_pos = mek_data[5] + struct.heat_cap = mek_data[6] + struct.fuel_asm = mek_data[7] + struct.fuel_sa = mek_data[8] + struct.fuel_cap = mek_data[9] + struct.waste_cap = mek_data[10] + struct.ccool_cap = mek_data[11] + struct.hcool_cap = mek_data[12] + struct.max_burn = mek_data[13] + end + + -- handle a reactor status packet + ---@param pkt rplc_frame + local function _handle_status(pkt) + local valid = (type(pkt.data[1]) == "number") and (type(pkt.data[2]) == "boolean") and + (type(pkt.data[3]) == "boolean") and (type(pkt.data[4]) == "boolean") and + (type(pkt.data[5]) == "number") + + if valid then + self.sDB.last_status_update = pkt.data[1] + self.sDB.control_state = pkt.data[2] + self.sDB.no_reactor = pkt.data[3] + self.sDB.formed = pkt.data[4] + self.sDB.auto_ack_token = pkt.data[5] + + if (not self.sDB.no_reactor) and self.sDB.formed and (type(pkt.data[6]) == "number") then + self.sDB.mek_status.heating_rate = pkt.data[6] or 0.0 + + -- attempt to read mek_data table + if type(pkt.data[7]) == "table" then + if #pkt.data[7] == 17 then + _copy_status(pkt.data[7]) + self.received_status_cache = true + else + log.error(log_header .. "RPLC status packet reactor data length mismatch") + end + end + end + else + log.debug(log_header .. "RPLC status packet invalid") + end end -- mark this PLC session as closed, stop watchdog @@ -332,48 +372,17 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue, if pkt.type == RPLC_TYPE.STATUS then -- status packet received, update data if pkt.length >= 5 then - if (type(pkt.data[1]) == "number") and (type(pkt.data[2]) == "boolean") and (type(pkt.data[3]) == "boolean") and - (type(pkt.data[4]) == "boolean") and (type(pkt.data[5]) == "number") then - self.sDB.last_status_update = pkt.data[1] - self.sDB.control_state = pkt.data[2] - self.sDB.no_reactor = pkt.data[3] - self.sDB.formed = pkt.data[4] - self.sDB.auto_ack_token = pkt.data[5] - - if (not self.sDB.no_reactor) and self.sDB.formed and (type(pkt.data[6]) == "number") then - self.sDB.mek_status.heating_rate = pkt.data[6] or 0.0 - - -- attempt to read mek_data table - if type(pkt.data[7]) == "table" then - local status = pcall(_copy_status, pkt.data[7]) - if status then - -- copied in status data OK - self.received_status_cache = true - else - -- error copying status data - log.error(log_header .. "failed to parse status packet data") - end - end - end - else - log.debug(log_header .. "RPLC status packet invalid") - end + _handle_status(pkt) else log.debug(log_header .. "RPLC status packet length mismatch") end elseif pkt.type == RPLC_TYPE.MEK_STRUCT then -- received reactor structure, record it - if pkt.length == 14 then - local status = pcall(_copy_struct, pkt.data) - if status then - -- copied in structure data OK - _compute_op_temps() - self.received_struct = true - out_queue.push_data(svqtypes.SV_Q_DATA.PLC_BUILD_CHANGED, reactor_id) - else - -- error copying structure data - log.error(log_header .. "failed to parse struct packet data") - end + if pkt.length == 13 then + _copy_struct(pkt.data) + _compute_op_temps() + self.received_struct = true + out_queue.push_data(svqtypes.SV_Q_DATA.PLC_BUILD_CHANGED, reactor_id) else log.debug(log_header .. "RPLC struct packet length mismatch") end