diff --git a/reactor-plc/plc.lua b/reactor-plc/plc.lua index 6e62815..0942bdc 100644 --- a/reactor-plc/plc.lua +++ b/reactor-plc/plc.lua @@ -284,8 +284,9 @@ function plc.rps_init(reactor, is_formed) self.state[state_keys.sys_fail] = true end - -- SCRAM the reactor now (blocks waiting for server tick) + -- SCRAM the reactor now
---@return boolean success + --- EVENT_CONSUMER: this function consumes events function public.scram() log.info("RPS: reactor SCRAM") @@ -300,8 +301,9 @@ function plc.rps_init(reactor, is_formed) end end - -- start the reactor now (blocks waiting for server tick) + -- start the reactor now
---@return boolean success + --- EVENT_CONSUMER: this function consumes events function public.activate() if not self.tripped then log.info("RPS: reactor start") @@ -654,10 +656,7 @@ function plc.comms(version, nic, reactor, rps, conn_watchdog) -- send structure properties (these should not change, server will cache these) local function _send_struct() - local min_pos = { x = 0, y = 0, z = 0 } - local max_pos = { x = 0, y = 0, z = 0 } - - local mek_data = { false, 0, 0, 0, min_pos, max_pos, 0, 0, 0, 0, 0, 0, 0, 0 } + local mek_data = { false, 0, 0, 0, types.new_zero_coordinate(), types.new_zero_coordinate(), 0, 0, 0, 0, 0, 0, 0, 0 } local tasks = { function () mek_data[1] = reactor.getLength() end, @@ -727,21 +726,18 @@ function plc.comms(version, nic, reactor, rps, conn_watchdog) local heating_rate = 0.0 ---@type number if (not no_reactor) and rps.is_formed() then - if _update_status_cache() then - mek_data = self.status_cache - end - + if _update_status_cache() then mek_data = self.status_cache end heating_rate = reactor.getHeatingRate() end local sys_status = { - util.time(), -- timestamp - (not self.scrammed), -- requested control state - no_reactor, -- no reactor peripheral connected - formed, -- reactor formed - self.auto_ack_token, -- token to indicate auto command has been received before this status update - heating_rate, -- heating rate - mek_data -- mekanism status data + util.time(), -- timestamp + (not self.scrammed), -- requested control state + no_reactor, -- no reactor peripheral connected + formed, -- reactor formed + self.auto_ack_token, -- indicate auto command received prior to this status update + heating_rate, -- heating rate + mek_data -- mekanism status data } _send(RPLC_TYPE.STATUS, sys_status) @@ -879,6 +875,10 @@ function plc.comms(version, nic, reactor, rps, conn_watchdog) -- enable the reactor self.scrammed = false _send_ack(packet.type, rps.activate()) + elseif packet.type == RPLC_TYPE.RPS_DISABLE then + -- disable the reactor, but do not trip + self.scrammed = true + _send_ack(packet.type, rps.scram()) elseif packet.type == RPLC_TYPE.RPS_SCRAM then -- disable the reactor per manual request self.scrammed = true diff --git a/scada-common/comms.lua b/scada-common/comms.lua index 081950e..4bf8262 100644 --- a/scada-common/comms.lua +++ b/scada-common/comms.lua @@ -17,7 +17,7 @@ local max_distance = nil local comms = {} -- protocol version (non-protocol changes tracked by util.lua version) -comms.version = "2.3.0" +comms.version = "2.4.0" ---@enum PROTOCOL local PROTOCOL = { @@ -33,13 +33,14 @@ local RPLC_TYPE = { MEK_STRUCT = 1, -- mekanism build structure MEK_BURN_RATE = 2, -- set burn rate RPS_ENABLE = 3, -- enable reactor - RPS_SCRAM = 4, -- SCRAM reactor (manual request) - RPS_ASCRAM = 5, -- SCRAM reactor (automatic request) - RPS_STATUS = 6, -- RPS status - RPS_ALARM = 7, -- RPS alarm broadcast - RPS_RESET = 8, -- clear RPS trip (if in bad state, will trip immediately) - RPS_AUTO_RESET = 9, -- clear RPS trip if it is just a timeout or auto scram - AUTO_BURN_RATE = 10 -- set an automatic burn rate, PLC will respond with status, enable toggle speed limited + RPS_DISABLE = 4, -- disable the reactor + RPS_SCRAM = 5, -- SCRAM reactor (manual request) + RPS_ASCRAM = 6, -- SCRAM reactor (automatic request) + RPS_STATUS = 7, -- RPS status + RPS_ALARM = 8, -- RPS alarm broadcast + RPS_RESET = 9, -- clear RPS trip (if in bad state, will trip immediately) + RPS_AUTO_RESET = 10, -- clear RPS trip if it is just a timeout or auto scram + AUTO_BURN_RATE = 11 -- set an automatic burn rate, PLC will respond with status, enable toggle speed limited } ---@enum MGMT_TYPE @@ -396,9 +397,7 @@ function comms.modbus_packet() -- populate raw array self.raw = { self.txn_id, self.unit_id, self.func_code } - for i = 1, self.length do - insert(self.raw, data[i]) - end + for i = 1, self.length do insert(self.raw, data[i]) end else log.error("comms.modbus_packet.make(): data not table") end @@ -484,9 +483,7 @@ function comms.rplc_packet() -- populate raw array self.raw = { self.id, self.type } - for i = 1, #data do - insert(self.raw, data[i]) - end + for i = 1, #data do insert(self.raw, data[i]) end else log.error("comms.rplc_packet.make(): data not table") end @@ -568,9 +565,7 @@ function comms.mgmt_packet() -- populate raw array self.raw = { self.type } - for i = 1, #data do - insert(self.raw, data[i]) - end + for i = 1, #data do insert(self.raw, data[i]) end else log.error("comms.mgmt_packet.make(): data not table") end @@ -649,9 +644,7 @@ function comms.crdn_packet() -- populate raw array self.raw = { self.type } - for i = 1, #data do - insert(self.raw, data[i]) - end + for i = 1, #data do insert(self.raw, data[i]) end else log.error("comms.crdn_packet.make(): data not table") end diff --git a/supervisor/facility.lua b/supervisor/facility.lua index 8c91157..30bcd68 100644 --- a/supervisor/facility.lua +++ b/supervisor/facility.lua @@ -399,10 +399,9 @@ function facility.new(num_reactors, cooling_conf) end elseif self.mode == PROCESS.INACTIVE then for i = 1, #self.prio_defs do - -- SCRAM reactors and disengage auto control - -- use manual SCRAM since inactive was requested, and automatic SCRAM trips an alarm + -- disable reactors and disengage auto control for _, u in pairs(self.prio_defs[i]) do - u.scram() + u.disable() u.auto_disengage() end end diff --git a/supervisor/session/plc.lua b/supervisor/session/plc.lua index 654ca99..23fb1c6 100644 --- a/supervisor/session/plc.lua +++ b/supervisor/session/plc.lua @@ -25,8 +25,9 @@ local PLC_S_CMDS = { SCRAM = 1, ASCRAM = 2, ENABLE = 3, - RPS_RESET = 4, - RPS_AUTO_RESET = 5 + DISABLE = 4, + RPS_RESET = 5, + RPS_AUTO_RESET = 6 } local PLC_S_DATA = { @@ -80,6 +81,7 @@ function plc.new_session(id, s_addr, reactor_id, in_queue, out_queue, timeout, f retry_times = { struct_req = (util.time() + 500), status_req = (util.time() + 500), + disable_req = 0, scram_req = 0, ascram_req = 0, burn_rate_req = 0, @@ -87,6 +89,7 @@ function plc.new_session(id, s_addr, reactor_id, in_queue, out_queue, timeout, f }, -- command acknowledgements acks = { + disable = true, scram = true, ascram = true, burn_rate = true, @@ -627,6 +630,11 @@ function plc.new_session(id, s_addr, reactor_id, in_queue, out_queue, timeout, f if not self.auto_lock then _send(RPLC_TYPE.RPS_ENABLE, {}) end + elseif cmd == PLC_S_CMDS.DISABLE then + -- disable the reactor + self.acks.disable = false + self.retry_times.disable_req = util.time() + INITIAL_WAIT + _send(RPLC_TYPE.RPS_DISABLE, {}) elseif cmd == PLC_S_CMDS.SCRAM then -- SCRAM reactor self.acks.scram = false @@ -780,6 +788,15 @@ function plc.new_session(id, s_addr, reactor_id, in_queue, out_queue, timeout, f end end + -- reactor disable request retry + + if not self.acks.disable then + if rtimes.disable_req - util.time() <= 0 then + _send(RPLC_TYPE.RPS_DISABLE, {}) + rtimes.disable_req = util.time() + RETRY_PERIOD + end + end + -- SCRAM request retry if not self.acks.scram then diff --git a/supervisor/unit.lua b/supervisor/unit.lua index 262de6b..e0fe65e 100644 --- a/supervisor/unit.lua +++ b/supervisor/unit.lua @@ -645,6 +645,13 @@ function unit.new(reactor_id, num_boilers, num_turbines) -- OPERATIONS -- --#region + -- queue a command to disable the reactor + function public.disable() + if self.plc_s ~= nil then + self.plc_s.in_queue.push_command(PLC_S_CMDS.DISABLE) + end + end + -- queue a command to SCRAM the reactor function public.scram() if self.plc_s ~= nil then