mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
Merge branch 'devel' into 193-pocket-main-application
This commit is contained in:
commit
d9ec3d7825
28
.github/workflows/check.yml
vendored
Normal file
28
.github/workflows/check.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
name: Lua Checks
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- latest
|
||||
- devel
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- latest
|
||||
- devel
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v3.5.1
|
||||
- name: Luacheck
|
||||
uses: lunarmodules/luacheck@v1.1.0
|
||||
with:
|
||||
# -a = disable warning for unused arguments
|
||||
# -i 121 = Setting a read-only global variable.
|
||||
# -u 512 = Loop can be executed at most once.
|
||||
# -i 542 = An empty if branch.
|
||||
args: . --no-max-line-length -a -i 121 512 542 --exclude-files ./lockbox/* ./*/config.lua --globals _HOST term fs peripheral rs bit parallel colors textutils shell settings window read periphemu http os
|
47
.github/workflows/shields.yml
vendored
Normal file
47
.github/workflows/shields.yml
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
# Simple workflow for deploying static content to GitHub Pages
|
||||
name: Deploy Component Versions
|
||||
|
||||
on:
|
||||
# Runs on pushes targeting the default branch
|
||||
push:
|
||||
branches: ["main"]
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
|
||||
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
# Single deploy job since we're just deploying
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v3
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v3.1.3
|
||||
- run: mkdir shields
|
||||
- run: python imgen.py shields
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v1
|
||||
with:
|
||||
# Upload shields JSON
|
||||
path: '.'
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v2
|
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -13,7 +13,6 @@
|
||||
"window",
|
||||
"read",
|
||||
"periphemu",
|
||||
"mekanismEnergyHelper",
|
||||
"_HOST",
|
||||
"http"
|
||||
],
|
||||
|
25
README.md
25
README.md
@ -1,6 +1,12 @@
|
||||
# cc-mek-scada
|
||||
Configurable ComputerCraft SCADA system for multi-reactor control of Mekanism fission reactors with a GUI, automatic safety features, waste processing control, and more!
|
||||
|
||||
![GitHub](https://img.shields.io/github/license/MikaylaFischler/cc-mek-scada)
|
||||
![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/MikaylaFischler/cc-mek-scada?include_prereleases)
|
||||
![GitHub Workflow Status (with branch)](https://img.shields.io/github/actions/workflow/status/MikaylaFischler/cc-mek-scada/check.yml?branch=main&label=main)
|
||||
![GitHub Workflow Status (with branch)](https://img.shields.io/github/actions/workflow/status/MikaylaFischler/cc-mek-scada/check.yml?branch=latest&label=latest)
|
||||
![GitHub Workflow Status (with branch)](https://img.shields.io/github/actions/workflow/status/MikaylaFischler/cc-mek-scada/check.yml?branch=devel&label=devel)
|
||||
|
||||
Mod Requirements:
|
||||
- CC: Tweaked
|
||||
- Mekanism v10.1+
|
||||
@ -12,6 +18,25 @@ v10.1+ is required due the complete support of CC:Tweaked added in Mekanism v10.
|
||||
|
||||
There was also an apparent bug with boilers disconnecting and reconnecting when active in my test world on 10.0.24, so it may not even have been an option to fully implement this with support for 10.0.
|
||||
|
||||
## Released Component Versions
|
||||
|
||||
### Core
|
||||
|
||||
![Bootloader](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Fbootloader.json)
|
||||
![Comms](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Fcomms.json)
|
||||
|
||||
### Utilities
|
||||
|
||||
![Installer](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Finstaller.json)
|
||||
|
||||
### Applications
|
||||
|
||||
![Reactor PLC](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Freactor-plc.json)
|
||||
![RTU](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Frtu.json)
|
||||
![Supervisor](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Fsupervisor.json)
|
||||
![Coordinator](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Fcoordinator.json)
|
||||
![Pocket](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Fpocket.json)
|
||||
|
||||
## Installation
|
||||
|
||||
You can install this on a ComputerCraft computer using either:
|
||||
|
@ -1,11 +1,13 @@
|
||||
local apisessions = {}
|
||||
|
||||
---@param packet capi_frame
|
||||
---@diagnostic disable-next-line: unused-local
|
||||
function apisessions.handle_packet(packet)
|
||||
end
|
||||
|
||||
-- attempt to identify which session's watchdog timer fired
|
||||
---@param timer_event number
|
||||
---@diagnostic disable-next-line: unused-local
|
||||
function apisessions.check_all_watchdogs(timer_event)
|
||||
end
|
||||
|
||||
|
@ -11,7 +11,6 @@ local dialog = require("coordinator.ui.dialog")
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
local print_ts = util.print_ts
|
||||
local println_ts = util.println_ts
|
||||
|
||||
local PROTOCOL = comms.PROTOCOL
|
||||
@ -246,7 +245,7 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, range
|
||||
---@param msg table
|
||||
local function _send_sv(protocol, msg_type, msg)
|
||||
local s_pkt = comms.scada_packet()
|
||||
local pkt = nil ---@type mgmt_packet|crdn_packet
|
||||
local pkt ---@type mgmt_packet|crdn_packet
|
||||
|
||||
if protocol == PROTOCOL.SCADA_MGMT then
|
||||
pkt = comms.mgmt_packet()
|
||||
|
@ -657,8 +657,8 @@ function iocontrol.update_unit_statuses(statuses)
|
||||
if type(rtu_statuses.rad_mon) == "table" then
|
||||
if #rtu_statuses.rad_mon > 0 then
|
||||
local rad_mon = rtu_statuses.rad_mon[1]
|
||||
local rtu_faulted = rad_mon[1] ---@type boolean
|
||||
unit.radiation = rad_mon[2] ---@type number
|
||||
-- local rtu_faulted = rad_mon[1] ---@type boolean
|
||||
unit.radiation = rad_mon[2] ---@type number
|
||||
|
||||
unit.unit_ps.publish("radiation", unit.radiation)
|
||||
else
|
||||
|
@ -12,10 +12,11 @@ local ALARM_STATE = types.ALARM_STATE
|
||||
---@class sounder
|
||||
local sounder = {}
|
||||
|
||||
-- note: max samples = 0x20000 (128 * 1024 samples)
|
||||
|
||||
local _2_PI = 2 * math.pi -- 2 whole pies, hope you're hungry
|
||||
local _DRATE = 48000 -- 48kHz audio
|
||||
local _MAX_VAL = 127 / 2 -- max signed integer in this 8-bit audio
|
||||
local _MAX_SAMPLES = 0x20000 -- 128 * 1024 samples
|
||||
local _05s_SAMPLES = 24000 -- half a second worth of samples
|
||||
|
||||
local test_alarms = { false, false, false, false, false, false, false, false, false, false, false, false }
|
||||
|
@ -21,9 +21,7 @@ local sounder = require("coordinator.sounder")
|
||||
|
||||
local COORDINATOR_VERSION = "v0.12.6"
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
local print_ts = util.print_ts
|
||||
local println_ts = util.println_ts
|
||||
|
||||
local log_graphics = coordinator.log_graphics
|
||||
@ -287,7 +285,7 @@ local function main()
|
||||
else
|
||||
log_sys("wired modem reconnected")
|
||||
end
|
||||
elseif type == "monitor" then
|
||||
-- elseif type == "monitor" then
|
||||
-- not supported, system will exit on loss of in-use monitors
|
||||
elseif type == "speaker" then
|
||||
local msg = "alarm sounder speaker reconnected"
|
||||
|
@ -18,9 +18,8 @@ local border = core.graphics.border
|
||||
---@param root graphics_element parent
|
||||
---@param x integer top left x
|
||||
---@param y integer top left y
|
||||
---@param data reactor_db reactor data
|
||||
---@param ps psil ps interface
|
||||
local function new_view(root, x, y, data, ps)
|
||||
local function new_view(root, x, y, ps)
|
||||
local reactor = Rectangle{parent=root,border=border(1, colors.gray, true),width=30,height=7,x=x,y=y}
|
||||
|
||||
local text_fg_bg = cpair(colors.black, colors.lightGray)
|
||||
|
@ -24,19 +24,18 @@ local pipe = core.graphics.pipe
|
||||
---@param y integer top left y
|
||||
---@param unit ioctl_unit unit database entry
|
||||
local function make(parent, x, y, unit)
|
||||
local height = 0
|
||||
local num_boilers = #unit.boiler_data_tbl
|
||||
local num_turbines = #unit.turbine_data_tbl
|
||||
|
||||
assert(num_boilers >= 0 and num_boilers <= 2, "minimum 0 boilers, maximum 2 boilers")
|
||||
assert(num_turbines >= 1 and num_turbines <= 3, "minimum 1 turbine, maximum 3 turbines")
|
||||
|
||||
local height = 25
|
||||
|
||||
if num_boilers == 0 and num_turbines == 1 then
|
||||
height = 9
|
||||
elseif num_boilers == 1 and num_turbines <= 2 then
|
||||
height = 17
|
||||
else
|
||||
height = 25
|
||||
end
|
||||
|
||||
assert(parent.height() >= (y + height), "main display not of sufficient vertical resolution (add an additional row of monitors)")
|
||||
@ -51,7 +50,7 @@ local function make(parent, x, y, unit)
|
||||
-- REACTOR --
|
||||
-------------
|
||||
|
||||
reactor_view(root, 1, 3, unit.reactor_data, unit.unit_ps)
|
||||
reactor_view(root, 1, 3, unit.unit_ps)
|
||||
|
||||
if num_boilers > 0 then
|
||||
local coolant_pipes = {}
|
||||
|
@ -5,7 +5,6 @@
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local iocontrol = require("coordinator.iocontrol")
|
||||
local sounder = require("coordinator.sounder")
|
||||
|
||||
local style = require("coordinator.ui.style")
|
||||
|
||||
@ -15,14 +14,9 @@ local unit_overview = require("coordinator.ui.components.unit_overview")
|
||||
|
||||
local core = require("graphics.core")
|
||||
|
||||
local ColorMap = require("graphics.elements.colormap")
|
||||
local DisplayBox = require("graphics.elements.displaybox")
|
||||
local Div = require("graphics.elements.div")
|
||||
local TextBox = require("graphics.elements.textbox")
|
||||
|
||||
local PushButton = require("graphics.elements.controls.push_button")
|
||||
local SwitchButton = require("graphics.elements.controls.switch_button")
|
||||
|
||||
local DataIndicator = require("graphics.elements.indicators.data")
|
||||
|
||||
local TEXT_ALIGN = core.graphics.TEXT_ALIGN
|
||||
|
@ -30,8 +30,7 @@ local function spinbox(args)
|
||||
assert(util.is_int(wn_prec), "graphics.element.controls.spinbox_numeric: whole number precision must be an integer")
|
||||
assert(util.is_int(fr_prec), "graphics.element.controls.spinbox_numeric: fractional precision must be an integer")
|
||||
|
||||
local fmt = ""
|
||||
local fmt_init = ""
|
||||
local fmt, fmt_init ---@type string, string
|
||||
|
||||
if fr_prec > 0 then
|
||||
fmt = "%" .. (wn_prec + fr_prec + 1) .. "." .. fr_prec .. "f"
|
||||
|
@ -73,7 +73,7 @@ local function core_map(args)
|
||||
local function draw_core(t)
|
||||
local i = 1
|
||||
local back_c = "F"
|
||||
local text_c = "8"
|
||||
local text_c ---@type string
|
||||
|
||||
-- determine fuel assembly coloring
|
||||
if t <= 300 then
|
||||
|
@ -38,7 +38,7 @@ local function indicator_led_rgb(args)
|
||||
e.value = new_state
|
||||
e.window.setCursorPos(1, 1)
|
||||
if type(args.colors[new_state]) == "number" then
|
||||
e.window.blit("\x8c", colors.toBlit(args.colors[new_state]), e.fg_bg.blit_bkg)
|
||||
e.window.blit("\x8c", colors.toBlit(args.colors[new_state]), e.fg_bg.blit_bkg)
|
||||
end
|
||||
end
|
||||
|
||||
|
26
imgen.py
26
imgen.py
@ -1,5 +1,6 @@
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
# list files in a directory
|
||||
def list_files(path):
|
||||
@ -100,7 +101,30 @@ f.close()
|
||||
|
||||
manifest_size = os.path.getsize("install_manifest.json")
|
||||
|
||||
final_manifest = make_manifest(manifest_size)
|
||||
|
||||
# calculate file size then regenerate with embedded size
|
||||
f = open("install_manifest.json", "w")
|
||||
json.dump(make_manifest(manifest_size), f)
|
||||
json.dump(final_manifest, f)
|
||||
f.close()
|
||||
|
||||
if sys.argv[1] == "shields":
|
||||
# write all the JSON files for shields.io
|
||||
for key, version in final_manifest["versions"].items():
|
||||
f = open("./shields/" + key + ".json", "w")
|
||||
|
||||
if version.find("alpha") >= 0:
|
||||
color = "yellow"
|
||||
elif version.find("beta") >= 0:
|
||||
color = "orange"
|
||||
else:
|
||||
color = "blue"
|
||||
|
||||
json.dump({
|
||||
"schemaVersion": 1,
|
||||
"label": key,
|
||||
"message": "" + version,
|
||||
"color": color
|
||||
}, f)
|
||||
|
||||
f.close()
|
||||
|
File diff suppressed because one or more lines are too long
@ -18,9 +18,9 @@ local renderer = require("pocket.renderer")
|
||||
|
||||
local POCKET_VERSION = "alpha-v0.1.0"
|
||||
|
||||
local print = util.print
|
||||
-- local print = util.print
|
||||
local println = util.println
|
||||
local print_ts = util.print_ts
|
||||
-- local print_ts = util.print_ts
|
||||
local println_ts = util.println_ts
|
||||
|
||||
----------------------------------------
|
||||
|
@ -68,11 +68,6 @@ function plc.rps_init(reactor, is_formed, emer_cool)
|
||||
end
|
||||
end
|
||||
|
||||
-- clear reactor access fault flag
|
||||
local function _clear_fault()
|
||||
self.state[state_keys.fault] = false
|
||||
end
|
||||
|
||||
-- set emergency coolant control (if configured)
|
||||
---@param state boolean true to enable emergency coolant, false to disable
|
||||
local function _set_emer_cool(state)
|
||||
@ -779,7 +774,6 @@ function plc.comms(id, version, modem, local_port, server_port, range, reactor,
|
||||
---@param setpoints setpoints setpoint control table
|
||||
function public.handle_packet(packet, plc_state, setpoints)
|
||||
-- print a log message to the terminal as long as the UI isn't running
|
||||
local function println(message) if not plc_state.fp_ok then util.println(message) end end
|
||||
local function println_ts(message) if not plc_state.fp_ok then util.println_ts(message) end end
|
||||
|
||||
-- handle packets now that we have prints setup
|
||||
|
@ -20,9 +20,7 @@ local threads = require("reactor-plc.threads")
|
||||
|
||||
local R_PLC_VERSION = "v1.1.5"
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
local print_ts = util.print_ts
|
||||
local println_ts = util.println_ts
|
||||
|
||||
----------------------------------------
|
||||
@ -176,8 +174,9 @@ local function main()
|
||||
|
||||
-- front panel time!
|
||||
if not renderer.ui_ready() then
|
||||
local message = nil
|
||||
local message
|
||||
plc_state.fp_ok, message = pcall(renderer.start_ui)
|
||||
|
||||
if not plc_state.fp_ok then
|
||||
renderer.close_ui()
|
||||
println_ts(util.c("UI error: ", message))
|
||||
|
@ -34,7 +34,6 @@ local MQ__COMM_CMD = {
|
||||
---@param init function
|
||||
function threads.thread__main(smem, init)
|
||||
-- print a log message to the terminal as long as the UI isn't running
|
||||
local function println(message) if not smem.plc_state.fp_ok then util.println(message) end end
|
||||
local function println_ts(message) if not smem.plc_state.fp_ok then util.println_ts(message) end end
|
||||
|
||||
---@class parallel_thread
|
||||
@ -307,7 +306,6 @@ end
|
||||
---@param smem plc_shared_memory
|
||||
function threads.thread__rps(smem)
|
||||
-- print a log message to the terminal as long as the UI isn't running
|
||||
local function println(message) if not smem.plc_state.fp_ok then util.println(message) end end
|
||||
local function println_ts(message) if not smem.plc_state.fp_ok then util.println_ts(message) end end
|
||||
|
||||
---@class parallel_thread
|
||||
@ -682,7 +680,7 @@ function threads.thread__setpoint_control(smem)
|
||||
-- we yielded, check enable again
|
||||
if setpoints.burn_rate_en and (type(current_burn_rate) == "number") and (current_burn_rate ~= setpoints.burn_rate) then
|
||||
-- calculate new burn rate
|
||||
local new_burn_rate = current_burn_rate
|
||||
local new_burn_rate ---@type number
|
||||
|
||||
if setpoints.burn_rate > current_burn_rate then
|
||||
-- need to ramp up
|
||||
|
@ -34,7 +34,7 @@ function redstone_rtu.new()
|
||||
---@param side string
|
||||
---@param color integer
|
||||
function public.link_di(side, color)
|
||||
local f_read = nil
|
||||
local f_read ---@type function
|
||||
|
||||
if color then
|
||||
f_read = function ()
|
||||
@ -53,8 +53,8 @@ function redstone_rtu.new()
|
||||
---@param side string
|
||||
---@param color integer
|
||||
function public.link_do(side, color)
|
||||
local f_read = nil
|
||||
local f_write = nil
|
||||
local f_read ---@type function
|
||||
local f_write ---@type function
|
||||
|
||||
if color then
|
||||
f_read = function ()
|
||||
|
@ -347,11 +347,9 @@ function modbus.new(rtu_dev, use_parallel_read)
|
||||
response = { MODBUS_EXCODE.NEG_ACKNOWLEDGE }
|
||||
end
|
||||
|
||||
-- default is to echo back
|
||||
local func_code = packet.func_code
|
||||
|
||||
-- echo back with error flag, on success the "error" will be acknowledgement
|
||||
func_code = bit.bor(packet.func_code, MODBUS_FCODE.ERROR_FLAG)
|
||||
-- default is to echo back<br>
|
||||
-- but here we echo back with error flag, on success the "error" will be acknowledgement
|
||||
local func_code = bit.bor(packet.func_code, MODBUS_FCODE.ERROR_FLAG)
|
||||
|
||||
-- create reply
|
||||
local reply = comms.modbus_packet()
|
||||
@ -365,8 +363,8 @@ function modbus.new(rtu_dev, use_parallel_read)
|
||||
---@param packet modbus_frame
|
||||
---@return boolean return_code, modbus_packet reply
|
||||
function public.handle_packet(packet)
|
||||
local return_code = true
|
||||
local response = nil
|
||||
local return_code ---@type boolean
|
||||
local response ---@type table|MODBUS_EXCODE
|
||||
|
||||
if packet.length >= 2 then
|
||||
-- handle by function code
|
||||
|
@ -14,9 +14,6 @@ local ESTABLISH_ACK = comms.ESTABLISH_ACK
|
||||
local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE
|
||||
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
local print_ts = util.print_ts
|
||||
local println_ts = util.println_ts
|
||||
|
||||
-- create a new RTU unit
|
||||
@ -347,8 +344,8 @@ function rtu.comms(version, modem, local_port, server_port, range, conn_watchdog
|
||||
if protocol == PROTOCOL.MODBUS_TCP then
|
||||
---@cast packet modbus_frame
|
||||
if rtu_state.linked then
|
||||
local return_code = false
|
||||
local reply = modbus.reply__neg_ack(packet)
|
||||
local return_code ---@type boolean
|
||||
local reply ---@type modbus_packet
|
||||
|
||||
-- handle MODBUS instruction
|
||||
if packet.unit_id <= #units then
|
||||
|
@ -25,13 +25,11 @@ local sna_rtu = require("rtu.dev.sna_rtu")
|
||||
local sps_rtu = require("rtu.dev.sps_rtu")
|
||||
local turbinev_rtu = require("rtu.dev.turbinev_rtu")
|
||||
|
||||
local RTU_VERSION = "v0.13.2"
|
||||
local RTU_VERSION = "v0.13.3"
|
||||
|
||||
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
local print_ts = util.print_ts
|
||||
local println_ts = util.println_ts
|
||||
|
||||
----------------------------------------
|
||||
@ -287,9 +285,9 @@ local function main()
|
||||
|
||||
local device = ppm.get_periph(name)
|
||||
|
||||
local type = nil ---@type string|nil
|
||||
local rtu_iface = nil ---@type rtu_device
|
||||
local rtu_type = nil ---@type RTU_UNIT_TYPE
|
||||
local type ---@type string|nil
|
||||
local rtu_iface ---@type rtu_device
|
||||
local rtu_type ---@type RTU_UNIT_TYPE
|
||||
local is_multiblock = false ---@type boolean
|
||||
local formed = nil ---@type boolean|nil
|
||||
local faulted = nil ---@type boolean|nil
|
||||
@ -356,11 +354,11 @@ local function main()
|
||||
elseif type == "solarNeutronActivator" then
|
||||
-- SNA
|
||||
rtu_type = RTU_UNIT_TYPE.SNA
|
||||
rtu_iface, _ = sna_rtu.new(device)
|
||||
rtu_iface, faulted = sna_rtu.new(device)
|
||||
elseif type == "environmentDetector" then
|
||||
-- advanced peripherals environment detector
|
||||
rtu_type = RTU_UNIT_TYPE.ENV_DETECTOR
|
||||
rtu_iface, _ = envd_rtu.new(device)
|
||||
rtu_iface, faulted = envd_rtu.new(device)
|
||||
elseif type == ppm.VIRTUAL_DEVICE_TYPE then
|
||||
-- placeholder device
|
||||
rtu_type = RTU_UNIT_TYPE.VIRTUAL
|
||||
|
@ -17,9 +17,6 @@ local threads = {}
|
||||
|
||||
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
local print_ts = util.print_ts
|
||||
local println_ts = util.println_ts
|
||||
|
||||
local MAIN_CLOCK = 2 -- (2Hz, 40 ticks)
|
||||
|
@ -5,7 +5,6 @@
|
||||
local aes128 = require("lockbox.cipher.aes128")
|
||||
local ctr_mode = require("lockbox.cipher.mode.ctr")
|
||||
local sha1 = require("lockbox.digest.sha1")
|
||||
local sha2_224 = require("lockbox.digest.sha2_224")
|
||||
local sha2_256 = require("lockbox.digest.sha2_256")
|
||||
local pbkdf2 = require("lockbox.kdf.pbkdf2")
|
||||
local hmac = require("lockbox.mac.hmac")
|
||||
@ -157,10 +156,6 @@ end
|
||||
-- wrap a modem as a secure modem to send encrypted traffic
|
||||
---@param modem table modem to wrap
|
||||
function crypto.secure_modem(modem)
|
||||
local self = {
|
||||
modem = modem
|
||||
}
|
||||
|
||||
---@class secure_modem
|
||||
---@field open function
|
||||
---@field isOpen function
|
||||
@ -177,17 +172,17 @@ function crypto.secure_modem(modem)
|
||||
local public = {}
|
||||
|
||||
-- wrap a modem
|
||||
---@param modem table
|
||||
---@param reconnected_modem table
|
||||
---@diagnostic disable-next-line: redefined-local
|
||||
function public.wrap(modem)
|
||||
self.modem = modem
|
||||
for key, func in pairs(self.modem) do
|
||||
function public.wrap(reconnected_modem)
|
||||
modem = reconnected_modem
|
||||
for key, func in pairs(modem) do
|
||||
public[key] = func
|
||||
end
|
||||
end
|
||||
|
||||
-- wrap modem functions, then we replace transmit
|
||||
public.wrap(self.modem)
|
||||
public.wrap(modem)
|
||||
|
||||
-- send a packet with encryption
|
||||
---@param channel integer
|
||||
@ -198,9 +193,9 @@ function crypto.secure_modem(modem)
|
||||
|
||||
local iv, ciphertext = crypto.encrypt(plaintext)
|
||||
---@diagnostic disable-next-line: redefined-local
|
||||
local hmac = crypto.hmac(iv .. ciphertext)
|
||||
local computed_hmac = crypto.hmac(iv .. ciphertext)
|
||||
|
||||
self.modem.transmit(channel, reply_channel, { hmac, iv, ciphertext })
|
||||
modem.transmit(channel, reply_channel, { computed_hmac, iv, ciphertext })
|
||||
end
|
||||
|
||||
-- parse in a modem message as a network packet
|
||||
@ -217,13 +212,13 @@ function crypto.secure_modem(modem)
|
||||
if type(message) == "table" then
|
||||
if #message == 3 then
|
||||
---@diagnostic disable-next-line: redefined-local
|
||||
local hmac = message[1]
|
||||
local rx_hmac = message[1]
|
||||
local iv = message[2]
|
||||
local ciphertext = message[3]
|
||||
|
||||
local computed_hmac = crypto.hmac(iv .. ciphertext)
|
||||
|
||||
if hmac == computed_hmac then
|
||||
if rx_hmac == computed_hmac then
|
||||
-- message intact
|
||||
local plaintext = crypto.decrypt(iv, ciphertext)
|
||||
body = textutils.unserialize(plaintext)
|
||||
|
@ -7,7 +7,7 @@ local println_ts = util.println_ts
|
||||
|
||||
println("SCADA BOOTLOADER V" .. BOOTLOADER_VERSION)
|
||||
|
||||
local exit_code = false
|
||||
local exit_code ---@type boolean
|
||||
|
||||
println_ts("BOOT> SCANNING FOR APPLICATIONS...")
|
||||
|
||||
|
@ -16,16 +16,12 @@ local FAC_COMMAND = comms.FAC_COMMAND
|
||||
|
||||
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
||||
|
||||
local SV_Q_CMDS = svqtypes.SV_Q_CMDS
|
||||
local SV_Q_DATA = svqtypes.SV_Q_DATA
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
local print_ts = util.print_ts
|
||||
local println_ts = util.println_ts
|
||||
|
||||
-- retry time constants in ms
|
||||
local INITIAL_WAIT = 1500
|
||||
-- local INITIAL_WAIT = 1500
|
||||
local RETRY_PERIOD = 1000
|
||||
local PARTIAL_RETRY_PERIOD = 2000
|
||||
|
||||
@ -198,7 +194,7 @@ function coordinator.new_session(id, in_queue, out_queue, timeout, facility)
|
||||
-- keep alive reply
|
||||
if pkt.length == 2 then
|
||||
local srv_start = pkt.data[1]
|
||||
local coord_send = pkt.data[2]
|
||||
-- local coord_send = pkt.data[2]
|
||||
local srv_now = util.time()
|
||||
self.last_rtt = srv_now - srv_start
|
||||
|
||||
|
@ -14,10 +14,7 @@ local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE
|
||||
local PLC_AUTO_ACK = comms.PLC_AUTO_ACK
|
||||
local UNIT_COMMAND = comms.UNIT_COMMAND
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
local print_ts = util.print_ts
|
||||
local println_ts = util.println_ts
|
||||
|
||||
-- retry time constants in ms
|
||||
local INITIAL_WAIT = 1500
|
||||
@ -476,7 +473,7 @@ function plc.new_session(id, reactor_id, in_queue, out_queue, timeout)
|
||||
-- keep alive reply
|
||||
if pkt.length == 2 then
|
||||
local srv_start = pkt.data[1]
|
||||
local plc_send = pkt.data[2]
|
||||
-- local plc_send = pkt.data[2]
|
||||
local srv_now = util.time()
|
||||
self.last_rtt = srv_now - srv_start
|
||||
|
||||
|
@ -22,10 +22,7 @@ local PROTOCOL = comms.PROTOCOL
|
||||
local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE
|
||||
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
local print_ts = util.print_ts
|
||||
local println_ts = util.println_ts
|
||||
|
||||
local PERIODICS = {
|
||||
KEEP_ALIVE = 2000
|
||||
@ -78,9 +75,7 @@ function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facili
|
||||
end
|
||||
|
||||
for i = 1, #self.advert do
|
||||
local unit = nil ---@type unit_session|nil
|
||||
local rs_in_q = nil ---@type mqueue|nil
|
||||
local tbv_in_q = nil ---@type mqueue|nil
|
||||
local unit = nil ---@type unit_session|nil
|
||||
|
||||
---@type rtu_advertisement
|
||||
local unit_advert = {
|
||||
@ -242,7 +237,7 @@ function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facili
|
||||
-- keep alive reply
|
||||
if pkt.length == 2 then
|
||||
local srv_start = pkt.data[1]
|
||||
local rtu_send = pkt.data[2]
|
||||
-- local rtu_send = pkt.data[2]
|
||||
local srv_now = util.time()
|
||||
self.last_rtt = srv_now - srv_start
|
||||
|
||||
|
@ -12,7 +12,6 @@ local MODBUS_FCODE = types.MODBUS_FCODE
|
||||
|
||||
local IO_PORT = rsio.IO
|
||||
local IO_LVL = rsio.IO_LVL
|
||||
local IO_DIR = rsio.IO_DIR
|
||||
local IO_MODE = rsio.IO_MODE
|
||||
|
||||
local TXN_READY = -1
|
||||
|
@ -13,12 +13,10 @@ local rtu = require("supervisor.session.rtu")
|
||||
|
||||
-- Supervisor Sessions Handler
|
||||
|
||||
local SV_Q_CMDS = svqtypes.SV_Q_CMDS
|
||||
local SV_Q_DATA = svqtypes.SV_Q_DATA
|
||||
|
||||
local PLC_S_CMDS = plc.PLC_S_CMDS
|
||||
local PLC_S_DATA = plc.PLC_S_DATA
|
||||
local CRD_S_CMDS = coordinator.CRD_S_CMDS
|
||||
local CRD_S_DATA = coordinator.CRD_S_DATA
|
||||
|
||||
local svsessions = {}
|
||||
|
@ -14,11 +14,9 @@ local svsessions = require("supervisor.session.svsessions")
|
||||
local config = require("supervisor.config")
|
||||
local supervisor = require("supervisor.supervisor")
|
||||
|
||||
local SUPERVISOR_VERSION = "v0.14.3"
|
||||
local SUPERVISOR_VERSION = "v0.14.4"
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
local print_ts = util.print_ts
|
||||
local println_ts = util.println_ts
|
||||
|
||||
----------------------------------------
|
||||
|
@ -11,10 +11,7 @@ local DEVICE_TYPE = comms.DEVICE_TYPE
|
||||
local ESTABLISH_ACK = comms.ESTABLISH_ACK
|
||||
local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
local print_ts = util.print_ts
|
||||
local println_ts = util.println_ts
|
||||
|
||||
-- supervisory controller communications
|
||||
---@nodiscard
|
||||
|
@ -4,14 +4,14 @@ local pbkdf2 = require("lockbox.kdf.pbkdf2")
|
||||
local AES128Cipher = require("lockbox.cipher.aes128")
|
||||
local HMAC = require("lockbox.mac.hmac")
|
||||
local SHA1 = require("lockbox.digest.sha1")
|
||||
local SHA2_224 = require("lockbox.digest.sha2_224")
|
||||
-- local SHA2_224 = require("lockbox.digest.sha2_224")
|
||||
local SHA2_256 = require("lockbox.digest.sha2_256")
|
||||
local Stream = require("lockbox.util.stream")
|
||||
local Array = require("lockbox.util.array")
|
||||
|
||||
local CBCMode = require("lockbox.cipher.mode.cbc")
|
||||
local CFBMode = require("lockbox.cipher.mode.cfb")
|
||||
local OFBMode = require("lockbox.cipher.mode.ofb")
|
||||
-- local CBCMode = require("lockbox.cipher.mode.cbc")
|
||||
-- local CFBMode = require("lockbox.cipher.mode.cfb")
|
||||
-- local OFBMode = require("lockbox.cipher.mode.ofb")
|
||||
local CTRMode = require("lockbox.cipher.mode.ctr")
|
||||
|
||||
local ZeroPadding = require("lockbox.padding.zero")
|
||||
@ -35,6 +35,7 @@ util.println("pbkdf2: took " .. (util.time() - start) .. "ms")
|
||||
util.println(keyd.asHex())
|
||||
|
||||
local pkt = comms.modbus_packet()
|
||||
---@diagnostic disable-next-line: param-type-mismatch
|
||||
pkt.make(1, 2, 7, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
|
||||
local spkt = comms.scada_packet()
|
||||
spkt.make(1, 1, pkt.raw_sendable())
|
||||
|
@ -10,7 +10,6 @@ local println = util.println
|
||||
|
||||
local IO = rsio.IO
|
||||
local IO_LVL = rsio.IO_LVL
|
||||
local IO_DIR = rsio.IO_DIR
|
||||
local IO_MODE = rsio.IO_MODE
|
||||
|
||||
println("starting RSIO tester")
|
||||
|
Loading…
Reference in New Issue
Block a user