Merge pull request #577 from MikaylaFischler/pocket-alpha-dev

Waste App
This commit is contained in:
Mikayla 2024-11-19 21:24:08 -05:00 committed by GitHub
commit 56e4f93db8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 608 additions and 52 deletions

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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")

View File

@ -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
--------------------------------- ---------------------------------

View File

@ -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

View File

@ -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
View 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

View File

@ -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)

View File

@ -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}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 }