mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
#283 common cleanup, added lockbox version to crash dump, changed crash handler to pcall requires for graphics/lockbox
This commit is contained in:
parent
451f804f87
commit
9ce75eb4bd
@ -2,10 +2,12 @@
|
||||
-- System and Safety Constants
|
||||
--
|
||||
|
||||
---@class scada_constants
|
||||
local constants = {}
|
||||
|
||||
--#region Reactor Protection System (on the PLC) Limits
|
||||
|
||||
---@class _rps_constants
|
||||
local rps = {}
|
||||
|
||||
rps.MAX_DAMAGE_PERCENT = 90 -- damage >= 90%
|
||||
@ -21,6 +23,7 @@ constants.RPS_LIMITS = rps
|
||||
|
||||
--#region Annunciator Limits
|
||||
|
||||
---@class _annunciator_constants
|
||||
local annunc = {}
|
||||
|
||||
annunc.RCSFlowLow_H2O = -3.2 -- flow < -3.2 mB/s
|
||||
@ -44,6 +47,7 @@ constants.ANNUNCIATOR_LIMITS = annunc
|
||||
|
||||
--#region Supervisor Alarm Limits
|
||||
|
||||
---@class _alarm_constants
|
||||
local alarms = {}
|
||||
|
||||
-- unit alarms
|
||||
|
@ -6,8 +6,10 @@ local comms = require("scada-common.comms")
|
||||
local log = require("scada-common.log")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local core = require("graphics.core")
|
||||
local has_graphics, core = pcall(require, "graphics.core")
|
||||
local has_lockbox, lockbox = pcall(require, "lockbox")
|
||||
|
||||
---@class crash_handler
|
||||
local crash = {}
|
||||
|
||||
local app = "unknown"
|
||||
@ -34,7 +36,8 @@ function crash.handler(error)
|
||||
log.info(util.c("APPLICATION: ", app))
|
||||
log.info(util.c("FIRMWARE VERSION: ", ver))
|
||||
log.info(util.c("COMMS VERSION: ", comms.version))
|
||||
log.info(util.c("GRAPHICS VERSION: ", core.version))
|
||||
if has_graphics then log.info(util.c("GRAPHICS VERSION: ", core.version)) end
|
||||
if has_lockbox then log.info(util.c("LOCKBOX VERSION: ", lockbox.version)) end
|
||||
log.info("----------------------------------")
|
||||
log.info(debug.traceback("--- begin debug trace ---", 1))
|
||||
log.info("--- end debug trace ---")
|
||||
|
@ -4,14 +4,11 @@
|
||||
|
||||
local util = require("scada-common.util")
|
||||
|
||||
---@class log
|
||||
---@class logger
|
||||
local log = {}
|
||||
|
||||
---@alias MODE integer
|
||||
local MODE = {
|
||||
APPEND = 0,
|
||||
NEW = 1
|
||||
}
|
||||
local MODE = { APPEND = 0, NEW = 1 }
|
||||
|
||||
log.MODE = MODE
|
||||
|
||||
|
@ -4,6 +4,14 @@
|
||||
|
||||
local mqueue = {}
|
||||
|
||||
---@class queue_item
|
||||
---@field qtype MQ_TYPE
|
||||
---@field message any
|
||||
|
||||
---@class queue_data
|
||||
---@field key any
|
||||
---@field val any
|
||||
|
||||
---@enum MQ_TYPE
|
||||
local TYPE = {
|
||||
COMMAND = 0,
|
||||
@ -13,22 +21,14 @@ local TYPE = {
|
||||
|
||||
mqueue.TYPE = TYPE
|
||||
|
||||
local insert = table.insert
|
||||
local remove = table.remove
|
||||
|
||||
-- create a new message queue
|
||||
---@nodiscard
|
||||
function mqueue.new()
|
||||
local queue = {}
|
||||
|
||||
local insert = table.insert
|
||||
local remove = table.remove
|
||||
|
||||
---@class queue_item
|
||||
---@field qtype MQ_TYPE
|
||||
---@field message any
|
||||
|
||||
---@class queue_data
|
||||
---@field key any
|
||||
---@field val any
|
||||
|
||||
---@class mqueue
|
||||
local public = {}
|
||||
|
||||
@ -48,28 +48,20 @@ function mqueue.new()
|
||||
-- push a new item onto the queue
|
||||
---@param qtype MQ_TYPE
|
||||
---@param message any
|
||||
local function _push(qtype, message)
|
||||
insert(queue, { qtype = qtype, message = message })
|
||||
end
|
||||
local function _push(qtype, message) insert(queue, { qtype = qtype, message = message }) end
|
||||
|
||||
-- push a command onto the queue
|
||||
---@param message any
|
||||
function public.push_command(message)
|
||||
_push(TYPE.COMMAND, message)
|
||||
end
|
||||
function public.push_command(message) _push(TYPE.COMMAND, message) end
|
||||
|
||||
-- push data onto the queue
|
||||
---@param key any
|
||||
---@param value any
|
||||
function public.push_data(key, value)
|
||||
_push(TYPE.DATA, { key = key, val = value })
|
||||
end
|
||||
function public.push_data(key, value) _push(TYPE.DATA, { key = key, val = value }) end
|
||||
|
||||
-- push a packet onto the queue
|
||||
---@param packet packet|frame
|
||||
function public.push_packet(packet)
|
||||
_push(TYPE.PACKET, packet)
|
||||
end
|
||||
function public.push_packet(packet) _push(TYPE.PACKET, packet) end
|
||||
|
||||
-- get an item off the queue
|
||||
---@nodiscard
|
||||
@ -77,9 +69,7 @@ function mqueue.new()
|
||||
function public.pop()
|
||||
if #queue > 0 then
|
||||
return remove(queue, 1)
|
||||
else
|
||||
return nil
|
||||
end
|
||||
else return nil end
|
||||
end
|
||||
|
||||
return public
|
||||
|
@ -2,19 +2,21 @@
|
||||
-- Network Communications
|
||||
--
|
||||
|
||||
local comms = require("scada-common.comms")
|
||||
local log = require("scada-common.log")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local md5 = require("lockbox.digest.md5")
|
||||
local sha256 = require("lockbox.digest.sha2_256")
|
||||
local pbkdf2 = require("lockbox.kdf.pbkdf2")
|
||||
local hmac = require("lockbox.mac.hmac")
|
||||
local stream = require("lockbox.util.stream")
|
||||
local array = require("lockbox.util.array")
|
||||
local comms = require("scada-common.comms")
|
||||
|
||||
local log = require("scada-common.log")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
---@class scada_net_interface
|
||||
local network = {}
|
||||
|
||||
-- cryptography engine
|
||||
local c_eng = {
|
||||
key = nil,
|
||||
hmac = nil
|
||||
|
@ -8,15 +8,13 @@ local util = require("scada-common.util")
|
||||
---@class ppm
|
||||
local ppm = {}
|
||||
|
||||
local ACCESS_FAULT = nil ---@type nil
|
||||
|
||||
local UNDEFINED_FIELD = "undefined field"
|
||||
|
||||
local ACCESS_FAULT = nil ---@type nil
|
||||
local UNDEFINED_FIELD = "undefined field"
|
||||
local VIRTUAL_DEVICE_TYPE = "ppm_vdev"
|
||||
|
||||
ppm.ACCESS_FAULT = ACCESS_FAULT
|
||||
ppm.UNDEFINED_FIELD = UNDEFINED_FIELD
|
||||
ppm.VIRTUAL_DEVICE_TYPE = VIRTUAL_DEVICE_TYPE
|
||||
ppm.ACCESS_FAULT = ACCESS_FAULT
|
||||
ppm.UNDEFINED_FIELD = UNDEFINED_FIELD
|
||||
ppm.VIRTUAL_DEVICE_TYPE = VIRTUAL_DEVICE_TYPE
|
||||
|
||||
----------------------------
|
||||
-- PRIVATE DATA/FUNCTIONS --
|
||||
@ -34,9 +32,9 @@ local ppm_sys = {
|
||||
mute = false
|
||||
}
|
||||
|
||||
-- wrap peripheral calls with lua protected call as we don't want a disconnect to crash a program<br>
|
||||
-- also provides peripheral-specific fault checks (auto-clear fault defaults to true)<br>
|
||||
-- assumes iface is a valid peripheral
|
||||
-- Wrap peripheral calls with lua protected call as we don't want a disconnect to crash a program.
|
||||
-- Additionally provides peripheral-specific fault checks (auto-clear fault defaults to true).<br>
|
||||
-- Note: assumes iface is a valid peripheral.
|
||||
---@param iface string CC peripheral interface
|
||||
local function peri_init(iface)
|
||||
local self = {
|
||||
@ -307,16 +305,12 @@ end
|
||||
-- list all available peripherals
|
||||
---@nodiscard
|
||||
---@return table names
|
||||
function ppm.list_avail()
|
||||
return peripheral.getNames()
|
||||
end
|
||||
function ppm.list_avail() return peripheral.getNames() end
|
||||
|
||||
-- list mounted peripherals
|
||||
---@nodiscard
|
||||
---@return table mounts
|
||||
function ppm.list_mounts()
|
||||
return ppm_sys.mounts
|
||||
end
|
||||
function ppm.list_mounts() return ppm_sys.mounts end
|
||||
|
||||
-- get a mounted peripheral side/interface by device table
|
||||
---@nodiscard
|
||||
@ -390,9 +384,7 @@ end
|
||||
-- get the fission reactor (if multiple, returns the first)
|
||||
---@nodiscard
|
||||
---@return table|nil reactor function table
|
||||
function ppm.get_fission_reactor()
|
||||
return ppm.get_device("fissionReactorLogicAdapter")
|
||||
end
|
||||
function ppm.get_fission_reactor() return ppm.get_device("fissionReactorLogicAdapter") end
|
||||
|
||||
-- get the wireless modem (if multiple, returns the first)<br>
|
||||
-- if this is in a CraftOS emulated environment, wired modems will be used instead
|
||||
@ -419,9 +411,7 @@ function ppm.get_monitor_list()
|
||||
local list = {}
|
||||
|
||||
for iface, device in pairs(ppm_sys.mounts) do
|
||||
if device.type == "monitor" then
|
||||
list[iface] = device
|
||||
end
|
||||
if device.type == "monitor" then list[iface] = device end
|
||||
end
|
||||
|
||||
return list
|
||||
|
@ -9,14 +9,12 @@ local psil = {}
|
||||
-- instantiate a new PSI layer
|
||||
---@nodiscard
|
||||
function psil.create()
|
||||
local self = {
|
||||
ic = {}
|
||||
}
|
||||
local ic = {}
|
||||
|
||||
-- allocate a new interconnect field
|
||||
---@key string data key
|
||||
local function alloc(key)
|
||||
self.ic[key] = { subscribers = {}, value = nil }
|
||||
ic[key] = { subscribers = {}, value = nil }
|
||||
end
|
||||
|
||||
---@class psil
|
||||
@ -28,22 +26,22 @@ function psil.create()
|
||||
---@param func function function to call on change
|
||||
function public.subscribe(key, func)
|
||||
-- allocate new key if not found or notify if value is found
|
||||
if self.ic[key] == nil then
|
||||
if ic[key] == nil then
|
||||
alloc(key)
|
||||
elseif self.ic[key].value ~= nil then
|
||||
func(self.ic[key].value)
|
||||
elseif ic[key].value ~= nil then
|
||||
func(ic[key].value)
|
||||
end
|
||||
|
||||
-- subscribe to key
|
||||
table.insert(self.ic[key].subscribers, { notify = func })
|
||||
table.insert(ic[key].subscribers, { notify = func })
|
||||
end
|
||||
|
||||
-- unsubscribe a function from a given key
|
||||
---@param key string data key
|
||||
---@param func function function to unsubscribe
|
||||
function public.unsubscribe(key, func)
|
||||
if self.ic[key] ~= nil then
|
||||
util.filter_table(self.ic[key].subscribers, function (s) return s.notify ~= func end)
|
||||
if ic[key] ~= nil then
|
||||
util.filter_table(ic[key].subscribers, function (s) return s.notify ~= func end)
|
||||
end
|
||||
end
|
||||
|
||||
@ -51,32 +49,32 @@ function psil.create()
|
||||
---@param key string data key
|
||||
---@param value any data value
|
||||
function public.publish(key, value)
|
||||
if self.ic[key] == nil then alloc(key) end
|
||||
if ic[key] == nil then alloc(key) end
|
||||
|
||||
if self.ic[key].value ~= value then
|
||||
for i = 1, #self.ic[key].subscribers do
|
||||
self.ic[key].subscribers[i].notify(value)
|
||||
if ic[key].value ~= value then
|
||||
for i = 1, #ic[key].subscribers do
|
||||
ic[key].subscribers[i].notify(value)
|
||||
end
|
||||
end
|
||||
|
||||
self.ic[key].value = value
|
||||
ic[key].value = value
|
||||
end
|
||||
|
||||
-- publish a toggled boolean value to a given key, passing it to all subscribers if it has changed<br>
|
||||
-- this is intended to be used to toggle boolean indicators such as heartbeats without extra state variables
|
||||
---@param key string data key
|
||||
function public.toggle(key)
|
||||
if self.ic[key] == nil then alloc(key) end
|
||||
if ic[key] == nil then alloc(key) end
|
||||
|
||||
self.ic[key].value = self.ic[key].value == false
|
||||
ic[key].value = ic[key].value == false
|
||||
|
||||
for i = 1, #self.ic[key].subscribers do
|
||||
self.ic[key].subscribers[i].notify(self.ic[key].value)
|
||||
for i = 1, #ic[key].subscribers do
|
||||
ic[key].subscribers[i].notify(ic[key].value)
|
||||
end
|
||||
end
|
||||
|
||||
-- clear the contents of the interconnect
|
||||
function public.purge() self.ic = nil end
|
||||
function public.purge() ic = {} end
|
||||
|
||||
return public
|
||||
end
|
||||
|
@ -123,7 +123,7 @@ function rsio.to_string(port)
|
||||
if util.is_int(port) and port > 0 and port <= #names then
|
||||
return names[port]
|
||||
else
|
||||
return ""
|
||||
return "UNKNOWN"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -68,7 +68,7 @@ function tcd.handle(event)
|
||||
end
|
||||
end
|
||||
|
||||
-- identify any overdo callbacks<br>
|
||||
-- identify any overdue callbacks<br>
|
||||
-- prints to log debug output
|
||||
function tcd.diagnostics()
|
||||
for timer, entry in pairs(registry) do
|
||||
|
@ -80,9 +80,9 @@ end
|
||||
---@return string
|
||||
function util.strrep(str, n)
|
||||
local repeated = ""
|
||||
for _ = 1, n do
|
||||
repeated = repeated .. str
|
||||
end
|
||||
|
||||
for _ = 1, n do repeated = repeated .. str end
|
||||
|
||||
return repeated
|
||||
end
|
||||
|
||||
@ -123,7 +123,9 @@ function util.strwrap(str, limit) return cc_strings.wrap(str, limit) end
|
||||
---@diagnostic disable-next-line: unused-vararg
|
||||
function util.concat(...)
|
||||
local str = ""
|
||||
|
||||
for _, v in ipairs(arg) do str = str .. util.strval(v) end
|
||||
|
||||
return str
|
||||
end
|
||||
|
||||
@ -322,7 +324,8 @@ end
|
||||
--- EVENT_CONSUMER: this function consumes events
|
||||
function util.nop() util.psleep(0.05) end
|
||||
|
||||
-- attempt to maintain a minimum loop timing (duration of execution)
|
||||
-- attempt to maintain a minimum loop timing (duration of execution)<br>
|
||||
-- note: will not yield for time periods less than 50ms
|
||||
---@nodiscard
|
||||
---@param target_timing integer minimum amount of milliseconds to wait for
|
||||
---@param last_update integer millisecond time of last update
|
||||
@ -399,7 +402,7 @@ local function GFE(fe) return fe / 1000000000.0 end
|
||||
local function TFE(fe) return fe / 1000000000000.0 end
|
||||
local function PFE(fe) return fe / 1000000000000000.0 end
|
||||
local function EFE(fe) return fe / 1000000000000000000.0 end -- if you accomplish this please touch grass
|
||||
local function ZFE(fe) return fe / 1000000000000000000000.0 end -- please stop
|
||||
local function ZFE(fe) return fe / 1000000000000000000000.0 end -- how & why did you do this?
|
||||
|
||||
-- format a power value into XXX.XX UNIT format (FE, kFE, MFE, GFE, TFE, PFE, EFE, ZFE)
|
||||
---@nodiscard
|
||||
|
Loading…
Reference in New Issue
Block a user