Merge pull request #577 from MikaylaFischler/pocket-alpha-dev
Waste App
This commit is contained in:
commit
56e4f93db8
@ -105,6 +105,7 @@ function iocontrol.init(conf, comms, temp_scale, energy_scale)
|
|||||||
auto_current_waste_product = types.WASTE_PRODUCT.PLUTONIUM,
|
auto_current_waste_product = types.WASTE_PRODUCT.PLUTONIUM,
|
||||||
auto_pu_fallback_active = false,
|
auto_pu_fallback_active = false,
|
||||||
auto_sps_disabled = false,
|
auto_sps_disabled = false,
|
||||||
|
waste_stats = { 0, 0, 0, 0, 0, 0 }, -- waste in, pu, po, po pellets, am, spent waste
|
||||||
|
|
||||||
radiation = types.new_zero_radiation_reading(),
|
radiation = types.new_zero_radiation_reading(),
|
||||||
|
|
||||||
@ -118,6 +119,7 @@ function iocontrol.init(conf, comms, temp_scale, energy_scale)
|
|||||||
induction_ps_tbl = {}, ---@type psil[]
|
induction_ps_tbl = {}, ---@type psil[]
|
||||||
induction_data_tbl = {}, ---@type imatrix_session_db[]
|
induction_data_tbl = {}, ---@type imatrix_session_db[]
|
||||||
|
|
||||||
|
sps_status = 1,
|
||||||
sps_ps_tbl = {}, ---@type psil[]
|
sps_ps_tbl = {}, ---@type psil[]
|
||||||
sps_data_tbl = {}, ---@type sps_session_db[]
|
sps_data_tbl = {}, ---@type sps_session_db[]
|
||||||
|
|
||||||
@ -174,6 +176,7 @@ function iocontrol.init(conf, comms, temp_scale, energy_scale)
|
|||||||
|
|
||||||
waste_mode = types.WASTE_MODE.MANUAL_PLUTONIUM,
|
waste_mode = types.WASTE_MODE.MANUAL_PLUTONIUM,
|
||||||
waste_product = types.WASTE_PRODUCT.PLUTONIUM,
|
waste_product = types.WASTE_PRODUCT.PLUTONIUM,
|
||||||
|
waste_stats = { 0, 0, 0 }, -- plutonium, polonium, po pellets
|
||||||
|
|
||||||
last_rate_change_ms = 0,
|
last_rate_change_ms = 0,
|
||||||
turbine_flow_stable = false,
|
turbine_flow_stable = false,
|
||||||
@ -662,6 +665,8 @@ function iocontrol.update_facility_status(status)
|
|||||||
|
|
||||||
-- SPS statuses
|
-- SPS statuses
|
||||||
if type(rtu_statuses.sps) == "table" then
|
if type(rtu_statuses.sps) == "table" then
|
||||||
|
local sps_status = 1
|
||||||
|
|
||||||
for id = 1, #fac.sps_ps_tbl do
|
for id = 1, #fac.sps_ps_tbl do
|
||||||
if rtu_statuses.sps[id] == nil then
|
if rtu_statuses.sps[id] == nil then
|
||||||
-- disconnected
|
-- disconnected
|
||||||
@ -677,22 +682,21 @@ function iocontrol.update_facility_status(status)
|
|||||||
local rtu_faulted = _record_multiblock_status(sps, data, ps)
|
local rtu_faulted = _record_multiblock_status(sps, data, ps)
|
||||||
|
|
||||||
if rtu_faulted then
|
if rtu_faulted then
|
||||||
ps.publish("computed_status", 3) -- faulted
|
sps_status = 3 -- faulted
|
||||||
elseif data.formed then
|
elseif data.formed then
|
||||||
if data.state.process_rate > 0 then
|
-- active / idle
|
||||||
ps.publish("computed_status", 5) -- active
|
sps_status = util.trinary(data.state.process_rate > 0, 5, 4)
|
||||||
else
|
else sps_status = 2 end -- not formed
|
||||||
ps.publish("computed_status", 4) -- idle
|
|
||||||
end
|
ps.publish("computed_status", sps_status)
|
||||||
else
|
|
||||||
ps.publish("computed_status", 2) -- not formed
|
|
||||||
end
|
|
||||||
|
|
||||||
io.facility.ps.publish("am_rate", data.state.process_rate * 1000)
|
io.facility.ps.publish("am_rate", data.state.process_rate * 1000)
|
||||||
else
|
else
|
||||||
log.debug(util.c(log_header, "invalid sps id ", id))
|
log.debug(util.c(log_header, "invalid sps id ", id))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
io.facility.sps_status = sps_status
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "sps list not a table")
|
log.debug(log_header .. "sps list not a table")
|
||||||
valid = false
|
valid = false
|
||||||
@ -1192,6 +1196,7 @@ function iocontrol.update_unit_statuses(statuses)
|
|||||||
local u_spent_rate = waste_rate
|
local u_spent_rate = waste_rate
|
||||||
local u_pu_rate = util.trinary(is_pu, waste_rate, 0.0)
|
local u_pu_rate = util.trinary(is_pu, waste_rate, 0.0)
|
||||||
local u_po_rate = unit.sna_out_rate
|
local u_po_rate = unit.sna_out_rate
|
||||||
|
local u_po_pl_rate = 0
|
||||||
|
|
||||||
unit.unit_ps.publish("pu_rate", u_pu_rate)
|
unit.unit_ps.publish("pu_rate", u_pu_rate)
|
||||||
unit.unit_ps.publish("po_rate", u_po_rate)
|
unit.unit_ps.publish("po_rate", u_po_rate)
|
||||||
@ -1202,6 +1207,7 @@ function iocontrol.update_unit_statuses(statuses)
|
|||||||
u_spent_rate = u_po_rate
|
u_spent_rate = u_po_rate
|
||||||
unit.unit_ps.publish("po_pl_rate", u_po_rate)
|
unit.unit_ps.publish("po_pl_rate", u_po_rate)
|
||||||
unit.unit_ps.publish("po_am_rate", 0)
|
unit.unit_ps.publish("po_am_rate", 0)
|
||||||
|
u_po_pl_rate = u_po_rate
|
||||||
po_pl_rate = po_pl_rate + u_po_rate
|
po_pl_rate = po_pl_rate + u_po_rate
|
||||||
elseif unit.waste_product == types.WASTE_PRODUCT.ANTI_MATTER then
|
elseif unit.waste_product == types.WASTE_PRODUCT.ANTI_MATTER then
|
||||||
u_spent_rate = 0
|
u_spent_rate = 0
|
||||||
@ -1213,6 +1219,8 @@ function iocontrol.update_unit_statuses(statuses)
|
|||||||
unit.unit_ps.publish("po_am_rate", 0)
|
unit.unit_ps.publish("po_am_rate", 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
unit.waste_stats = { u_pu_rate, u_po_rate, u_po_pl_rate }
|
||||||
|
|
||||||
unit.unit_ps.publish("ws_rate", u_spent_rate)
|
unit.unit_ps.publish("ws_rate", u_spent_rate)
|
||||||
|
|
||||||
pu_rate = pu_rate + u_pu_rate
|
pu_rate = pu_rate + u_pu_rate
|
||||||
@ -1221,6 +1229,8 @@ function iocontrol.update_unit_statuses(statuses)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
io.facility.waste_stats = { burn_rate_sum, pu_rate, po_rate, po_pl_rate, po_am_rate, spent_rate }
|
||||||
|
|
||||||
io.facility.ps.publish("burn_sum", burn_rate_sum)
|
io.facility.ps.publish("burn_sum", burn_rate_sum)
|
||||||
io.facility.ps.publish("sna_count", sna_count_sum)
|
io.facility.ps.publish("sna_count", sna_count_sum)
|
||||||
io.facility.ps.publish("pu_rate", pu_rate)
|
io.facility.ps.publish("pu_rate", pu_rate)
|
||||||
|
|||||||
@ -445,36 +445,21 @@ end
|
|||||||
---@param product WASTE_PRODUCT waste product for auto control
|
---@param product WASTE_PRODUCT waste product for auto control
|
||||||
function process.set_process_waste(product)
|
function process.set_process_waste(product)
|
||||||
pctl.comms.send_fac_command(F_CMD.SET_WASTE_MODE, product)
|
pctl.comms.send_fac_command(F_CMD.SET_WASTE_MODE, product)
|
||||||
|
|
||||||
log.debug(util.c("PROCESS: SET WASTE ", product))
|
log.debug(util.c("PROCESS: SET WASTE ", product))
|
||||||
|
|
||||||
-- update config table and save
|
|
||||||
pctl.control_states.process.waste_product = product
|
|
||||||
_write_auto_config()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- set automatic process control plutonium fallback
|
-- set automatic process control plutonium fallback
|
||||||
---@param enabled boolean whether to enable plutonium fallback
|
---@param enabled boolean whether to enable plutonium fallback
|
||||||
function process.set_pu_fallback(enabled)
|
function process.set_pu_fallback(enabled)
|
||||||
pctl.comms.send_fac_command(F_CMD.SET_PU_FB, enabled)
|
pctl.comms.send_fac_command(F_CMD.SET_PU_FB, enabled)
|
||||||
|
|
||||||
log.debug(util.c("PROCESS: SET PU FALLBACK ", enabled))
|
log.debug(util.c("PROCESS: SET PU FALLBACK ", enabled))
|
||||||
|
|
||||||
-- update config table and save
|
|
||||||
pctl.control_states.process.pu_fallback = enabled
|
|
||||||
_write_auto_config()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- set automatic process control SPS usage at low power
|
-- set automatic process control SPS usage at low power
|
||||||
---@param enabled boolean whether to enable SPS usage at low power
|
---@param enabled boolean whether to enable SPS usage at low power
|
||||||
function process.set_sps_low_power(enabled)
|
function process.set_sps_low_power(enabled)
|
||||||
pctl.comms.send_fac_command(F_CMD.SET_SPS_LP, enabled)
|
pctl.comms.send_fac_command(F_CMD.SET_SPS_LP, enabled)
|
||||||
|
|
||||||
log.debug(util.c("PROCESS: SET SPS LOW POWER ", enabled))
|
log.debug(util.c("PROCESS: SET SPS LOW POWER ", enabled))
|
||||||
|
|
||||||
-- update config table and save
|
|
||||||
pctl.control_states.process.sps_low_power = enabled
|
|
||||||
_write_auto_config()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- save process control settings
|
-- save process control settings
|
||||||
@ -527,21 +512,30 @@ end
|
|||||||
-- record waste product settting after attempting to change it
|
-- record waste product settting after attempting to change it
|
||||||
---@param response WASTE_PRODUCT supervisor waste product settting
|
---@param response WASTE_PRODUCT supervisor waste product settting
|
||||||
function process.waste_ack_handle(response)
|
function process.waste_ack_handle(response)
|
||||||
|
-- update config table and save
|
||||||
pctl.control_states.process.waste_product = response
|
pctl.control_states.process.waste_product = response
|
||||||
|
_write_auto_config()
|
||||||
|
|
||||||
pctl.io.facility.ps.publish("process_waste_product", response)
|
pctl.io.facility.ps.publish("process_waste_product", response)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- record plutonium fallback settting after attempting to change it
|
-- record plutonium fallback settting after attempting to change it
|
||||||
---@param response boolean supervisor plutonium fallback settting
|
---@param response boolean supervisor plutonium fallback settting
|
||||||
function process.pu_fb_ack_handle(response)
|
function process.pu_fb_ack_handle(response)
|
||||||
|
-- update config table and save
|
||||||
pctl.control_states.process.pu_fallback = response
|
pctl.control_states.process.pu_fallback = response
|
||||||
|
_write_auto_config()
|
||||||
|
|
||||||
pctl.io.facility.ps.publish("process_pu_fallback", response)
|
pctl.io.facility.ps.publish("process_pu_fallback", response)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- record SPS low power settting after attempting to change it
|
-- record SPS low power settting after attempting to change it
|
||||||
---@param response boolean supervisor SPS low power settting
|
---@param response boolean supervisor SPS low power settting
|
||||||
function process.sps_lp_ack_handle(response)
|
function process.sps_lp_ack_handle(response)
|
||||||
|
-- update config table and save
|
||||||
pctl.control_states.process.sps_low_power = response
|
pctl.control_states.process.sps_low_power = response
|
||||||
|
_write_auto_config()
|
||||||
|
|
||||||
pctl.io.facility.ps.publish("process_sps_low_power", response)
|
pctl.io.facility.ps.publish("process_sps_low_power", response)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
local comms = require("scada-common.comms")
|
local comms = require("scada-common.comms")
|
||||||
local log = require("scada-common.log")
|
local log = require("scada-common.log")
|
||||||
local mqueue = require("scada-common.mqueue")
|
local mqueue = require("scada-common.mqueue")
|
||||||
|
local types = require("scada-common.types")
|
||||||
local util = require("scada-common.util")
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
local iocontrol = require("coordinator.iocontrol")
|
local iocontrol = require("coordinator.iocontrol")
|
||||||
@ -14,6 +15,9 @@ local MGMT_TYPE = comms.MGMT_TYPE
|
|||||||
local FAC_COMMAND = comms.FAC_COMMAND
|
local FAC_COMMAND = comms.FAC_COMMAND
|
||||||
local UNIT_COMMAND = comms.UNIT_COMMAND
|
local UNIT_COMMAND = comms.UNIT_COMMAND
|
||||||
|
|
||||||
|
local AUTO_GROUP = types.AUTO_GROUP
|
||||||
|
local WASTE_MODE = types.WASTE_MODE
|
||||||
|
|
||||||
-- retry time constants in ms
|
-- retry time constants in ms
|
||||||
-- local INITIAL_WAIT = 1500
|
-- local INITIAL_WAIT = 1500
|
||||||
-- local RETRY_PERIOD = 1000
|
-- local RETRY_PERIOD = 1000
|
||||||
@ -166,8 +170,26 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout)
|
|||||||
log.info(log_tag .. "FAC ACK ALL ALARMS")
|
log.info(log_tag .. "FAC ACK ALL ALARMS")
|
||||||
self.proc_handle.fac_ack_alarms()
|
self.proc_handle.fac_ack_alarms()
|
||||||
elseif cmd == FAC_COMMAND.SET_WASTE_MODE then
|
elseif cmd == FAC_COMMAND.SET_WASTE_MODE then
|
||||||
|
if pkt.length == 2 then
|
||||||
|
log.info(util.c(log_tag, " SET WASTE ", pkt.data[2]))
|
||||||
|
process.set_process_waste(pkt.data[2])
|
||||||
|
else
|
||||||
|
log.debug(log_tag .. "CRDN set waste mode packet length mismatch")
|
||||||
|
end
|
||||||
elseif cmd == FAC_COMMAND.SET_PU_FB then
|
elseif cmd == FAC_COMMAND.SET_PU_FB then
|
||||||
|
if pkt.length == 2 then
|
||||||
|
log.info(util.c(log_tag, " SET PU FALLBACK ", pkt.data[2]))
|
||||||
|
process.set_pu_fallback(pkt.data[2] == true)
|
||||||
|
else
|
||||||
|
log.debug(log_tag .. "CRDN set pu fallback packet length mismatch")
|
||||||
|
end
|
||||||
elseif cmd == FAC_COMMAND.SET_SPS_LP then
|
elseif cmd == FAC_COMMAND.SET_SPS_LP then
|
||||||
|
if pkt.length == 2 then
|
||||||
|
log.info(util.c(log_tag, " SET SPS LOW POWER ", pkt.data[2]))
|
||||||
|
process.set_sps_low_power(pkt.data[2] == true)
|
||||||
|
else
|
||||||
|
log.debug(log_tag .. "CRDN set sps low power packet length mismatch")
|
||||||
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_tag .. "CRDN facility command unknown")
|
log.debug(log_tag .. "CRDN facility command unknown")
|
||||||
end
|
end
|
||||||
@ -192,20 +214,28 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout)
|
|||||||
log.info(util.c(log_tag, "UNIT[", uid, "] RESET RPS"))
|
log.info(util.c(log_tag, "UNIT[", uid, "] RESET RPS"))
|
||||||
self.proc_handle.reset_rps(uid)
|
self.proc_handle.reset_rps(uid)
|
||||||
elseif cmd == UNIT_COMMAND.SET_BURN then
|
elseif cmd == UNIT_COMMAND.SET_BURN then
|
||||||
if pkt.length == 3 then
|
if (pkt.length == 3) and (type(pkt.data[3]) == "number") then
|
||||||
log.info(util.c(log_tag, "UNIT[", uid, "] SET BURN ", pkt.data[3]))
|
log.info(util.c(log_tag, "UNIT[", uid, "] SET BURN ", pkt.data[3]))
|
||||||
process.set_rate(uid, pkt.data[3])
|
process.set_rate(uid, pkt.data[3])
|
||||||
else
|
else
|
||||||
log.debug(log_tag .. "CRDN unit command burn rate missing option")
|
log.debug(log_tag .. "CRDN unit command burn rate missing option")
|
||||||
end
|
end
|
||||||
elseif cmd == UNIT_COMMAND.SET_WASTE then
|
elseif cmd == UNIT_COMMAND.SET_WASTE then
|
||||||
|
if (pkt.length == 3) and (type(pkt.data[3]) == "number") and
|
||||||
|
(pkt.data[3] >= WASTE_MODE.AUTO) and (pkt.data[3] <= WASTE_MODE.MANUAL_ANTI_MATTER) then
|
||||||
|
log.info(util.c(log_tag, "UNIT[", id, "] SET WASTE ", pkt.data[3]))
|
||||||
|
process.set_unit_waste(uid, pkt.data[3])
|
||||||
|
else
|
||||||
|
log.debug(log_tag .. "CRDN unit command set waste missing/invalid option")
|
||||||
|
end
|
||||||
elseif cmd == UNIT_COMMAND.ACK_ALL_ALARMS then
|
elseif cmd == UNIT_COMMAND.ACK_ALL_ALARMS then
|
||||||
log.info(util.c(log_tag, "UNIT[", uid, "] ACK ALL ALARMS"))
|
log.info(util.c(log_tag, "UNIT[", uid, "] ACK ALL ALARMS"))
|
||||||
self.proc_handle.ack_all_alarms(uid)
|
self.proc_handle.ack_all_alarms(uid)
|
||||||
elseif cmd == UNIT_COMMAND.ACK_ALARM then
|
elseif cmd == UNIT_COMMAND.ACK_ALARM then
|
||||||
elseif cmd == UNIT_COMMAND.RESET_ALARM then
|
elseif cmd == UNIT_COMMAND.RESET_ALARM then
|
||||||
elseif cmd == UNIT_COMMAND.SET_GROUP then
|
elseif cmd == UNIT_COMMAND.SET_GROUP then
|
||||||
if pkt.length == 3 then
|
if (pkt.length == 3) and (type(pkt.data[3]) == "number") and
|
||||||
|
(pkt.data[3] >= AUTO_GROUP.MANUAL) and (pkt.data[3] <= AUTO_GROUP.BACKUP) then
|
||||||
log.info(util.c(log_tag, "UNIT[", uid, "] SET GROUP ", pkt.data[3]))
|
log.info(util.c(log_tag, "UNIT[", uid, "] SET GROUP ", pkt.data[3]))
|
||||||
process.set_group(uid, pkt.data[3])
|
process.set_group(uid, pkt.data[3])
|
||||||
else
|
else
|
||||||
@ -275,7 +305,6 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout)
|
|||||||
u.annunciator.AutoControl,
|
u.annunciator.AutoControl,
|
||||||
u.a_group
|
u.a_group
|
||||||
}
|
}
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
_send(CRDN_TYPE.API_GET_CTRL, data)
|
_send(CRDN_TYPE.API_GET_CTRL, data)
|
||||||
@ -310,6 +339,47 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
_send(CRDN_TYPE.API_GET_PROC, data)
|
_send(CRDN_TYPE.API_GET_PROC, data)
|
||||||
|
elseif pkt.type == CRDN_TYPE.API_GET_WASTE then
|
||||||
|
local data = {}
|
||||||
|
|
||||||
|
local fac = db.facility
|
||||||
|
local proc = process.get_control_states().process
|
||||||
|
|
||||||
|
-- unit data
|
||||||
|
for i = 1, #db.units do
|
||||||
|
local u = db.units[i]
|
||||||
|
|
||||||
|
data[i] = {
|
||||||
|
u.waste_mode,
|
||||||
|
u.waste_product,
|
||||||
|
u.num_snas,
|
||||||
|
u.sna_peak_rate,
|
||||||
|
u.sna_max_rate,
|
||||||
|
u.sna_out_rate,
|
||||||
|
u.waste_stats
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local process_rate = 0
|
||||||
|
|
||||||
|
if fac.sps_data_tbl[1].state then
|
||||||
|
process_rate = fac.sps_data_tbl[1].state.process_rate
|
||||||
|
end
|
||||||
|
|
||||||
|
-- facility data
|
||||||
|
data[#db.units + 1] = {
|
||||||
|
fac.auto_current_waste_product,
|
||||||
|
fac.auto_pu_fallback_active,
|
||||||
|
fac.auto_sps_disabled,
|
||||||
|
proc.waste_product,
|
||||||
|
proc.pu_fallback,
|
||||||
|
proc.sps_low_power,
|
||||||
|
fac.waste_stats,
|
||||||
|
fac.sps_status,
|
||||||
|
process_rate
|
||||||
|
}
|
||||||
|
|
||||||
|
_send(CRDN_TYPE.API_GET_WASTE, data)
|
||||||
else
|
else
|
||||||
log.debug(log_tag .. "handler received unsupported CRDN packet type " .. pkt.type)
|
log.debug(log_tag .. "handler received unsupported CRDN packet type " .. pkt.type)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -19,7 +19,7 @@ local renderer = require("coordinator.renderer")
|
|||||||
local sounder = require("coordinator.sounder")
|
local sounder = require("coordinator.sounder")
|
||||||
local threads = require("coordinator.threads")
|
local threads = require("coordinator.threads")
|
||||||
|
|
||||||
local COORDINATOR_VERSION = "v1.5.15"
|
local COORDINATOR_VERSION = "v1.5.16"
|
||||||
|
|
||||||
local CHUNK_LOAD_DELAY_S = 30.0
|
local CHUNK_LOAD_DELAY_S = 30.0
|
||||||
|
|
||||||
|
|||||||
@ -94,7 +94,8 @@ function iocontrol.init_core(pkt_comms, nav, cfg)
|
|||||||
io.api = {
|
io.api = {
|
||||||
get_unit = function (unit) comms.api__get_unit(unit) end,
|
get_unit = function (unit) comms.api__get_unit(unit) end,
|
||||||
get_ctrl = function () comms.api__get_control() end,
|
get_ctrl = function () comms.api__get_control() end,
|
||||||
get_proc = function () comms.api__get_process() end
|
get_proc = function () comms.api__get_process() end,
|
||||||
|
get_waste = function () comms.api__get_waste() end
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -158,6 +159,8 @@ function iocontrol.init_fac(conf)
|
|||||||
---@type WASTE_PRODUCT
|
---@type WASTE_PRODUCT
|
||||||
auto_current_waste_product = types.WASTE_PRODUCT.PLUTONIUM,
|
auto_current_waste_product = types.WASTE_PRODUCT.PLUTONIUM,
|
||||||
auto_pu_fallback_active = false,
|
auto_pu_fallback_active = false,
|
||||||
|
auto_sps_disabled = false,
|
||||||
|
waste_stats = { 0, 0, 0, 0, 0, 0 }, -- waste in, pu, po, po pellets, am, spent waste
|
||||||
|
|
||||||
radiation = types.new_zero_radiation_reading(),
|
radiation = types.new_zero_radiation_reading(),
|
||||||
|
|
||||||
@ -217,6 +220,7 @@ function iocontrol.init_fac(conf)
|
|||||||
|
|
||||||
last_rate_change_ms = 0,
|
last_rate_change_ms = 0,
|
||||||
turbine_flow_stable = false,
|
turbine_flow_stable = false,
|
||||||
|
waste_stats = { 0, 0, 0 }, -- plutonium, polonium, po pellets
|
||||||
|
|
||||||
-- auto control group
|
-- auto control group
|
||||||
a_group = types.AUTO_GROUP.MANUAL,
|
a_group = types.AUTO_GROUP.MANUAL,
|
||||||
@ -920,6 +924,65 @@ function iocontrol.record_process_data(data)
|
|||||||
fac.ps.publish("process_gen_target", f_data[5][4])
|
fac.ps.publish("process_gen_target", f_data[5][4])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- update waste app with unit data from API_GET_WASTE
|
||||||
|
---@param data table
|
||||||
|
function iocontrol.record_waste_data(data)
|
||||||
|
-- get unit data
|
||||||
|
for u_id = 1, #io.units do
|
||||||
|
local unit = io.units[u_id]
|
||||||
|
local u_data = data[u_id]
|
||||||
|
|
||||||
|
unit.waste_mode = u_data[1]
|
||||||
|
unit.waste_product = u_data[2]
|
||||||
|
unit.num_snas = u_data[3]
|
||||||
|
unit.sna_peak_rate = u_data[4]
|
||||||
|
unit.sna_max_rate = u_data[5]
|
||||||
|
unit.sna_out_rate = u_data[6]
|
||||||
|
unit.waste_stats = u_data[7]
|
||||||
|
|
||||||
|
unit.unit_ps.publish("U_AutoWaste", unit.waste_mode == types.WASTE_MODE.AUTO)
|
||||||
|
unit.unit_ps.publish("U_WasteMode", unit.waste_mode)
|
||||||
|
unit.unit_ps.publish("U_WasteProduct", unit.waste_product)
|
||||||
|
|
||||||
|
unit.unit_ps.publish("sna_count", unit.num_snas)
|
||||||
|
unit.unit_ps.publish("sna_peak_rate", unit.sna_peak_rate)
|
||||||
|
unit.unit_ps.publish("sna_max_rate", unit.sna_max_rate)
|
||||||
|
unit.unit_ps.publish("sna_out_rate", unit.sna_out_rate)
|
||||||
|
|
||||||
|
unit.unit_ps.publish("pu_rate", unit.waste_stats[1])
|
||||||
|
unit.unit_ps.publish("po_rate", unit.waste_stats[2])
|
||||||
|
unit.unit_ps.publish("po_pl_rate", unit.waste_stats[3])
|
||||||
|
end
|
||||||
|
|
||||||
|
-- get facility data
|
||||||
|
local fac = io.facility
|
||||||
|
local f_data = data[#io.units + 1]
|
||||||
|
|
||||||
|
fac.auto_current_waste_product = f_data[1]
|
||||||
|
fac.auto_pu_fallback_active = f_data[2]
|
||||||
|
fac.auto_sps_disabled = f_data[3]
|
||||||
|
|
||||||
|
fac.ps.publish("current_waste_product", fac.auto_current_waste_product)
|
||||||
|
fac.ps.publish("pu_fallback_active", fac.auto_pu_fallback_active)
|
||||||
|
fac.ps.publish("sps_disabled_low_power", fac.auto_sps_disabled)
|
||||||
|
|
||||||
|
fac.ps.publish("process_waste_product", f_data[4])
|
||||||
|
fac.ps.publish("process_pu_fallback", f_data[5])
|
||||||
|
fac.ps.publish("process_sps_low_power", f_data[6])
|
||||||
|
|
||||||
|
fac.waste_stats = f_data[7]
|
||||||
|
|
||||||
|
fac.ps.publish("burn_sum", fac.waste_stats[1])
|
||||||
|
fac.ps.publish("pu_rate", fac.waste_stats[2])
|
||||||
|
fac.ps.publish("po_rate", fac.waste_stats[3])
|
||||||
|
fac.ps.publish("po_pl_rate", fac.waste_stats[4])
|
||||||
|
fac.ps.publish("po_am_rate", fac.waste_stats[5])
|
||||||
|
fac.ps.publish("spent_waste_rate", fac.waste_stats[6])
|
||||||
|
|
||||||
|
fac.ps.publish("sps_computed_status", f_data[8])
|
||||||
|
fac.ps.publish("sps_process_rate", f_data[9])
|
||||||
|
end
|
||||||
|
|
||||||
-- get the IO controller database
|
-- get the IO controller database
|
||||||
function iocontrol.get_db() return io end
|
function iocontrol.get_db() return io end
|
||||||
|
|
||||||
|
|||||||
@ -89,13 +89,14 @@ local APP_ID = {
|
|||||||
UNITS = 3,
|
UNITS = 3,
|
||||||
CONTROL = 4,
|
CONTROL = 4,
|
||||||
PROCESS = 5,
|
PROCESS = 5,
|
||||||
GUIDE = 6,
|
WASTE = 6,
|
||||||
ABOUT = 7,
|
GUIDE = 7,
|
||||||
|
ABOUT = 8,
|
||||||
-- diagnostic app pages
|
-- diagnostic app pages
|
||||||
ALARMS = 8,
|
ALARMS = 9,
|
||||||
-- other
|
-- other
|
||||||
DUMMY = 9,
|
DUMMY = 10,
|
||||||
NUM_APPS = 9
|
NUM_APPS = 10
|
||||||
}
|
}
|
||||||
|
|
||||||
pocket.APP_ID = APP_ID
|
pocket.APP_ID = APP_ID
|
||||||
@ -264,7 +265,8 @@ function pocket.init_nav(smem)
|
|||||||
|
|
||||||
-- open an app
|
-- open an app
|
||||||
---@param app_id POCKET_APP_ID
|
---@param app_id POCKET_APP_ID
|
||||||
function nav.open_app(app_id)
|
---@param on_loaded? function
|
||||||
|
function nav.open_app(app_id, on_loaded)
|
||||||
-- reset help return on navigating out of an app
|
-- reset help return on navigating out of an app
|
||||||
if app_id == APP_ID.ROOT then self.help_return = nil end
|
if app_id == APP_ID.ROOT then self.help_return = nil end
|
||||||
|
|
||||||
@ -277,7 +279,7 @@ function pocket.init_nav(smem)
|
|||||||
app = self.apps[app_id]
|
app = self.apps[app_id]
|
||||||
else self.loader_return = nil end
|
else self.loader_return = nil end
|
||||||
|
|
||||||
if not app.loaded then smem.q.mq_render.push_data(MQ__RENDER_DATA.LOAD_APP, app_id) end
|
if not app.loaded then smem.q.mq_render.push_data(MQ__RENDER_DATA.LOAD_APP, { app_id, on_loaded }) end
|
||||||
|
|
||||||
self.cur_app = app_id
|
self.cur_app = app_id
|
||||||
self.pane.set_value(app_id)
|
self.pane.set_value(app_id)
|
||||||
@ -360,10 +362,10 @@ function pocket.init_nav(smem)
|
|||||||
function nav.open_help(key)
|
function nav.open_help(key)
|
||||||
self.help_return = self.cur_app
|
self.help_return = self.cur_app
|
||||||
|
|
||||||
nav.open_app(APP_ID.GUIDE)
|
nav.open_app(APP_ID.GUIDE, function ()
|
||||||
|
local show = self.help_map[key]
|
||||||
local load = self.help_map[key]
|
if show then show() end
|
||||||
if load then load() end
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- link the help map from the guide app
|
-- link the help map from the guide app
|
||||||
@ -565,6 +567,11 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
|||||||
if self.api.linked then _send_api(CRDN_TYPE.API_GET_PROC, {}) end
|
if self.api.linked then _send_api(CRDN_TYPE.API_GET_PROC, {}) end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- coordinator get waste app data
|
||||||
|
function public.api__get_waste()
|
||||||
|
if self.api.linked then _send_api(CRDN_TYPE.API_GET_WASTE, {}) end
|
||||||
|
end
|
||||||
|
|
||||||
-- send a facility command
|
-- send a facility command
|
||||||
---@param cmd FAC_COMMAND command
|
---@param cmd FAC_COMMAND command
|
||||||
---@param option any? optional option options for the optional options (like waste mode)
|
---@param option any? optional option options for the optional options (like waste mode)
|
||||||
@ -733,6 +740,10 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
|||||||
if _check_length(packet, #iocontrol.get_db().units + 1) then
|
if _check_length(packet, #iocontrol.get_db().units + 1) then
|
||||||
iocontrol.record_process_data(packet.data)
|
iocontrol.record_process_data(packet.data)
|
||||||
end
|
end
|
||||||
|
elseif packet.type == CRDN_TYPE.API_GET_WASTE then
|
||||||
|
if _check_length(packet, #iocontrol.get_db().units + 1) then
|
||||||
|
iocontrol.record_waste_data(packet.data)
|
||||||
|
end
|
||||||
else _fail_type(packet) end
|
else _fail_type(packet) end
|
||||||
else
|
else
|
||||||
log.debug("discarding coordinator SCADA_CRDN packet before linked")
|
log.debug("discarding coordinator SCADA_CRDN packet before linked")
|
||||||
|
|||||||
@ -85,6 +85,14 @@ function process.set_group(unit_id, group_id)
|
|||||||
log.debug(util.c("PROCESS: UNIT[", unit_id, "] SET GROUP ", group_id))
|
log.debug(util.c("PROCESS: UNIT[", unit_id, "] SET GROUP ", group_id))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- set waste mode
|
||||||
|
---@param id integer unit ID
|
||||||
|
---@param mode integer waste mode
|
||||||
|
function process.set_unit_waste(id, mode)
|
||||||
|
self.comms.send_unit_command(U_CMD.SET_WASTE, id, mode)
|
||||||
|
log.debug(util.c("PROCESS: UNIT[", id, "] SET WASTE ", mode))
|
||||||
|
end
|
||||||
|
|
||||||
-- acknowledge all alarms
|
-- acknowledge all alarms
|
||||||
---@param id integer unit ID
|
---@param id integer unit ID
|
||||||
function process.ack_all_alarms(id)
|
function process.ack_all_alarms(id)
|
||||||
@ -131,6 +139,27 @@ function process.process_stop()
|
|||||||
log.debug("PROCESS: STOP AUTO CTRL")
|
log.debug("PROCESS: STOP AUTO CTRL")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- set automatic process control waste mode
|
||||||
|
---@param product WASTE_PRODUCT waste product for auto control
|
||||||
|
function process.set_process_waste(product)
|
||||||
|
self.comms.send_fac_command(F_CMD.SET_WASTE_MODE, product)
|
||||||
|
log.debug(util.c("PROCESS: SET WASTE ", product))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- set automatic process control plutonium fallback
|
||||||
|
---@param enabled boolean whether to enable plutonium fallback
|
||||||
|
function process.set_pu_fallback(enabled)
|
||||||
|
self.comms.send_fac_command(F_CMD.SET_PU_FB, enabled)
|
||||||
|
log.debug(util.c("PROCESS: SET PU FALLBACK ", enabled))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- set automatic process control SPS usage at low power
|
||||||
|
---@param enabled boolean whether to enable SPS usage at low power
|
||||||
|
function process.set_sps_low_power(enabled)
|
||||||
|
self.comms.send_fac_command(F_CMD.SET_SPS_LP, enabled)
|
||||||
|
log.debug(util.c("PROCESS: SET SPS LOW POWER ", enabled))
|
||||||
|
end
|
||||||
|
|
||||||
-- #endregion
|
-- #endregion
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
||||||
|
|||||||
@ -20,7 +20,7 @@ local pocket = require("pocket.pocket")
|
|||||||
local renderer = require("pocket.renderer")
|
local renderer = require("pocket.renderer")
|
||||||
local threads = require("pocket.threads")
|
local threads = require("pocket.threads")
|
||||||
|
|
||||||
local POCKET_VERSION = "v0.12.9-alpha"
|
local POCKET_VERSION = "v0.12.10-alpha"
|
||||||
|
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local println_ts = util.println_ts
|
local println_ts = util.println_ts
|
||||||
|
|||||||
@ -165,15 +165,18 @@ function threads.thread__render(smem)
|
|||||||
local cmd = msg.message ---@type queue_data
|
local cmd = msg.message ---@type queue_data
|
||||||
|
|
||||||
if cmd.key == MQ__RENDER_DATA.LOAD_APP then
|
if cmd.key == MQ__RENDER_DATA.LOAD_APP then
|
||||||
log.debug("RENDER: load app " .. cmd.val)
|
log.debug("RENDER: load app " .. cmd.val[1])
|
||||||
|
|
||||||
local draw_start = util.time_ms()
|
local draw_start = util.time_ms()
|
||||||
|
|
||||||
pkt_state.ui_ok, pkt_state.ui_error = pcall(function () nav.load_app(cmd.val) end)
|
pkt_state.ui_ok, pkt_state.ui_error = pcall(function () nav.load_app(cmd.val[1]) end)
|
||||||
if not pkt_state.ui_ok then
|
if not pkt_state.ui_ok then
|
||||||
log.fatal(util.c("RENDER: app load failed with error ", pkt_state.ui_error))
|
log.fatal(util.c("RENDER: app load failed with error ", pkt_state.ui_error))
|
||||||
else
|
else
|
||||||
log.debug("RENDER: app loaded in " .. (util.time_ms() - draw_start) .. "ms")
|
log.debug("RENDER: app loaded in " .. (util.time_ms() - draw_start) .. "ms")
|
||||||
|
|
||||||
|
-- call the on loaded function if provided
|
||||||
|
if type(cmd.val[2]) == "function" then cmd.val[2]() end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif msg.qtype == mqueue.TYPE.PACKET then
|
elseif msg.qtype == mqueue.TYPE.PACKET then
|
||||||
|
|||||||
310
pocket/ui/apps/waste.lua
Normal file
310
pocket/ui/apps/waste.lua
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
--
|
||||||
|
-- Waste Control Page
|
||||||
|
--
|
||||||
|
|
||||||
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
|
local iocontrol = require("pocket.iocontrol")
|
||||||
|
local pocket = require("pocket.pocket")
|
||||||
|
local process = require("pocket.process")
|
||||||
|
|
||||||
|
local style = require("pocket.ui.style")
|
||||||
|
|
||||||
|
local core = require("graphics.core")
|
||||||
|
|
||||||
|
local Div = require("graphics.elements.Div")
|
||||||
|
local MultiPane = require("graphics.elements.MultiPane")
|
||||||
|
local TextBox = require("graphics.elements.TextBox")
|
||||||
|
|
||||||
|
local WaitingAnim = require("graphics.elements.animations.Waiting")
|
||||||
|
|
||||||
|
local Checkbox = require("graphics.elements.controls.Checkbox")
|
||||||
|
local PushButton = require("graphics.elements.controls.PushButton")
|
||||||
|
local RadioButton = require("graphics.elements.controls.RadioButton")
|
||||||
|
|
||||||
|
local DataIndicator = require("graphics.elements.indicators.DataIndicator")
|
||||||
|
local IconIndicator = require("graphics.elements.indicators.IconIndicator")
|
||||||
|
local StateIndicator = require("graphics.elements.indicators.StateIndicator")
|
||||||
|
|
||||||
|
local ALIGN = core.ALIGN
|
||||||
|
local cpair = core.cpair
|
||||||
|
|
||||||
|
local APP_ID = pocket.APP_ID
|
||||||
|
|
||||||
|
local label_fg_bg = style.label
|
||||||
|
local text_fg = style.text_fg
|
||||||
|
|
||||||
|
local lu_col = style.label_unit_pair
|
||||||
|
|
||||||
|
local yel_ind_s = style.icon_states.yel_ind_s
|
||||||
|
local wht_ind_s = style.icon_states.wht_ind_s
|
||||||
|
|
||||||
|
-- new waste control page view
|
||||||
|
---@param root Container parent
|
||||||
|
local function new_view(root)
|
||||||
|
local db = iocontrol.get_db()
|
||||||
|
|
||||||
|
local frame = Div{parent=root,x=1,y=1}
|
||||||
|
|
||||||
|
local app = db.nav.register_app(APP_ID.WASTE, frame, nil, false, true)
|
||||||
|
|
||||||
|
local load_div = Div{parent=frame,x=1,y=1}
|
||||||
|
local main = Div{parent=frame,x=1,y=1}
|
||||||
|
|
||||||
|
TextBox{parent=load_div,y=12,text="Loading...",alignment=ALIGN.CENTER}
|
||||||
|
WaitingAnim{parent=load_div,x=math.floor(main.get_width()/2)-1,y=8,fg_bg=cpair(colors.brown,colors._INHERIT)}
|
||||||
|
|
||||||
|
local load_pane = MultiPane{parent=main,x=1,y=1,panes={load_div,main}}
|
||||||
|
|
||||||
|
app.set_sidebar({ { label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = db.nav.go_home } })
|
||||||
|
|
||||||
|
local page_div = nil ---@type Div|nil
|
||||||
|
|
||||||
|
-- load the app (create the elements)
|
||||||
|
local function load()
|
||||||
|
local f_ps = db.facility.ps
|
||||||
|
|
||||||
|
page_div = Div{parent=main,y=2,width=main.get_width()}
|
||||||
|
|
||||||
|
local panes = {} ---@type Div[]
|
||||||
|
local u_pages = {} ---@type nav_tree_page[]
|
||||||
|
|
||||||
|
local last_update = 0
|
||||||
|
-- refresh data callback, every 500ms it will re-send the query
|
||||||
|
local function update()
|
||||||
|
if util.time_ms() - last_update >= 500 then
|
||||||
|
db.api.get_waste()
|
||||||
|
last_update = util.time_ms()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--#region unit waste options/statistics
|
||||||
|
|
||||||
|
for i = 1, db.facility.num_units do
|
||||||
|
local u_pane = Div{parent=page_div}
|
||||||
|
local u_div = Div{parent=u_pane,x=2,width=main.get_width()-2}
|
||||||
|
local unit = db.units[i]
|
||||||
|
local u_ps = unit.unit_ps
|
||||||
|
|
||||||
|
table.insert(panes, u_div)
|
||||||
|
|
||||||
|
local u_page = app.new_page(nil, #panes)
|
||||||
|
u_page.tasks = { update }
|
||||||
|
|
||||||
|
table.insert(u_pages, u_page)
|
||||||
|
|
||||||
|
TextBox{parent=u_div,y=1,text="Reactor Unit #"..i,alignment=ALIGN.CENTER}
|
||||||
|
|
||||||
|
local function set_waste(mode) process.set_unit_waste(i, mode) end
|
||||||
|
|
||||||
|
local waste_prod = StateIndicator{parent=u_div,x=16,y=3,states=style.waste.states_abbrv,value=1,min_width=6}
|
||||||
|
local waste_mode = RadioButton{parent=u_div,y=3,options=style.waste.unit_opts,callback=set_waste,radio_colors=cpair(colors.lightGray,colors.gray),select_color=colors.white}
|
||||||
|
|
||||||
|
waste_prod.register(u_ps, "U_WasteProduct", waste_prod.update)
|
||||||
|
waste_mode.register(u_ps, "U_WasteMode", waste_mode.set_value)
|
||||||
|
|
||||||
|
TextBox{parent=u_div,y=8,text="Plutonium (Pellets)",fg_bg=label_fg_bg}
|
||||||
|
local pu = DataIndicator{parent=u_div,label="",format="%16.3f",value=0,unit="mB/t",lu_colors=lu_col,width=21,fg_bg=text_fg}
|
||||||
|
TextBox{parent=u_div,y=11,text="Polonium",fg_bg=label_fg_bg}
|
||||||
|
local po = DataIndicator{parent=u_div,label="",format="%16.3f",value=0,unit="mB/t",lu_colors=lu_col,width=21,fg_bg=text_fg}
|
||||||
|
TextBox{parent=u_div,y=14,text="Polonium (Pellets)",fg_bg=label_fg_bg}
|
||||||
|
local popl = DataIndicator{parent=u_div,label="",format="%16.3f",value=0,unit="mB/t",lu_colors=lu_col,width=21,fg_bg=text_fg}
|
||||||
|
|
||||||
|
pu.register(u_ps, "pu_rate", pu.update)
|
||||||
|
po.register(u_ps, "po_rate", po.update)
|
||||||
|
popl.register(u_ps, "po_pl_rate", popl.update)
|
||||||
|
|
||||||
|
local sna_div = Div{parent=u_pane,x=2,width=page_div.get_width()-2}
|
||||||
|
table.insert(panes, sna_div)
|
||||||
|
|
||||||
|
local sps_page = app.new_page(u_page, #panes)
|
||||||
|
sps_page.tasks = { update }
|
||||||
|
|
||||||
|
PushButton{parent=u_div,x=6,y=18,text="SNA DATA",min_width=12,fg_bg=cpair(colors.lightGray,colors.gray),active_fg_bg=cpair(colors.gray,colors.lightGray),callback=sps_page.nav_to}
|
||||||
|
PushButton{parent=sna_div,x=9,y=18,text="BACK",min_width=6,fg_bg=cpair(colors.lightGray,colors.gray),active_fg_bg=cpair(colors.gray,colors.lightGray),callback=u_page.nav_to}
|
||||||
|
|
||||||
|
TextBox{parent=sna_div,y=1,text="Unit "..i.." SNAs",alignment=ALIGN.CENTER}
|
||||||
|
TextBox{parent=sna_div,y=3,text="Connected",fg_bg=label_fg_bg}
|
||||||
|
local count = DataIndicator{parent=sna_div,x=20,y=3,label="",format="%2d",value=0,unit="",lu_colors=lu_col,width=2,fg_bg=text_fg}
|
||||||
|
|
||||||
|
TextBox{parent=sna_div,y=5,text="Peak Possible Rate\n In\n Out",fg_bg=label_fg_bg}
|
||||||
|
local peak_i = DataIndicator{parent=sna_div,x=6,y=6,label="",format="%11.2f",value=0,unit="mB/t",lu_colors=lu_col,width=17,fg_bg=text_fg}
|
||||||
|
local peak_o = DataIndicator{parent=sna_div,x=6,label="",format="%11.2f",value=0,unit="mB/t",lu_colors=lu_col,width=17,fg_bg=text_fg}
|
||||||
|
|
||||||
|
TextBox{parent=sna_div,y=9,text="Current Maximum Rate\n In\n Out",fg_bg=label_fg_bg}
|
||||||
|
local max_i = DataIndicator{parent=sna_div,x=6,y=10,label="",format="%11.2f",value=0,unit="mB/t",lu_colors=lu_col,width=17,fg_bg=text_fg}
|
||||||
|
local max_o = DataIndicator{parent=sna_div,x=6,label="",format="%11.2f",value=0,unit="mB/t",lu_colors=lu_col,width=17,fg_bg=text_fg}
|
||||||
|
|
||||||
|
TextBox{parent=sna_div,y=13,text="Current Rate\n In\n Out",fg_bg=label_fg_bg}
|
||||||
|
local cur_i = DataIndicator{parent=sna_div,x=6,y=14,label="",format="%11.2f",value=0,unit="mB/t",lu_colors=lu_col,width=17,fg_bg=text_fg}
|
||||||
|
local cur_o = DataIndicator{parent=sna_div,x=6,label="",format="%11.2f",value=0,unit="mB/t",lu_colors=lu_col,width=17,fg_bg=text_fg}
|
||||||
|
|
||||||
|
count.register(u_ps, "sna_count", count.update)
|
||||||
|
peak_i.register(u_ps, "sna_peak_rate", function (x) peak_i.update(x * 10) end)
|
||||||
|
peak_o.register(u_ps, "sna_peak_rate", peak_o.update)
|
||||||
|
max_i.register(u_ps, "sna_max_rate", function (x) max_i.update(x * 10) end)
|
||||||
|
max_o.register(u_ps, "sna_max_rate", max_o.update)
|
||||||
|
cur_i.register(u_ps, "sna_out_rate", function (x) cur_i.update(x * 10) end)
|
||||||
|
cur_o.register(u_ps, "sna_out_rate", cur_o.update)
|
||||||
|
end
|
||||||
|
|
||||||
|
--#endregion
|
||||||
|
|
||||||
|
--#region waste control page
|
||||||
|
|
||||||
|
local c_pane = Div{parent=page_div}
|
||||||
|
local c_div = Div{parent=c_pane,x=2,width=main.get_width()-2}
|
||||||
|
table.insert(panes, c_div)
|
||||||
|
|
||||||
|
local wst_ctrl = app.new_page(nil, #panes)
|
||||||
|
wst_ctrl.tasks = { update }
|
||||||
|
|
||||||
|
TextBox{parent=c_div,y=1,text="Waste Control",alignment=ALIGN.CENTER}
|
||||||
|
|
||||||
|
local status = StateIndicator{parent=c_div,x=3,y=3,states=style.waste.states,value=1,min_width=17}
|
||||||
|
local waste_prod = RadioButton{parent=c_div,y=5,options=style.waste.options,callback=process.set_process_waste,radio_colors=cpair(colors.lightGray,colors.gray),select_color=colors.white}
|
||||||
|
|
||||||
|
status.register(f_ps, "current_waste_product", status.update)
|
||||||
|
waste_prod.register(f_ps, "process_waste_product", waste_prod.set_value)
|
||||||
|
|
||||||
|
local fb_active = IconIndicator{parent=c_div,y=9,label="Fallback Active",states=wht_ind_s}
|
||||||
|
local sps_disabled = IconIndicator{parent=c_div,y=10,label="SPS Disabled LC",states=yel_ind_s}
|
||||||
|
|
||||||
|
fb_active.register(f_ps, "pu_fallback_active", fb_active.update)
|
||||||
|
sps_disabled.register(f_ps, "sps_disabled_low_power", sps_disabled.update)
|
||||||
|
|
||||||
|
TextBox{parent=c_div,y=12,text="Nuclear Waste In",fg_bg=label_fg_bg}
|
||||||
|
local sum_raw_waste = DataIndicator{parent=c_div,label="",format="%16.3f",value=0,unit="mB/t",lu_colors=lu_col,width=21,fg_bg=text_fg}
|
||||||
|
|
||||||
|
sum_raw_waste.register(f_ps, "burn_sum", sum_raw_waste.update)
|
||||||
|
|
||||||
|
TextBox{parent=c_div,y=15,text="Spent Waste Out",fg_bg=label_fg_bg}
|
||||||
|
local sum_sp_waste = DataIndicator{parent=c_div,label="",format="%16.3f",value=0,unit="mB/t",lu_colors=lu_col,width=21,fg_bg=text_fg}
|
||||||
|
|
||||||
|
sum_sp_waste.register(f_ps, "spent_waste_rate", sum_sp_waste.update)
|
||||||
|
|
||||||
|
local stats_div = Div{parent=c_pane,x=2,width=page_div.get_width()-2}
|
||||||
|
table.insert(panes, stats_div)
|
||||||
|
|
||||||
|
local stats_page = app.new_page(wst_ctrl, #panes)
|
||||||
|
stats_page.tasks = { update }
|
||||||
|
|
||||||
|
PushButton{parent=c_div,x=6,y=18,text="PROD RATES",min_width=12,fg_bg=cpair(colors.lightGray,colors.gray),active_fg_bg=cpair(colors.gray,colors.lightGray),callback=stats_page.nav_to}
|
||||||
|
PushButton{parent=stats_div,x=9,y=18,text="BACK",min_width=6,fg_bg=cpair(colors.lightGray,colors.gray),active_fg_bg=cpair(colors.gray,colors.lightGray),callback=wst_ctrl.nav_to}
|
||||||
|
|
||||||
|
TextBox{parent=stats_div,y=1,text="Production Rates",alignment=ALIGN.CENTER}
|
||||||
|
|
||||||
|
TextBox{parent=stats_div,y=3,text="Plutonium (Pellets)",fg_bg=label_fg_bg}
|
||||||
|
local pu = DataIndicator{parent=stats_div,label="",format="%16.3f",value=0,unit="mB/t",lu_colors=lu_col,width=21,fg_bg=text_fg}
|
||||||
|
TextBox{parent=stats_div,y=6,text="Polonium",fg_bg=label_fg_bg}
|
||||||
|
local po = DataIndicator{parent=stats_div,label="",format="%16.3f",value=0,unit="mB/t",lu_colors=lu_col,width=21,fg_bg=text_fg}
|
||||||
|
TextBox{parent=stats_div,y=9,text="Polonium (Pellets)",fg_bg=label_fg_bg}
|
||||||
|
local popl = DataIndicator{parent=stats_div,label="",format="%16.3f",value=0,unit="mB/t",lu_colors=lu_col,width=21,fg_bg=text_fg}
|
||||||
|
|
||||||
|
pu.register(f_ps, "pu_rate", pu.update)
|
||||||
|
po.register(f_ps, "po_rate", po.update)
|
||||||
|
popl.register(f_ps, "po_pl_rate", popl.update)
|
||||||
|
|
||||||
|
TextBox{parent=stats_div,y=12,text="Antimatter",fg_bg=label_fg_bg}
|
||||||
|
local am = DataIndicator{parent=stats_div,label="",format="%16d",value=0,unit="\xb5B/t",lu_colors=lu_col,width=21,fg_bg=text_fg}
|
||||||
|
|
||||||
|
am.register(f_ps, "sps_process_rate", function (r) am.update(r * 1000) end)
|
||||||
|
|
||||||
|
--#endregion
|
||||||
|
|
||||||
|
--#region waste options page
|
||||||
|
|
||||||
|
local o_pane = Div{parent=page_div}
|
||||||
|
local o_div = Div{parent=o_pane,x=2,width=main.get_width()-2}
|
||||||
|
table.insert(panes, o_pane)
|
||||||
|
|
||||||
|
local opt_page = app.new_page(nil, #panes)
|
||||||
|
opt_page.tasks = { update }
|
||||||
|
|
||||||
|
TextBox{parent=o_div,y=1,text="Waste Options",alignment=ALIGN.CENTER}
|
||||||
|
|
||||||
|
local pu_fallback = Checkbox{parent=o_div,x=2,y=3,label="Pu Fallback",callback=process.set_pu_fallback,box_fg_bg=cpair(colors.white,colors.gray)}
|
||||||
|
|
||||||
|
TextBox{parent=o_div,x=2,y=5,height=3,text="Switch to Pu when SNAs cannot keep up with waste.",fg_bg=label_fg_bg}
|
||||||
|
|
||||||
|
local lc_sps = Checkbox{parent=o_div,x=2,y=9,label="Low Charge SPS",callback=process.set_sps_low_power,box_fg_bg=cpair(colors.white,colors.gray)}
|
||||||
|
|
||||||
|
TextBox{parent=o_div,x=2,y=11,height=3,text="Use SPS at low charge, otherwise switches to Po.",fg_bg=label_fg_bg}
|
||||||
|
|
||||||
|
pu_fallback.register(f_ps, "process_pu_fallback", pu_fallback.set_value)
|
||||||
|
lc_sps.register(f_ps, "process_sps_low_power", lc_sps.set_value)
|
||||||
|
|
||||||
|
--#endregion
|
||||||
|
|
||||||
|
--#region SPS page
|
||||||
|
|
||||||
|
local s_pane = Div{parent=page_div}
|
||||||
|
local s_div = Div{parent=s_pane,x=2,width=main.get_width()-2}
|
||||||
|
table.insert(panes, s_pane)
|
||||||
|
|
||||||
|
local sps_page = app.new_page(nil, #panes)
|
||||||
|
sps_page.tasks = { update }
|
||||||
|
|
||||||
|
TextBox{parent=s_div,y=1,text="Facility SPS",alignment=ALIGN.CENTER}
|
||||||
|
|
||||||
|
local sps_status = StateIndicator{parent=s_div,x=5,y=3,states=style.sps.states,value=1,min_width=12}
|
||||||
|
|
||||||
|
sps_status.register(f_ps, "sps_computed_status", sps_status.update)
|
||||||
|
|
||||||
|
TextBox{parent=s_div,y=5,text="Input Rate",width=10,fg_bg=label_fg_bg}
|
||||||
|
local sps_in = DataIndicator{parent=s_div,label="",format="%16.2f",value=0,unit="mB/t",lu_colors=lu_col,width=21,fg_bg=text_fg}
|
||||||
|
|
||||||
|
sps_in.register(f_ps, "po_am_rate", sps_in.update)
|
||||||
|
|
||||||
|
TextBox{parent=s_div,y=8,text="Production Rate",width=15,fg_bg=label_fg_bg}
|
||||||
|
local sps_rate = DataIndicator{parent=s_div,label="",format="%16d",value=0,unit="\xb5B/t",lu_colors=lu_col,width=21,fg_bg=text_fg}
|
||||||
|
|
||||||
|
sps_rate.register(f_ps, "sps_process_rate", function (r) sps_rate.update(r * 1000) end)
|
||||||
|
|
||||||
|
--#endregion
|
||||||
|
|
||||||
|
-- setup multipane
|
||||||
|
local u_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes}
|
||||||
|
app.set_root_pane(u_pane)
|
||||||
|
|
||||||
|
-- setup sidebar
|
||||||
|
|
||||||
|
local list = {
|
||||||
|
{ label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = db.nav.go_home },
|
||||||
|
{ label = "WST", color = core.cpair(colors.black, colors.brown), callback = wst_ctrl.nav_to },
|
||||||
|
{ label = "OPT", color = core.cpair(colors.black, colors.white), callback = opt_page.nav_to },
|
||||||
|
{ label = "SPS", color = core.cpair(colors.black, colors.purple), callback = sps_page.nav_to }
|
||||||
|
}
|
||||||
|
|
||||||
|
for i = 1, db.facility.num_units do
|
||||||
|
table.insert(list, { label = "U-" .. i, color = core.cpair(colors.black, colors.lightGray), callback = u_pages[i].nav_to })
|
||||||
|
end
|
||||||
|
|
||||||
|
app.set_sidebar(list)
|
||||||
|
|
||||||
|
-- done, show the app
|
||||||
|
wst_ctrl.nav_to()
|
||||||
|
load_pane.set_value(2)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- delete the elements and switch back to the loading screen
|
||||||
|
local function unload()
|
||||||
|
if page_div then
|
||||||
|
page_div.delete()
|
||||||
|
page_div = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
app.set_sidebar({ { label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = db.nav.go_home } })
|
||||||
|
app.delete_pages()
|
||||||
|
|
||||||
|
-- show loading screen
|
||||||
|
load_pane.set_value(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
app.set_load(load)
|
||||||
|
app.set_unload(unload)
|
||||||
|
|
||||||
|
return main
|
||||||
|
end
|
||||||
|
|
||||||
|
return new_view
|
||||||
@ -15,6 +15,7 @@ local loader_app = require("pocket.ui.apps.loader")
|
|||||||
local process_app = require("pocket.ui.apps.process")
|
local process_app = require("pocket.ui.apps.process")
|
||||||
local sys_apps = require("pocket.ui.apps.sys_apps")
|
local sys_apps = require("pocket.ui.apps.sys_apps")
|
||||||
local unit_app = require("pocket.ui.apps.unit")
|
local unit_app = require("pocket.ui.apps.unit")
|
||||||
|
local waste_app = require("pocket.ui.apps.waste")
|
||||||
|
|
||||||
local home_page = require("pocket.ui.pages.home_page")
|
local home_page = require("pocket.ui.pages.home_page")
|
||||||
|
|
||||||
@ -66,6 +67,7 @@ local function init(main)
|
|||||||
unit_app(page_div)
|
unit_app(page_div)
|
||||||
control_app(page_div)
|
control_app(page_div)
|
||||||
process_app(page_div)
|
process_app(page_div)
|
||||||
|
waste_app(page_div)
|
||||||
guide_app(page_div)
|
guide_app(page_div)
|
||||||
loader_app(page_div)
|
loader_app(page_div)
|
||||||
sys_apps(page_div)
|
sys_apps(page_div)
|
||||||
|
|||||||
@ -49,7 +49,7 @@ local function new_view(root)
|
|||||||
App{parent=apps_1,x=9,y=2,text="F",title="Facil",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.orange),active_fg_bg=active_fg_bg}
|
App{parent=apps_1,x=9,y=2,text="F",title="Facil",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.orange),active_fg_bg=active_fg_bg}
|
||||||
App{parent=apps_1,x=16,y=2,text="\x15",title="Control",callback=function()open(APP_ID.CONTROL)end,app_fg_bg=cpair(colors.black,colors.green),active_fg_bg=active_fg_bg}
|
App{parent=apps_1,x=16,y=2,text="\x15",title="Control",callback=function()open(APP_ID.CONTROL)end,app_fg_bg=cpair(colors.black,colors.green),active_fg_bg=active_fg_bg}
|
||||||
App{parent=apps_1,x=2,y=7,text="\x17",title="Process",callback=function()open(APP_ID.PROCESS)end,app_fg_bg=cpair(colors.black,colors.purple),active_fg_bg=active_fg_bg}
|
App{parent=apps_1,x=2,y=7,text="\x17",title="Process",callback=function()open(APP_ID.PROCESS)end,app_fg_bg=cpair(colors.black,colors.purple),active_fg_bg=active_fg_bg}
|
||||||
App{parent=apps_1,x=9,y=7,text="\x7f",title="Waste",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.brown),active_fg_bg=active_fg_bg}
|
App{parent=apps_1,x=9,y=7,text="\x7f",title="Waste",callback=function()open(APP_ID.WASTE)end,app_fg_bg=cpair(colors.black,colors.brown),active_fg_bg=active_fg_bg}
|
||||||
App{parent=apps_1,x=16,y=7,text="\x08",title="Devices",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.lightGray),active_fg_bg=active_fg_bg}
|
App{parent=apps_1,x=16,y=7,text="\x08",title="Devices",callback=function()open(APP_ID.DUMMY)end,app_fg_bg=cpair(colors.black,colors.lightGray),active_fg_bg=active_fg_bg}
|
||||||
App{parent=apps_1,x=2,y=12,text="\xb6",title="Guide",callback=function()open(APP_ID.GUIDE)end,app_fg_bg=cpair(colors.black,colors.cyan),active_fg_bg=active_fg_bg}
|
App{parent=apps_1,x=2,y=12,text="\xb6",title="Guide",callback=function()open(APP_ID.GUIDE)end,app_fg_bg=cpair(colors.black,colors.cyan),active_fg_bg=active_fg_bg}
|
||||||
App{parent=apps_1,x=9,y=12,text="?",title="About",callback=function()open(APP_ID.ABOUT)end,app_fg_bg=cpair(colors.black,colors.white),active_fg_bg=active_fg_bg}
|
App{parent=apps_1,x=9,y=12,text="?",title="About",callback=function()open(APP_ID.ABOUT)end,app_fg_bg=cpair(colors.black,colors.white),active_fg_bg=active_fg_bg}
|
||||||
|
|||||||
@ -214,4 +214,66 @@ style.imatrix = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
style.sps = {
|
||||||
|
-- SPS states
|
||||||
|
states = {
|
||||||
|
{
|
||||||
|
color = cpair(colors.black, colors.yellow),
|
||||||
|
text = "OFF-LINE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color = cpair(colors.black, colors.orange),
|
||||||
|
text = "NOT FORMED"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color = cpair(colors.black, colors.orange),
|
||||||
|
text = "RTU FAULT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color = cpair(colors.white, colors.gray),
|
||||||
|
text = "IDLE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color = cpair(colors.black, colors.green),
|
||||||
|
text = "ACTIVE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
style.waste = {
|
||||||
|
-- auto waste processing states
|
||||||
|
states = {
|
||||||
|
{
|
||||||
|
color = cpair(colors.black, colors.green),
|
||||||
|
text = "PLUTONIUM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color = cpair(colors.black, colors.cyan),
|
||||||
|
text = "POLONIUM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color = cpair(colors.black, colors.purple),
|
||||||
|
text = "ANTI MATTER"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
states_abbrv = {
|
||||||
|
{
|
||||||
|
color = cpair(colors.black, colors.green),
|
||||||
|
text = "Pu"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color = cpair(colors.black, colors.cyan),
|
||||||
|
text = "Po"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color = cpair(colors.black, colors.purple),
|
||||||
|
text = "AM"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
-- process radio button options
|
||||||
|
options = { "Plutonium", "Polonium", "Antimatter" },
|
||||||
|
-- unit waste selection
|
||||||
|
unit_opts = { "Auto", "Plutonium", "Polonium", "Antimatter" }
|
||||||
|
}
|
||||||
|
|
||||||
return style
|
return style
|
||||||
|
|||||||
@ -17,8 +17,8 @@ local max_distance = nil
|
|||||||
local comms = {}
|
local comms = {}
|
||||||
|
|
||||||
-- protocol/data versions (protocol/data independent changes tracked by util.lua version)
|
-- protocol/data versions (protocol/data independent changes tracked by util.lua version)
|
||||||
comms.version = "3.0.1"
|
comms.version = "3.0.2"
|
||||||
comms.api_version = "0.0.6"
|
comms.api_version = "0.0.7"
|
||||||
|
|
||||||
---@enum PROTOCOL
|
---@enum PROTOCOL
|
||||||
local PROTOCOL = {
|
local PROTOCOL = {
|
||||||
@ -68,8 +68,9 @@ local CRDN_TYPE = {
|
|||||||
UNIT_CMD = 6, -- command a reactor unit
|
UNIT_CMD = 6, -- command a reactor unit
|
||||||
API_GET_FAC = 7, -- API: get all the facility data
|
API_GET_FAC = 7, -- API: get all the facility data
|
||||||
API_GET_UNIT = 8, -- API: get reactor unit data
|
API_GET_UNIT = 8, -- API: get reactor unit data
|
||||||
API_GET_CTRL = 9, -- API: get data used for the control app
|
API_GET_CTRL = 9, -- API: get data for the control app
|
||||||
API_GET_PROC = 10 -- API: get data used for the process app
|
API_GET_PROC = 10, -- API: get data for the process app
|
||||||
|
API_GET_WASTE = 11 -- API: get data for the waste app
|
||||||
}
|
}
|
||||||
|
|
||||||
---@enum ESTABLISH_ACK
|
---@enum ESTABLISH_ACK
|
||||||
|
|||||||
@ -278,13 +278,13 @@ function coordinator.new_session(id, s_addr, i_seq_num, in_queue, out_queue, tim
|
|||||||
end
|
end
|
||||||
elseif cmd == FAC_COMMAND.SET_PU_FB then
|
elseif cmd == FAC_COMMAND.SET_PU_FB then
|
||||||
if pkt.length == 2 then
|
if pkt.length == 2 then
|
||||||
_send(CRDN_TYPE.FAC_CMD, { cmd, facility.set_pu_fallback(pkt.data[2]) })
|
_send(CRDN_TYPE.FAC_CMD, { cmd, facility.set_pu_fallback(pkt.data[2] == true) })
|
||||||
else
|
else
|
||||||
log.debug(log_tag .. "CRDN set pu fallback packet length mismatch")
|
log.debug(log_tag .. "CRDN set pu fallback packet length mismatch")
|
||||||
end
|
end
|
||||||
elseif cmd == FAC_COMMAND.SET_SPS_LP then
|
elseif cmd == FAC_COMMAND.SET_SPS_LP then
|
||||||
if pkt.length == 2 then
|
if pkt.length == 2 then
|
||||||
_send(CRDN_TYPE.FAC_CMD, { cmd, facility.set_sps_low_power(pkt.data[2]) })
|
_send(CRDN_TYPE.FAC_CMD, { cmd, facility.set_sps_low_power(pkt.data[2] == true) })
|
||||||
else
|
else
|
||||||
log.debug(log_tag .. "CRDN set sps low power packet length mismatch")
|
log.debug(log_tag .. "CRDN set sps low power packet length mismatch")
|
||||||
end
|
end
|
||||||
|
|||||||
@ -22,7 +22,7 @@ local supervisor = require("supervisor.supervisor")
|
|||||||
|
|
||||||
local svsessions = require("supervisor.session.svsessions")
|
local svsessions = require("supervisor.session.svsessions")
|
||||||
|
|
||||||
local SUPERVISOR_VERSION = "v1.5.15"
|
local SUPERVISOR_VERSION = "v1.5.17"
|
||||||
|
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local println_ts = util.println_ts
|
local println_ts = util.println_ts
|
||||||
|
|||||||
@ -986,7 +986,8 @@ function unit.new(reactor_id, num_boilers, num_turbines, ext_idle)
|
|||||||
local db = self.snas[i].get_db()
|
local db = self.snas[i].get_db()
|
||||||
total_peak = total_peak + db.state.peak_production
|
total_peak = total_peak + db.state.peak_production
|
||||||
total_avail = total_avail + db.state.production_rate
|
total_avail = total_avail + db.state.production_rate
|
||||||
total_out = total_out + math.min(db.tanks.input.amount / 10, db.state.production_rate)
|
local out_from_in = util.trinary(db.tanks.input.amount >= 10, db.tanks.input.amount / 10, 0)
|
||||||
|
total_out = total_out + math.min(out_from_in, db.state.production_rate)
|
||||||
end
|
end
|
||||||
status.sna = { #self.snas, total_peak, total_avail, total_out }
|
status.sna = { #self.snas, total_peak, total_avail, total_out }
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user