mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
added Luacheck GitHub action (#210)
* added shields.io elements * #209 luacheck action * #209 cleanup to pass luacheck * added check statuses to readme
This commit is contained in:
parent
3ae39b2455
commit
c987d14d8d
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
|
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -13,7 +13,6 @@
|
|||||||
"window",
|
"window",
|
||||||
"read",
|
"read",
|
||||||
"periphemu",
|
"periphemu",
|
||||||
"mekanismEnergyHelper",
|
|
||||||
"_HOST",
|
"_HOST",
|
||||||
"http"
|
"http"
|
||||||
],
|
],
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
# cc-mek-scada
|
# 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!
|
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 branch checks state](https://img.shields.io/github/checks-status/MikaylaFischler/cc-mek-scada/main?label=main)
|
||||||
|
![GitHub branch checks state](https://img.shields.io/github/checks-status/MikaylaFischler/cc-mek-scada/devel?label=devel)
|
||||||
|
|
||||||
Mod Requirements:
|
Mod Requirements:
|
||||||
- CC: Tweaked
|
- CC: Tweaked
|
||||||
- Mekanism v10.1+
|
- Mekanism v10.1+
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
local apisessions = {}
|
local apisessions = {}
|
||||||
|
|
||||||
---@param packet capi_frame
|
---@param packet capi_frame
|
||||||
|
---@diagnostic disable-next-line: unused-local
|
||||||
function apisessions.handle_packet(packet)
|
function apisessions.handle_packet(packet)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- attempt to identify which session's watchdog timer fired
|
-- attempt to identify which session's watchdog timer fired
|
||||||
---@param timer_event number
|
---@param timer_event number
|
||||||
|
---@diagnostic disable-next-line: unused-local
|
||||||
function apisessions.check_all_watchdogs(timer_event)
|
function apisessions.check_all_watchdogs(timer_event)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ local dialog = require("coordinator.ui.dialog")
|
|||||||
|
|
||||||
local print = util.print
|
local print = util.print
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local print_ts = util.print_ts
|
|
||||||
local println_ts = util.println_ts
|
local println_ts = util.println_ts
|
||||||
|
|
||||||
local PROTOCOL = comms.PROTOCOL
|
local PROTOCOL = comms.PROTOCOL
|
||||||
@ -246,7 +245,7 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, range
|
|||||||
---@param msg table
|
---@param msg table
|
||||||
local function _send_sv(protocol, msg_type, msg)
|
local function _send_sv(protocol, msg_type, msg)
|
||||||
local s_pkt = comms.scada_packet()
|
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
|
if protocol == PROTOCOL.SCADA_MGMT then
|
||||||
pkt = comms.mgmt_packet()
|
pkt = comms.mgmt_packet()
|
||||||
|
@ -657,8 +657,8 @@ function iocontrol.update_unit_statuses(statuses)
|
|||||||
if type(rtu_statuses.rad_mon) == "table" then
|
if type(rtu_statuses.rad_mon) == "table" then
|
||||||
if #rtu_statuses.rad_mon > 0 then
|
if #rtu_statuses.rad_mon > 0 then
|
||||||
local rad_mon = rtu_statuses.rad_mon[1]
|
local rad_mon = rtu_statuses.rad_mon[1]
|
||||||
local rtu_faulted = rad_mon[1] ---@type boolean
|
-- local rtu_faulted = rad_mon[1] ---@type boolean
|
||||||
unit.radiation = rad_mon[2] ---@type number
|
unit.radiation = rad_mon[2] ---@type number
|
||||||
|
|
||||||
unit.unit_ps.publish("radiation", unit.radiation)
|
unit.unit_ps.publish("radiation", unit.radiation)
|
||||||
else
|
else
|
||||||
|
@ -12,10 +12,11 @@ local ALARM_STATE = types.ALARM_STATE
|
|||||||
---@class sounder
|
---@class sounder
|
||||||
local sounder = {}
|
local sounder = {}
|
||||||
|
|
||||||
|
-- note: max samples = 0x20000 (128 * 1024 samples)
|
||||||
|
|
||||||
local _2_PI = 2 * math.pi -- 2 whole pies, hope you're hungry
|
local _2_PI = 2 * math.pi -- 2 whole pies, hope you're hungry
|
||||||
local _DRATE = 48000 -- 48kHz audio
|
local _DRATE = 48000 -- 48kHz audio
|
||||||
local _MAX_VAL = 127 / 2 -- max signed integer in this 8-bit 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 _05s_SAMPLES = 24000 -- half a second worth of samples
|
||||||
|
|
||||||
local test_alarms = { false, false, false, false, false, false, false, false, false, false, false, false }
|
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 COORDINATOR_VERSION = "v0.12.6"
|
||||||
|
|
||||||
local print = util.print
|
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local print_ts = util.print_ts
|
|
||||||
local println_ts = util.println_ts
|
local println_ts = util.println_ts
|
||||||
|
|
||||||
local log_graphics = coordinator.log_graphics
|
local log_graphics = coordinator.log_graphics
|
||||||
@ -287,7 +285,7 @@ local function main()
|
|||||||
else
|
else
|
||||||
log_sys("wired modem reconnected")
|
log_sys("wired modem reconnected")
|
||||||
end
|
end
|
||||||
elseif type == "monitor" then
|
-- elseif type == "monitor" then
|
||||||
-- not supported, system will exit on loss of in-use monitors
|
-- not supported, system will exit on loss of in-use monitors
|
||||||
elseif type == "speaker" then
|
elseif type == "speaker" then
|
||||||
local msg = "alarm sounder speaker reconnected"
|
local msg = "alarm sounder speaker reconnected"
|
||||||
|
@ -18,9 +18,8 @@ local border = core.graphics.border
|
|||||||
---@param root graphics_element parent
|
---@param root graphics_element parent
|
||||||
---@param x integer top left x
|
---@param x integer top left x
|
||||||
---@param y integer top left y
|
---@param y integer top left y
|
||||||
---@param data reactor_db reactor data
|
|
||||||
---@param ps psil ps interface
|
---@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 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)
|
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 y integer top left y
|
||||||
---@param unit ioctl_unit unit database entry
|
---@param unit ioctl_unit unit database entry
|
||||||
local function make(parent, x, y, unit)
|
local function make(parent, x, y, unit)
|
||||||
local height = 0
|
|
||||||
local num_boilers = #unit.boiler_data_tbl
|
local num_boilers = #unit.boiler_data_tbl
|
||||||
local num_turbines = #unit.turbine_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_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")
|
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
|
if num_boilers == 0 and num_turbines == 1 then
|
||||||
height = 9
|
height = 9
|
||||||
elseif num_boilers == 1 and num_turbines <= 2 then
|
elseif num_boilers == 1 and num_turbines <= 2 then
|
||||||
height = 17
|
height = 17
|
||||||
else
|
|
||||||
height = 25
|
|
||||||
end
|
end
|
||||||
|
|
||||||
assert(parent.height() >= (y + height), "main display not of sufficient vertical resolution (add an additional row of monitors)")
|
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 --
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
reactor_view(root, 1, 3, unit.reactor_data, unit.unit_ps)
|
reactor_view(root, 1, 3, unit.unit_ps)
|
||||||
|
|
||||||
if num_boilers > 0 then
|
if num_boilers > 0 then
|
||||||
local coolant_pipes = {}
|
local coolant_pipes = {}
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
local util = require("scada-common.util")
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
local iocontrol = require("coordinator.iocontrol")
|
local iocontrol = require("coordinator.iocontrol")
|
||||||
local sounder = require("coordinator.sounder")
|
|
||||||
|
|
||||||
local style = require("coordinator.ui.style")
|
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 core = require("graphics.core")
|
||||||
|
|
||||||
local ColorMap = require("graphics.elements.colormap")
|
|
||||||
local DisplayBox = require("graphics.elements.displaybox")
|
local DisplayBox = require("graphics.elements.displaybox")
|
||||||
local Div = require("graphics.elements.div")
|
|
||||||
local TextBox = require("graphics.elements.textbox")
|
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 DataIndicator = require("graphics.elements.indicators.data")
|
||||||
|
|
||||||
local TEXT_ALIGN = core.graphics.TEXT_ALIGN
|
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(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")
|
assert(util.is_int(fr_prec), "graphics.element.controls.spinbox_numeric: fractional precision must be an integer")
|
||||||
|
|
||||||
local fmt = ""
|
local fmt, fmt_init ---@type string, string
|
||||||
local fmt_init = ""
|
|
||||||
|
|
||||||
if fr_prec > 0 then
|
if fr_prec > 0 then
|
||||||
fmt = "%" .. (wn_prec + fr_prec + 1) .. "." .. fr_prec .. "f"
|
fmt = "%" .. (wn_prec + fr_prec + 1) .. "." .. fr_prec .. "f"
|
||||||
|
@ -73,7 +73,7 @@ local function core_map(args)
|
|||||||
local function draw_core(t)
|
local function draw_core(t)
|
||||||
local i = 1
|
local i = 1
|
||||||
local back_c = "F"
|
local back_c = "F"
|
||||||
local text_c = "8"
|
local text_c ---@type string
|
||||||
|
|
||||||
-- determine fuel assembly coloring
|
-- determine fuel assembly coloring
|
||||||
if t <= 300 then
|
if t <= 300 then
|
||||||
|
@ -38,7 +38,7 @@ local function indicator_led_rgb(args)
|
|||||||
e.value = new_state
|
e.value = new_state
|
||||||
e.window.setCursorPos(1, 1)
|
e.window.setCursorPos(1, 1)
|
||||||
if type(args.colors[new_state]) == "number" then
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -6,11 +6,11 @@ require("/initenv").init_env()
|
|||||||
|
|
||||||
local util = require("scada-common.util")
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
local POCKET_VERSION = "alpha-v0.0.0"
|
-- local POCKET_VERSION = "alpha-v0.0.0"
|
||||||
|
|
||||||
local print = util.print
|
-- local print = util.print
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local print_ts = util.print_ts
|
-- local print_ts = util.print_ts
|
||||||
local println_ts = util.println_ts
|
-- local println_ts = util.println_ts
|
||||||
|
|
||||||
println("Sorry, this isn't written yet :(")
|
println("Sorry, this isn't written yet :(")
|
||||||
|
@ -68,11 +68,6 @@ function plc.rps_init(reactor, is_formed, emer_cool)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- clear reactor access fault flag
|
|
||||||
local function _clear_fault()
|
|
||||||
self.state[state_keys.fault] = false
|
|
||||||
end
|
|
||||||
|
|
||||||
-- set emergency coolant control (if configured)
|
-- set emergency coolant control (if configured)
|
||||||
---@param state boolean true to enable emergency coolant, false to disable
|
---@param state boolean true to enable emergency coolant, false to disable
|
||||||
local function _set_emer_cool(state)
|
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
|
---@param setpoints setpoints setpoint control table
|
||||||
function public.handle_packet(packet, plc_state, setpoints)
|
function public.handle_packet(packet, plc_state, setpoints)
|
||||||
-- print a log message to the terminal as long as the UI isn't running
|
-- 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
|
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
|
-- 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 R_PLC_VERSION = "v1.1.5"
|
||||||
|
|
||||||
local print = util.print
|
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local print_ts = util.print_ts
|
|
||||||
local println_ts = util.println_ts
|
local println_ts = util.println_ts
|
||||||
|
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
@ -176,8 +174,9 @@ local function main()
|
|||||||
|
|
||||||
-- front panel time!
|
-- front panel time!
|
||||||
if not renderer.ui_ready() then
|
if not renderer.ui_ready() then
|
||||||
local message = nil
|
local message
|
||||||
plc_state.fp_ok, message = pcall(renderer.start_ui)
|
plc_state.fp_ok, message = pcall(renderer.start_ui)
|
||||||
|
|
||||||
if not plc_state.fp_ok then
|
if not plc_state.fp_ok then
|
||||||
renderer.close_ui()
|
renderer.close_ui()
|
||||||
println_ts(util.c("UI error: ", message))
|
println_ts(util.c("UI error: ", message))
|
||||||
|
@ -34,7 +34,6 @@ local MQ__COMM_CMD = {
|
|||||||
---@param init function
|
---@param init function
|
||||||
function threads.thread__main(smem, init)
|
function threads.thread__main(smem, init)
|
||||||
-- print a log message to the terminal as long as the UI isn't running
|
-- 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
|
local function println_ts(message) if not smem.plc_state.fp_ok then util.println_ts(message) end end
|
||||||
|
|
||||||
---@class parallel_thread
|
---@class parallel_thread
|
||||||
@ -307,7 +306,6 @@ end
|
|||||||
---@param smem plc_shared_memory
|
---@param smem plc_shared_memory
|
||||||
function threads.thread__rps(smem)
|
function threads.thread__rps(smem)
|
||||||
-- print a log message to the terminal as long as the UI isn't running
|
-- 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
|
local function println_ts(message) if not smem.plc_state.fp_ok then util.println_ts(message) end end
|
||||||
|
|
||||||
---@class parallel_thread
|
---@class parallel_thread
|
||||||
@ -682,7 +680,7 @@ function threads.thread__setpoint_control(smem)
|
|||||||
-- we yielded, check enable again
|
-- we yielded, check enable again
|
||||||
if setpoints.burn_rate_en and (type(current_burn_rate) == "number") and (current_burn_rate ~= setpoints.burn_rate) then
|
if setpoints.burn_rate_en and (type(current_burn_rate) == "number") and (current_burn_rate ~= setpoints.burn_rate) then
|
||||||
-- calculate new burn rate
|
-- 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
|
if setpoints.burn_rate > current_burn_rate then
|
||||||
-- need to ramp up
|
-- need to ramp up
|
||||||
|
@ -34,7 +34,7 @@ function redstone_rtu.new()
|
|||||||
---@param side string
|
---@param side string
|
||||||
---@param color integer
|
---@param color integer
|
||||||
function public.link_di(side, color)
|
function public.link_di(side, color)
|
||||||
local f_read = nil
|
local f_read ---@type function
|
||||||
|
|
||||||
if color then
|
if color then
|
||||||
f_read = function ()
|
f_read = function ()
|
||||||
@ -53,8 +53,8 @@ function redstone_rtu.new()
|
|||||||
---@param side string
|
---@param side string
|
||||||
---@param color integer
|
---@param color integer
|
||||||
function public.link_do(side, color)
|
function public.link_do(side, color)
|
||||||
local f_read = nil
|
local f_read ---@type function
|
||||||
local f_write = nil
|
local f_write ---@type function
|
||||||
|
|
||||||
if color then
|
if color then
|
||||||
f_read = function ()
|
f_read = function ()
|
||||||
|
@ -347,11 +347,9 @@ function modbus.new(rtu_dev, use_parallel_read)
|
|||||||
response = { MODBUS_EXCODE.NEG_ACKNOWLEDGE }
|
response = { MODBUS_EXCODE.NEG_ACKNOWLEDGE }
|
||||||
end
|
end
|
||||||
|
|
||||||
-- default is to echo back
|
-- default is to echo back<br>
|
||||||
local func_code = packet.func_code
|
-- 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)
|
||||||
-- echo back with error flag, on success the "error" will be acknowledgement
|
|
||||||
func_code = bit.bor(packet.func_code, MODBUS_FCODE.ERROR_FLAG)
|
|
||||||
|
|
||||||
-- create reply
|
-- create reply
|
||||||
local reply = comms.modbus_packet()
|
local reply = comms.modbus_packet()
|
||||||
@ -365,8 +363,8 @@ function modbus.new(rtu_dev, use_parallel_read)
|
|||||||
---@param packet modbus_frame
|
---@param packet modbus_frame
|
||||||
---@return boolean return_code, modbus_packet reply
|
---@return boolean return_code, modbus_packet reply
|
||||||
function public.handle_packet(packet)
|
function public.handle_packet(packet)
|
||||||
local return_code = true
|
local return_code ---@type boolean
|
||||||
local response = nil
|
local response ---@type table|MODBUS_EXCODE
|
||||||
|
|
||||||
if packet.length >= 2 then
|
if packet.length >= 2 then
|
||||||
-- handle by function code
|
-- handle by function code
|
||||||
|
@ -14,9 +14,6 @@ local ESTABLISH_ACK = comms.ESTABLISH_ACK
|
|||||||
local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE
|
local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE
|
||||||
local RTU_UNIT_TYPE = types.RTU_UNIT_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 println_ts = util.println_ts
|
||||||
|
|
||||||
-- create a new RTU unit
|
-- 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
|
if protocol == PROTOCOL.MODBUS_TCP then
|
||||||
---@cast packet modbus_frame
|
---@cast packet modbus_frame
|
||||||
if rtu_state.linked then
|
if rtu_state.linked then
|
||||||
local return_code = false
|
local return_code ---@type boolean
|
||||||
local reply = modbus.reply__neg_ack(packet)
|
local reply ---@type modbus_packet
|
||||||
|
|
||||||
-- handle MODBUS instruction
|
-- handle MODBUS instruction
|
||||||
if packet.unit_id <= #units then
|
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 sps_rtu = require("rtu.dev.sps_rtu")
|
||||||
local turbinev_rtu = require("rtu.dev.turbinev_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 RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
||||||
|
|
||||||
local print = util.print
|
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local print_ts = util.print_ts
|
|
||||||
local println_ts = util.println_ts
|
local println_ts = util.println_ts
|
||||||
|
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
@ -287,9 +285,9 @@ local function main()
|
|||||||
|
|
||||||
local device = ppm.get_periph(name)
|
local device = ppm.get_periph(name)
|
||||||
|
|
||||||
local type = nil ---@type string|nil
|
local type ---@type string|nil
|
||||||
local rtu_iface = nil ---@type rtu_device
|
local rtu_iface ---@type rtu_device
|
||||||
local rtu_type = nil ---@type RTU_UNIT_TYPE
|
local rtu_type ---@type RTU_UNIT_TYPE
|
||||||
local is_multiblock = false ---@type boolean
|
local is_multiblock = false ---@type boolean
|
||||||
local formed = nil ---@type boolean|nil
|
local formed = nil ---@type boolean|nil
|
||||||
local faulted = nil ---@type boolean|nil
|
local faulted = nil ---@type boolean|nil
|
||||||
@ -356,11 +354,11 @@ local function main()
|
|||||||
elseif type == "solarNeutronActivator" then
|
elseif type == "solarNeutronActivator" then
|
||||||
-- SNA
|
-- SNA
|
||||||
rtu_type = RTU_UNIT_TYPE.SNA
|
rtu_type = RTU_UNIT_TYPE.SNA
|
||||||
rtu_iface, _ = sna_rtu.new(device)
|
rtu_iface, faulted = sna_rtu.new(device)
|
||||||
elseif type == "environmentDetector" then
|
elseif type == "environmentDetector" then
|
||||||
-- advanced peripherals environment detector
|
-- advanced peripherals environment detector
|
||||||
rtu_type = RTU_UNIT_TYPE.ENV_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
|
elseif type == ppm.VIRTUAL_DEVICE_TYPE then
|
||||||
-- placeholder device
|
-- placeholder device
|
||||||
rtu_type = RTU_UNIT_TYPE.VIRTUAL
|
rtu_type = RTU_UNIT_TYPE.VIRTUAL
|
||||||
|
@ -17,9 +17,6 @@ local threads = {}
|
|||||||
|
|
||||||
local RTU_UNIT_TYPE = types.RTU_UNIT_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 println_ts = util.println_ts
|
||||||
|
|
||||||
local MAIN_CLOCK = 2 -- (2Hz, 40 ticks)
|
local MAIN_CLOCK = 2 -- (2Hz, 40 ticks)
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
local aes128 = require("lockbox.cipher.aes128")
|
local aes128 = require("lockbox.cipher.aes128")
|
||||||
local ctr_mode = require("lockbox.cipher.mode.ctr")
|
local ctr_mode = require("lockbox.cipher.mode.ctr")
|
||||||
local sha1 = require("lockbox.digest.sha1")
|
local sha1 = require("lockbox.digest.sha1")
|
||||||
local sha2_224 = require("lockbox.digest.sha2_224")
|
|
||||||
local sha2_256 = require("lockbox.digest.sha2_256")
|
local sha2_256 = require("lockbox.digest.sha2_256")
|
||||||
local pbkdf2 = require("lockbox.kdf.pbkdf2")
|
local pbkdf2 = require("lockbox.kdf.pbkdf2")
|
||||||
local hmac = require("lockbox.mac.hmac")
|
local hmac = require("lockbox.mac.hmac")
|
||||||
@ -157,10 +156,6 @@ end
|
|||||||
-- wrap a modem as a secure modem to send encrypted traffic
|
-- wrap a modem as a secure modem to send encrypted traffic
|
||||||
---@param modem table modem to wrap
|
---@param modem table modem to wrap
|
||||||
function crypto.secure_modem(modem)
|
function crypto.secure_modem(modem)
|
||||||
local self = {
|
|
||||||
modem = modem
|
|
||||||
}
|
|
||||||
|
|
||||||
---@class secure_modem
|
---@class secure_modem
|
||||||
---@field open function
|
---@field open function
|
||||||
---@field isOpen function
|
---@field isOpen function
|
||||||
@ -177,17 +172,17 @@ function crypto.secure_modem(modem)
|
|||||||
local public = {}
|
local public = {}
|
||||||
|
|
||||||
-- wrap a modem
|
-- wrap a modem
|
||||||
---@param modem table
|
---@param reconnected_modem table
|
||||||
---@diagnostic disable-next-line: redefined-local
|
---@diagnostic disable-next-line: redefined-local
|
||||||
function public.wrap(modem)
|
function public.wrap(reconnected_modem)
|
||||||
self.modem = modem
|
modem = reconnected_modem
|
||||||
for key, func in pairs(self.modem) do
|
for key, func in pairs(modem) do
|
||||||
public[key] = func
|
public[key] = func
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- wrap modem functions, then we replace transmit
|
-- wrap modem functions, then we replace transmit
|
||||||
public.wrap(self.modem)
|
public.wrap(modem)
|
||||||
|
|
||||||
-- send a packet with encryption
|
-- send a packet with encryption
|
||||||
---@param channel integer
|
---@param channel integer
|
||||||
@ -198,9 +193,9 @@ function crypto.secure_modem(modem)
|
|||||||
|
|
||||||
local iv, ciphertext = crypto.encrypt(plaintext)
|
local iv, ciphertext = crypto.encrypt(plaintext)
|
||||||
---@diagnostic disable-next-line: redefined-local
|
---@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
|
end
|
||||||
|
|
||||||
-- parse in a modem message as a network packet
|
-- parse in a modem message as a network packet
|
||||||
@ -217,13 +212,13 @@ function crypto.secure_modem(modem)
|
|||||||
if type(message) == "table" then
|
if type(message) == "table" then
|
||||||
if #message == 3 then
|
if #message == 3 then
|
||||||
---@diagnostic disable-next-line: redefined-local
|
---@diagnostic disable-next-line: redefined-local
|
||||||
local hmac = message[1]
|
local rx_hmac = message[1]
|
||||||
local iv = message[2]
|
local iv = message[2]
|
||||||
local ciphertext = message[3]
|
local ciphertext = message[3]
|
||||||
|
|
||||||
local computed_hmac = crypto.hmac(iv .. ciphertext)
|
local computed_hmac = crypto.hmac(iv .. ciphertext)
|
||||||
|
|
||||||
if hmac == computed_hmac then
|
if rx_hmac == computed_hmac then
|
||||||
-- message intact
|
-- message intact
|
||||||
local plaintext = crypto.decrypt(iv, ciphertext)
|
local plaintext = crypto.decrypt(iv, ciphertext)
|
||||||
body = textutils.unserialize(plaintext)
|
body = textutils.unserialize(plaintext)
|
||||||
|
@ -7,7 +7,7 @@ local println_ts = util.println_ts
|
|||||||
|
|
||||||
println("SCADA BOOTLOADER V" .. BOOTLOADER_VERSION)
|
println("SCADA BOOTLOADER V" .. BOOTLOADER_VERSION)
|
||||||
|
|
||||||
local exit_code = false
|
local exit_code ---@type boolean
|
||||||
|
|
||||||
println_ts("BOOT> SCANNING FOR APPLICATIONS...")
|
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 RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
||||||
|
|
||||||
local SV_Q_CMDS = svqtypes.SV_Q_CMDS
|
|
||||||
local SV_Q_DATA = svqtypes.SV_Q_DATA
|
local SV_Q_DATA = svqtypes.SV_Q_DATA
|
||||||
|
|
||||||
local print = util.print
|
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local print_ts = util.print_ts
|
|
||||||
local println_ts = util.println_ts
|
|
||||||
|
|
||||||
-- 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
|
||||||
local PARTIAL_RETRY_PERIOD = 2000
|
local PARTIAL_RETRY_PERIOD = 2000
|
||||||
|
|
||||||
@ -198,7 +194,7 @@ function coordinator.new_session(id, in_queue, out_queue, timeout, facility)
|
|||||||
-- keep alive reply
|
-- keep alive reply
|
||||||
if pkt.length == 2 then
|
if pkt.length == 2 then
|
||||||
local srv_start = pkt.data[1]
|
local srv_start = pkt.data[1]
|
||||||
local coord_send = pkt.data[2]
|
-- local coord_send = pkt.data[2]
|
||||||
local srv_now = util.time()
|
local srv_now = util.time()
|
||||||
self.last_rtt = srv_now - srv_start
|
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 PLC_AUTO_ACK = comms.PLC_AUTO_ACK
|
||||||
local UNIT_COMMAND = comms.UNIT_COMMAND
|
local UNIT_COMMAND = comms.UNIT_COMMAND
|
||||||
|
|
||||||
local print = util.print
|
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local print_ts = util.print_ts
|
|
||||||
local println_ts = util.println_ts
|
|
||||||
|
|
||||||
-- retry time constants in ms
|
-- retry time constants in ms
|
||||||
local INITIAL_WAIT = 1500
|
local INITIAL_WAIT = 1500
|
||||||
@ -476,7 +473,7 @@ function plc.new_session(id, reactor_id, in_queue, out_queue, timeout)
|
|||||||
-- keep alive reply
|
-- keep alive reply
|
||||||
if pkt.length == 2 then
|
if pkt.length == 2 then
|
||||||
local srv_start = pkt.data[1]
|
local srv_start = pkt.data[1]
|
||||||
local plc_send = pkt.data[2]
|
-- local plc_send = pkt.data[2]
|
||||||
local srv_now = util.time()
|
local srv_now = util.time()
|
||||||
self.last_rtt = srv_now - srv_start
|
self.last_rtt = srv_now - srv_start
|
||||||
|
|
||||||
|
@ -22,10 +22,7 @@ local PROTOCOL = comms.PROTOCOL
|
|||||||
local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE
|
local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE
|
||||||
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
||||||
|
|
||||||
local print = util.print
|
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local print_ts = util.print_ts
|
|
||||||
local println_ts = util.println_ts
|
|
||||||
|
|
||||||
local PERIODICS = {
|
local PERIODICS = {
|
||||||
KEEP_ALIVE = 2000
|
KEEP_ALIVE = 2000
|
||||||
@ -78,9 +75,7 @@ function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facili
|
|||||||
end
|
end
|
||||||
|
|
||||||
for i = 1, #self.advert do
|
for i = 1, #self.advert do
|
||||||
local unit = nil ---@type unit_session|nil
|
local unit = nil ---@type unit_session|nil
|
||||||
local rs_in_q = nil ---@type mqueue|nil
|
|
||||||
local tbv_in_q = nil ---@type mqueue|nil
|
|
||||||
|
|
||||||
---@type rtu_advertisement
|
---@type rtu_advertisement
|
||||||
local unit_advert = {
|
local unit_advert = {
|
||||||
@ -242,7 +237,7 @@ function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facili
|
|||||||
-- keep alive reply
|
-- keep alive reply
|
||||||
if pkt.length == 2 then
|
if pkt.length == 2 then
|
||||||
local srv_start = pkt.data[1]
|
local srv_start = pkt.data[1]
|
||||||
local rtu_send = pkt.data[2]
|
-- local rtu_send = pkt.data[2]
|
||||||
local srv_now = util.time()
|
local srv_now = util.time()
|
||||||
self.last_rtt = srv_now - srv_start
|
self.last_rtt = srv_now - srv_start
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ local MODBUS_FCODE = types.MODBUS_FCODE
|
|||||||
|
|
||||||
local IO_PORT = rsio.IO
|
local IO_PORT = rsio.IO
|
||||||
local IO_LVL = rsio.IO_LVL
|
local IO_LVL = rsio.IO_LVL
|
||||||
local IO_DIR = rsio.IO_DIR
|
|
||||||
local IO_MODE = rsio.IO_MODE
|
local IO_MODE = rsio.IO_MODE
|
||||||
|
|
||||||
local TXN_READY = -1
|
local TXN_READY = -1
|
||||||
|
@ -13,12 +13,10 @@ local rtu = require("supervisor.session.rtu")
|
|||||||
|
|
||||||
-- Supervisor Sessions Handler
|
-- Supervisor Sessions Handler
|
||||||
|
|
||||||
local SV_Q_CMDS = svqtypes.SV_Q_CMDS
|
|
||||||
local SV_Q_DATA = svqtypes.SV_Q_DATA
|
local SV_Q_DATA = svqtypes.SV_Q_DATA
|
||||||
|
|
||||||
local PLC_S_CMDS = plc.PLC_S_CMDS
|
local PLC_S_CMDS = plc.PLC_S_CMDS
|
||||||
local PLC_S_DATA = plc.PLC_S_DATA
|
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 CRD_S_DATA = coordinator.CRD_S_DATA
|
||||||
|
|
||||||
local svsessions = {}
|
local svsessions = {}
|
||||||
|
@ -14,11 +14,9 @@ local svsessions = require("supervisor.session.svsessions")
|
|||||||
local config = require("supervisor.config")
|
local config = require("supervisor.config")
|
||||||
local supervisor = require("supervisor.supervisor")
|
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 println = util.println
|
||||||
local print_ts = util.print_ts
|
|
||||||
local println_ts = util.println_ts
|
local println_ts = util.println_ts
|
||||||
|
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
|
@ -11,10 +11,7 @@ local DEVICE_TYPE = comms.DEVICE_TYPE
|
|||||||
local ESTABLISH_ACK = comms.ESTABLISH_ACK
|
local ESTABLISH_ACK = comms.ESTABLISH_ACK
|
||||||
local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE
|
local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE
|
||||||
|
|
||||||
local print = util.print
|
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local print_ts = util.print_ts
|
|
||||||
local println_ts = util.println_ts
|
|
||||||
|
|
||||||
-- supervisory controller communications
|
-- supervisory controller communications
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
|
@ -4,14 +4,14 @@ local pbkdf2 = require("lockbox.kdf.pbkdf2")
|
|||||||
local AES128Cipher = require("lockbox.cipher.aes128")
|
local AES128Cipher = require("lockbox.cipher.aes128")
|
||||||
local HMAC = require("lockbox.mac.hmac")
|
local HMAC = require("lockbox.mac.hmac")
|
||||||
local SHA1 = require("lockbox.digest.sha1")
|
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 SHA2_256 = require("lockbox.digest.sha2_256")
|
||||||
local Stream = require("lockbox.util.stream")
|
local Stream = require("lockbox.util.stream")
|
||||||
local Array = require("lockbox.util.array")
|
local Array = require("lockbox.util.array")
|
||||||
|
|
||||||
local CBCMode = require("lockbox.cipher.mode.cbc")
|
-- local CBCMode = require("lockbox.cipher.mode.cbc")
|
||||||
local CFBMode = require("lockbox.cipher.mode.cfb")
|
-- local CFBMode = require("lockbox.cipher.mode.cfb")
|
||||||
local OFBMode = require("lockbox.cipher.mode.ofb")
|
-- local OFBMode = require("lockbox.cipher.mode.ofb")
|
||||||
local CTRMode = require("lockbox.cipher.mode.ctr")
|
local CTRMode = require("lockbox.cipher.mode.ctr")
|
||||||
|
|
||||||
local ZeroPadding = require("lockbox.padding.zero")
|
local ZeroPadding = require("lockbox.padding.zero")
|
||||||
@ -35,6 +35,7 @@ util.println("pbkdf2: took " .. (util.time() - start) .. "ms")
|
|||||||
util.println(keyd.asHex())
|
util.println(keyd.asHex())
|
||||||
|
|
||||||
local pkt = comms.modbus_packet()
|
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})
|
pkt.make(1, 2, 7, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
|
||||||
local spkt = comms.scada_packet()
|
local spkt = comms.scada_packet()
|
||||||
spkt.make(1, 1, pkt.raw_sendable())
|
spkt.make(1, 1, pkt.raw_sendable())
|
||||||
|
@ -10,7 +10,6 @@ local println = util.println
|
|||||||
|
|
||||||
local IO = rsio.IO
|
local IO = rsio.IO
|
||||||
local IO_LVL = rsio.IO_LVL
|
local IO_LVL = rsio.IO_LVL
|
||||||
local IO_DIR = rsio.IO_DIR
|
|
||||||
local IO_MODE = rsio.IO_MODE
|
local IO_MODE = rsio.IO_MODE
|
||||||
|
|
||||||
println("starting RSIO tester")
|
println("starting RSIO tester")
|
||||||
|
Loading…
Reference in New Issue
Block a user