#640 reworked PLC initialization
This commit is contained in:
@@ -707,6 +707,112 @@ function plc.comms(version, nic, reactor, rps, conn_watchdog)
|
||||
reactor.__p_enable_afc()
|
||||
end
|
||||
|
||||
-- handle a burn rate command
|
||||
---@param packet rplc_frame
|
||||
---@param setpoints plc_setpoints
|
||||
--- EVENT_CONSUMER: this function consumes events
|
||||
local function _handle_burn_rate(packet, setpoints)
|
||||
if (packet.length == 2) and (type(packet.data[1]) == "number") then
|
||||
local success = false
|
||||
local burn_rate = math.floor(packet.data[1] * 10) / 10
|
||||
local ramp = packet.data[2]
|
||||
|
||||
-- if no known max burn rate, check again
|
||||
if self.max_burn_rate == nil then
|
||||
self.max_burn_rate = reactor.getMaxBurnRate()
|
||||
end
|
||||
|
||||
-- if we know our max burn rate, update current burn rate setpoint if in range
|
||||
if self.max_burn_rate ~= ppm.ACCESS_FAULT then
|
||||
if burn_rate > 0 and burn_rate <= self.max_burn_rate then
|
||||
if ramp then
|
||||
setpoints.burn_rate_en = true
|
||||
setpoints.burn_rate = burn_rate
|
||||
success = true
|
||||
else
|
||||
reactor.setBurnRate(burn_rate)
|
||||
success = reactor.__p_is_ok()
|
||||
end
|
||||
else
|
||||
log.debug(burn_rate .. " rate outside of 0 < x <= " .. self.max_burn_rate)
|
||||
end
|
||||
end
|
||||
|
||||
_send_ack(packet.type, success)
|
||||
else
|
||||
log.debug("RPLC set burn rate packet length mismatch or non-numeric burn rate")
|
||||
end
|
||||
end
|
||||
|
||||
-- handle an auto burn rate command
|
||||
---@param packet rplc_frame
|
||||
---@param setpoints plc_setpoints
|
||||
--- EVENT_CONSUMER: this function consumes events
|
||||
local function _handle_auto_burn_rate(packet, setpoints)
|
||||
if (packet.length == 3) and (type(packet.data[1]) == "number") and (type(packet.data[3]) == "number") then
|
||||
local ack = AUTO_ACK.FAIL
|
||||
local burn_rate = math.floor(packet.data[1] * 100) / 100
|
||||
local ramp = packet.data[2]
|
||||
self.auto_ack_token = packet.data[3]
|
||||
|
||||
-- if no known max burn rate, check again
|
||||
if self.max_burn_rate == nil then
|
||||
self.max_burn_rate = reactor.getMaxBurnRate()
|
||||
end
|
||||
|
||||
-- if we know our max burn rate, update current burn rate setpoint if in range
|
||||
if self.max_burn_rate ~= ppm.ACCESS_FAULT then
|
||||
if burn_rate < 0.01 then
|
||||
if rps.is_active() then
|
||||
-- auto scram to disable
|
||||
log.debug("AUTO: stopping the reactor to meet 0.0 burn rate")
|
||||
if rps.scram() then
|
||||
ack = AUTO_ACK.ZERO_DIS_OK
|
||||
else
|
||||
log.warning("AUTO: automatic reactor stop failed")
|
||||
end
|
||||
else
|
||||
ack = AUTO_ACK.ZERO_DIS_OK
|
||||
end
|
||||
elseif burn_rate <= self.max_burn_rate then
|
||||
if not rps.is_active() then
|
||||
-- activate the reactor
|
||||
log.debug("AUTO: activating the reactor")
|
||||
|
||||
reactor.setBurnRate(0.01)
|
||||
if reactor.__p_is_faulted() then
|
||||
log.warning("AUTO: failed to reset burn rate for auto activation")
|
||||
else
|
||||
if not rps.auto_activate() then
|
||||
log.warning("AUTO: automatic reactor activation failed")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- if active, set/ramp burn rate
|
||||
if rps.is_active() then
|
||||
if ramp then
|
||||
log.debug(util.c("AUTO: setting burn rate ramp to ", burn_rate))
|
||||
setpoints.burn_rate_en = true
|
||||
setpoints.burn_rate = burn_rate
|
||||
ack = AUTO_ACK.RAMP_SET_OK
|
||||
else
|
||||
log.debug(util.c("AUTO: setting burn rate directly to ", burn_rate))
|
||||
reactor.setBurnRate(burn_rate)
|
||||
ack = util.trinary(reactor.__p_is_faulted(), AUTO_ACK.FAIL, AUTO_ACK.DIRECT_SET_OK)
|
||||
end
|
||||
end
|
||||
else
|
||||
log.debug(util.c(burn_rate, " rate outside of 0 < x <= ", self.max_burn_rate))
|
||||
end
|
||||
end
|
||||
|
||||
_send_ack(packet.type, ack)
|
||||
else
|
||||
log.debug("RPLC set automatic burn rate packet length mismatch or non-numeric burn rate")
|
||||
end
|
||||
end
|
||||
|
||||
-- PUBLIC FUNCTIONS --
|
||||
|
||||
---@class plc_comms
|
||||
@@ -748,8 +854,8 @@ function plc.comms(version, nic, reactor, rps, conn_watchdog)
|
||||
---@param formed boolean reactor formed (from PLC state)
|
||||
function public.send_status(no_reactor, formed)
|
||||
if self.linked then
|
||||
local mek_data = nil ---@type table
|
||||
local heating_rate = 0.0 ---@type number
|
||||
local mek_data = nil ---@type table
|
||||
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
|
||||
@@ -803,15 +909,11 @@ function plc.comms(version, nic, reactor, rps, conn_watchdog)
|
||||
-- get as RPLC packet
|
||||
if s_pkt.protocol() == PROTOCOL.RPLC then
|
||||
local rplc_pkt = comms.rplc_packet()
|
||||
if rplc_pkt.decode(s_pkt) then
|
||||
pkt = rplc_pkt.get()
|
||||
end
|
||||
if rplc_pkt.decode(s_pkt) then pkt = rplc_pkt.get() end
|
||||
-- get as SCADA management packet
|
||||
elseif s_pkt.protocol() == PROTOCOL.SCADA_MGMT then
|
||||
local mgmt_pkt = comms.mgmt_packet()
|
||||
if mgmt_pkt.decode(s_pkt) then
|
||||
pkt = mgmt_pkt.get()
|
||||
end
|
||||
if mgmt_pkt.decode(s_pkt) then pkt = mgmt_pkt.get() end
|
||||
else
|
||||
log.debug("unsupported packet type " .. s_pkt.protocol(), true)
|
||||
end
|
||||
@@ -823,16 +925,13 @@ function plc.comms(version, nic, reactor, rps, conn_watchdog)
|
||||
-- handle RPLC and MGMT packets
|
||||
---@param packet rplc_frame|mgmt_frame packet frame
|
||||
---@param plc_state plc_state PLC state
|
||||
---@param setpoints setpoints setpoint control table
|
||||
function public.handle_packet(packet, plc_state, setpoints)
|
||||
-- print a log message to the terminal as long as the UI isn't running
|
||||
local function println_ts(message) if not plc_state.fp_ok then util.println_ts(message) end end
|
||||
|
||||
---@param setpoints plc_setpoints setpoint control table
|
||||
---@param println_ts function console print, when UI isn't running
|
||||
function public.handle_packet(packet, plc_state, setpoints, println_ts)
|
||||
local protocol = packet.scada_frame.protocol()
|
||||
local l_chan = packet.scada_frame.local_channel()
|
||||
local src_addr = packet.scada_frame.src_addr()
|
||||
|
||||
-- handle packets now that we have prints setup
|
||||
if l_chan == config.PLC_Channel then
|
||||
-- check sequence number
|
||||
if self.r_seq_num == nil then
|
||||
@@ -867,36 +966,7 @@ function plc.comms(version, nic, reactor, rps, conn_watchdog)
|
||||
log.debug("sent out structure again, did supervisor miss it?")
|
||||
elseif packet.type == RPLC_TYPE.MEK_BURN_RATE then
|
||||
-- set the burn rate
|
||||
if (packet.length == 2) and (type(packet.data[1]) == "number") then
|
||||
local success = false
|
||||
local burn_rate = math.floor(packet.data[1] * 10) / 10
|
||||
local ramp = packet.data[2]
|
||||
|
||||
-- if no known max burn rate, check again
|
||||
if self.max_burn_rate == nil then
|
||||
self.max_burn_rate = reactor.getMaxBurnRate()
|
||||
end
|
||||
|
||||
-- if we know our max burn rate, update current burn rate setpoint if in range
|
||||
if self.max_burn_rate ~= ppm.ACCESS_FAULT then
|
||||
if burn_rate > 0 and burn_rate <= self.max_burn_rate then
|
||||
if ramp then
|
||||
setpoints.burn_rate_en = true
|
||||
setpoints.burn_rate = burn_rate
|
||||
success = true
|
||||
else
|
||||
reactor.setBurnRate(burn_rate)
|
||||
success = reactor.__p_is_ok()
|
||||
end
|
||||
else
|
||||
log.debug(burn_rate .. " rate outside of 0 < x <= " .. self.max_burn_rate)
|
||||
end
|
||||
end
|
||||
|
||||
_send_ack(packet.type, success)
|
||||
else
|
||||
log.debug("RPLC set burn rate packet length mismatch or non-numeric burn rate")
|
||||
end
|
||||
_handle_burn_rate(packet, setpoints)
|
||||
elseif packet.type == RPLC_TYPE.RPS_ENABLE then
|
||||
-- enable the reactor
|
||||
self.scrammed = false
|
||||
@@ -925,68 +995,7 @@ function plc.comms(version, nic, reactor, rps, conn_watchdog)
|
||||
_send_ack(packet.type, true)
|
||||
elseif packet.type == RPLC_TYPE.AUTO_BURN_RATE then
|
||||
-- automatic control requested a new burn rate
|
||||
if (packet.length == 3) and (type(packet.data[1]) == "number") and (type(packet.data[3]) == "number") then
|
||||
local ack = AUTO_ACK.FAIL
|
||||
local burn_rate = math.floor(packet.data[1] * 100) / 100
|
||||
local ramp = packet.data[2]
|
||||
self.auto_ack_token = packet.data[3]
|
||||
|
||||
-- if no known max burn rate, check again
|
||||
if self.max_burn_rate == nil then
|
||||
self.max_burn_rate = reactor.getMaxBurnRate()
|
||||
end
|
||||
|
||||
-- if we know our max burn rate, update current burn rate setpoint if in range
|
||||
if self.max_burn_rate ~= ppm.ACCESS_FAULT then
|
||||
if burn_rate < 0.01 then
|
||||
if rps.is_active() then
|
||||
-- auto scram to disable
|
||||
log.debug("AUTO: stopping the reactor to meet 0.0 burn rate")
|
||||
if rps.scram() then
|
||||
ack = AUTO_ACK.ZERO_DIS_OK
|
||||
else
|
||||
log.warning("AUTO: automatic reactor stop failed")
|
||||
end
|
||||
else
|
||||
ack = AUTO_ACK.ZERO_DIS_OK
|
||||
end
|
||||
elseif burn_rate <= self.max_burn_rate then
|
||||
if not rps.is_active() then
|
||||
-- activate the reactor
|
||||
log.debug("AUTO: activating the reactor")
|
||||
|
||||
reactor.setBurnRate(0.01)
|
||||
if reactor.__p_is_faulted() then
|
||||
log.warning("AUTO: failed to reset burn rate for auto activation")
|
||||
else
|
||||
if not rps.auto_activate() then
|
||||
log.warning("AUTO: automatic reactor activation failed")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- if active, set/ramp burn rate
|
||||
if rps.is_active() then
|
||||
if ramp then
|
||||
log.debug(util.c("AUTO: setting burn rate ramp to ", burn_rate))
|
||||
setpoints.burn_rate_en = true
|
||||
setpoints.burn_rate = burn_rate
|
||||
ack = AUTO_ACK.RAMP_SET_OK
|
||||
else
|
||||
log.debug(util.c("AUTO: setting burn rate directly to ", burn_rate))
|
||||
reactor.setBurnRate(burn_rate)
|
||||
ack = util.trinary(reactor.__p_is_faulted(), AUTO_ACK.FAIL, AUTO_ACK.DIRECT_SET_OK)
|
||||
end
|
||||
end
|
||||
else
|
||||
log.debug(util.c(burn_rate, " rate outside of 0 < x <= ", self.max_burn_rate))
|
||||
end
|
||||
end
|
||||
|
||||
_send_ack(packet.type, ack)
|
||||
else
|
||||
log.debug("RPLC set automatic burn rate packet length mismatch or non-numeric burn rate")
|
||||
end
|
||||
_handle_auto_burn_rate(packet, setpoints)
|
||||
else
|
||||
log.debug("received unknown RPLC packet type " .. packet.type)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user