#47 scada-common doc comments
This commit is contained in:
parent
6e1ece8183
commit
3c688bfafa
@ -1,7 +1,9 @@
|
|||||||
local util = require("scada-common.util")
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
|
---@class alarm
|
||||||
local alarm = {}
|
local alarm = {}
|
||||||
|
|
||||||
|
---@alias SEVERITY integer
|
||||||
SEVERITY = {
|
SEVERITY = {
|
||||||
INFO = 0, -- basic info message
|
INFO = 0, -- basic info message
|
||||||
WARNING = 1, -- warning about some abnormal state
|
WARNING = 1, -- warning about some abnormal state
|
||||||
@ -13,6 +15,8 @@ SEVERITY = {
|
|||||||
|
|
||||||
alarm.SEVERITY = SEVERITY
|
alarm.SEVERITY = SEVERITY
|
||||||
|
|
||||||
|
-- severity integer to string
|
||||||
|
---@param severity SEVERITY
|
||||||
alarm.severity_to_string = function (severity)
|
alarm.severity_to_string = function (severity)
|
||||||
if severity == SEVERITY.INFO then
|
if severity == SEVERITY.INFO then
|
||||||
return "INFO"
|
return "INFO"
|
||||||
@ -31,6 +35,10 @@ alarm.severity_to_string = function (severity)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- create a new scada alarm entry
|
||||||
|
---@param severity SEVERITY
|
||||||
|
---@param device string
|
||||||
|
---@param message string
|
||||||
alarm.scada_alarm = function (severity, device, message)
|
alarm.scada_alarm = function (severity, device, message)
|
||||||
local self = {
|
local self = {
|
||||||
time = util.time(),
|
time = util.time(),
|
||||||
@ -40,11 +48,17 @@ alarm.scada_alarm = function (severity, device, message)
|
|||||||
message = message
|
message = message
|
||||||
}
|
}
|
||||||
|
|
||||||
local format = function ()
|
---@class scada_alarm
|
||||||
|
local public = {}
|
||||||
|
|
||||||
|
-- format the alarm as a string
|
||||||
|
---@return string message
|
||||||
|
public.format = function ()
|
||||||
return self.ts_string .. " [" .. alarm.severity_to_string(self.severity) .. "] (" .. self.device ") >> " .. self.message
|
return self.ts_string .. " [" .. alarm.severity_to_string(self.severity) .. "] (" .. self.device ") >> " .. self.message
|
||||||
end
|
end
|
||||||
|
|
||||||
local properties = function ()
|
-- get alarm properties
|
||||||
|
public.properties = function ()
|
||||||
return {
|
return {
|
||||||
time = self.time,
|
time = self.time,
|
||||||
severity = self.severity,
|
severity = self.severity,
|
||||||
@ -53,10 +67,7 @@ alarm.scada_alarm = function (severity, device, message)
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return public
|
||||||
format = format,
|
|
||||||
properties = properties
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return alarm
|
return alarm
|
||||||
|
|||||||
@ -5,11 +5,13 @@
|
|||||||
local log = require("scada-common.log")
|
local log = require("scada-common.log")
|
||||||
local types = require("scada-common.types")
|
local types = require("scada-common.types")
|
||||||
|
|
||||||
|
---@class comms
|
||||||
local comms = {}
|
local comms = {}
|
||||||
|
|
||||||
local rtu_t = types.rtu_t
|
local rtu_t = types.rtu_t
|
||||||
local insert = table.insert
|
local insert = table.insert
|
||||||
|
|
||||||
|
---@alias PROTOCOLS integer
|
||||||
local PROTOCOLS = {
|
local PROTOCOLS = {
|
||||||
MODBUS_TCP = 0, -- our "MODBUS TCP"-esque protocol
|
MODBUS_TCP = 0, -- our "MODBUS TCP"-esque protocol
|
||||||
RPLC = 1, -- reactor PLC protocol
|
RPLC = 1, -- reactor PLC protocol
|
||||||
@ -18,6 +20,7 @@ local PROTOCOLS = {
|
|||||||
COORD_API = 4 -- data/control packets for pocket computers to/from coordinators
|
COORD_API = 4 -- data/control packets for pocket computers to/from coordinators
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@alias RPLC_TYPES integer
|
||||||
local RPLC_TYPES = {
|
local RPLC_TYPES = {
|
||||||
LINK_REQ = 0, -- linking requests
|
LINK_REQ = 0, -- linking requests
|
||||||
STATUS = 1, -- reactor/system status
|
STATUS = 1, -- reactor/system status
|
||||||
@ -30,12 +33,14 @@ local RPLC_TYPES = {
|
|||||||
RPS_RESET = 8 -- clear RPS trip (if in bad state, will trip immediately)
|
RPS_RESET = 8 -- clear RPS trip (if in bad state, will trip immediately)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@alias RPLC_LINKING integer
|
||||||
local RPLC_LINKING = {
|
local RPLC_LINKING = {
|
||||||
ALLOW = 0, -- link approved
|
ALLOW = 0, -- link approved
|
||||||
DENY = 1, -- link denied
|
DENY = 1, -- link denied
|
||||||
COLLISION = 2 -- link denied due to existing active link
|
COLLISION = 2 -- link denied due to existing active link
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@alias SCADA_MGMT_TYPES integer
|
||||||
local SCADA_MGMT_TYPES = {
|
local SCADA_MGMT_TYPES = {
|
||||||
KEEP_ALIVE = 0, -- keep alive packet w/ RTT
|
KEEP_ALIVE = 0, -- keep alive packet w/ RTT
|
||||||
CLOSE = 1, -- close a connection
|
CLOSE = 1, -- close a connection
|
||||||
@ -43,6 +48,7 @@ local SCADA_MGMT_TYPES = {
|
|||||||
REMOTE_LINKED = 3 -- remote device linked
|
REMOTE_LINKED = 3 -- remote device linked
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@alias RTU_ADVERT_TYPES integer
|
||||||
local RTU_ADVERT_TYPES = {
|
local RTU_ADVERT_TYPES = {
|
||||||
REDSTONE = 0, -- redstone I/O
|
REDSTONE = 0, -- redstone I/O
|
||||||
BOILER = 1, -- boiler
|
BOILER = 1, -- boiler
|
||||||
@ -71,8 +77,14 @@ comms.scada_packet = function ()
|
|||||||
payload = nil
|
payload = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@class scada_packet
|
||||||
|
local public = {}
|
||||||
|
|
||||||
-- make a SCADA packet
|
-- make a SCADA packet
|
||||||
local make = function (seq_num, protocol, payload)
|
---@param seq_num integer
|
||||||
|
---@param protocol PROTOCOLS
|
||||||
|
---@param payload table
|
||||||
|
public.make = function (seq_num, protocol, payload)
|
||||||
self.valid = true
|
self.valid = true
|
||||||
self.seq_num = seq_num
|
self.seq_num = seq_num
|
||||||
self.protocol = protocol
|
self.protocol = protocol
|
||||||
@ -82,7 +94,12 @@ comms.scada_packet = function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- parse in a modem message as a SCADA packet
|
-- parse in a modem message as a SCADA packet
|
||||||
local receive = function (side, sender, reply_to, message, distance)
|
---@param side string
|
||||||
|
---@param sender integer
|
||||||
|
---@param reply_to integer
|
||||||
|
---@param message any
|
||||||
|
---@param distance integer
|
||||||
|
public.receive = function (side, sender, reply_to, message, distance)
|
||||||
self.modem_msg_in = {
|
self.modem_msg_in = {
|
||||||
iface = side,
|
iface = side,
|
||||||
s_port = sender,
|
s_port = sender,
|
||||||
@ -108,37 +125,20 @@ comms.scada_packet = function ()
|
|||||||
|
|
||||||
-- public accessors --
|
-- public accessors --
|
||||||
|
|
||||||
local modem_event = function () return self.modem_msg_in end
|
public.modem_event = function () return self.modem_msg_in end
|
||||||
local raw_sendable = function () return self.raw end
|
public.raw_sendable = function () return self.raw end
|
||||||
|
|
||||||
local local_port = function () return self.modem_msg_in.s_port end
|
public.local_port = function () return self.modem_msg_in.s_port end
|
||||||
local remote_port = function () return self.modem_msg_in.r_port end
|
public.remote_port = function () return self.modem_msg_in.r_port end
|
||||||
|
|
||||||
local is_valid = function () return self.valid end
|
public.is_valid = function () return self.valid end
|
||||||
|
|
||||||
local seq_num = function () return self.seq_num end
|
public.seq_num = function () return self.seq_num end
|
||||||
local protocol = function () return self.protocol end
|
public.protocol = function () return self.protocol end
|
||||||
local length = function () return self.length end
|
public.length = function () return self.length end
|
||||||
local data = function () return self.payload end
|
public.data = function () return self.payload end
|
||||||
|
|
||||||
return {
|
return public
|
||||||
-- construct
|
|
||||||
make = make,
|
|
||||||
receive = receive,
|
|
||||||
-- raw access
|
|
||||||
modem_event = modem_event,
|
|
||||||
raw_sendable = raw_sendable,
|
|
||||||
-- ports
|
|
||||||
local_port = local_port,
|
|
||||||
remote_port = remote_port,
|
|
||||||
-- well-formed
|
|
||||||
is_valid = is_valid,
|
|
||||||
-- packet properties
|
|
||||||
seq_num = seq_num,
|
|
||||||
protocol = protocol,
|
|
||||||
length = length,
|
|
||||||
data = data
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- MODBUS packet
|
-- MODBUS packet
|
||||||
@ -154,8 +154,15 @@ comms.modbus_packet = function ()
|
|||||||
data = nil
|
data = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@class modbus_packet
|
||||||
|
local public = {}
|
||||||
|
|
||||||
-- make a MODBUS packet
|
-- make a MODBUS packet
|
||||||
local make = function (txn_id, unit_id, func_code, data)
|
---@param txn_id integer
|
||||||
|
---@param unit_id integer
|
||||||
|
---@param func_code MODBUS_FCODE
|
||||||
|
---@param data table
|
||||||
|
public.make = function (txn_id, unit_id, func_code, data)
|
||||||
self.txn_id = txn_id
|
self.txn_id = txn_id
|
||||||
self.length = #data
|
self.length = #data
|
||||||
self.unit_id = unit_id
|
self.unit_id = unit_id
|
||||||
@ -170,7 +177,9 @@ comms.modbus_packet = function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- decode a MODBUS packet from a SCADA frame
|
-- decode a MODBUS packet from a SCADA frame
|
||||||
local decode = function (frame)
|
---@param frame scada_packet
|
||||||
|
---@return boolean success
|
||||||
|
public.decode = function (frame)
|
||||||
if frame then
|
if frame then
|
||||||
self.frame = frame
|
self.frame = frame
|
||||||
|
|
||||||
@ -179,7 +188,7 @@ comms.modbus_packet = function ()
|
|||||||
|
|
||||||
if size_ok then
|
if size_ok then
|
||||||
local data = frame.data()
|
local data = frame.data()
|
||||||
make(data[1], data[2], data[3], { table.unpack(data, 4, #data) })
|
public.make(data[1], data[2], data[3], { table.unpack(data, 4, #data) })
|
||||||
end
|
end
|
||||||
|
|
||||||
return size_ok
|
return size_ok
|
||||||
@ -194,10 +203,10 @@ comms.modbus_packet = function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get raw to send
|
-- get raw to send
|
||||||
local raw_sendable = function () return self.raw end
|
public.raw_sendable = function () return self.raw end
|
||||||
|
|
||||||
-- get this packet
|
-- get this packet
|
||||||
local get = function ()
|
public.get = function ()
|
||||||
return {
|
return {
|
||||||
scada_frame = self.frame,
|
scada_frame = self.frame,
|
||||||
txn_id = self.txn_id,
|
txn_id = self.txn_id,
|
||||||
@ -208,15 +217,7 @@ comms.modbus_packet = function ()
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return public
|
||||||
-- construct
|
|
||||||
make = make,
|
|
||||||
decode = decode,
|
|
||||||
-- raw access
|
|
||||||
raw_sendable = raw_sendable,
|
|
||||||
-- formatted access
|
|
||||||
get = get
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- reactor PLC packet
|
-- reactor PLC packet
|
||||||
@ -230,10 +231,12 @@ comms.rplc_packet = function ()
|
|||||||
body = nil
|
body = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@class rplc_packet
|
||||||
|
local public = {}
|
||||||
|
|
||||||
-- check that type is known
|
-- check that type is known
|
||||||
local _rplc_type_valid = function ()
|
local _rplc_type_valid = function ()
|
||||||
return self.type == RPLC_TYPES.KEEP_ALIVE or
|
return self.type == RPLC_TYPES.LINK_REQ or
|
||||||
self.type == RPLC_TYPES.LINK_REQ or
|
|
||||||
self.type == RPLC_TYPES.STATUS or
|
self.type == RPLC_TYPES.STATUS or
|
||||||
self.type == RPLC_TYPES.MEK_STRUCT or
|
self.type == RPLC_TYPES.MEK_STRUCT or
|
||||||
self.type == RPLC_TYPES.MEK_BURN_RATE or
|
self.type == RPLC_TYPES.MEK_BURN_RATE or
|
||||||
@ -245,7 +248,10 @@ comms.rplc_packet = function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- make an RPLC packet
|
-- make an RPLC packet
|
||||||
local make = function (id, packet_type, data)
|
---@param id integer
|
||||||
|
---@param packet_type RPLC_TYPES
|
||||||
|
---@param data table
|
||||||
|
public.make = function (id, packet_type, data)
|
||||||
-- packet accessor properties
|
-- packet accessor properties
|
||||||
self.id = id
|
self.id = id
|
||||||
self.type = packet_type
|
self.type = packet_type
|
||||||
@ -260,7 +266,9 @@ comms.rplc_packet = function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- decode an RPLC packet from a SCADA frame
|
-- decode an RPLC packet from a SCADA frame
|
||||||
local decode = function (frame)
|
---@param frame scada_packet
|
||||||
|
---@return boolean success
|
||||||
|
public.decode = function (frame)
|
||||||
if frame then
|
if frame then
|
||||||
self.frame = frame
|
self.frame = frame
|
||||||
|
|
||||||
@ -269,7 +277,7 @@ comms.rplc_packet = function ()
|
|||||||
|
|
||||||
if ok then
|
if ok then
|
||||||
local data = frame.data()
|
local data = frame.data()
|
||||||
make(data[1], data[2], { table.unpack(data, 3, #data) })
|
public.make(data[1], data[2], { table.unpack(data, 3, #data) })
|
||||||
ok = _rplc_type_valid()
|
ok = _rplc_type_valid()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -285,10 +293,10 @@ comms.rplc_packet = function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get raw to send
|
-- get raw to send
|
||||||
local raw_sendable = function () return self.raw end
|
public.raw_sendable = function () return self.raw end
|
||||||
|
|
||||||
-- get this packet
|
-- get this packet
|
||||||
local get = function ()
|
public.get = function ()
|
||||||
return {
|
return {
|
||||||
scada_frame = self.frame,
|
scada_frame = self.frame,
|
||||||
id = self.id,
|
id = self.id,
|
||||||
@ -298,15 +306,7 @@ comms.rplc_packet = function ()
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return public
|
||||||
-- construct
|
|
||||||
make = make,
|
|
||||||
decode = decode,
|
|
||||||
-- raw access
|
|
||||||
raw_sendable = raw_sendable,
|
|
||||||
-- formatted access
|
|
||||||
get = get
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- SCADA management packet
|
-- SCADA management packet
|
||||||
@ -319,17 +319,21 @@ comms.mgmt_packet = function ()
|
|||||||
data = nil
|
data = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@class mgmt_packet
|
||||||
|
local public = {}
|
||||||
|
|
||||||
-- check that type is known
|
-- check that type is known
|
||||||
local _scada_type_valid = function ()
|
local _scada_type_valid = function ()
|
||||||
return self.type == SCADA_MGMT_TYPES.PING or
|
return self.type == SCADA_MGMT_TYPES.KEEP_ALIVE or
|
||||||
self.type == SCADA_MGMT_TYPES.CLOSE or
|
self.type == SCADA_MGMT_TYPES.CLOSE or
|
||||||
self.type == SCADA_MGMT_TYPES.REMOTE_LINKED or
|
self.type == SCADA_MGMT_TYPES.REMOTE_LINKED or
|
||||||
self.type == SCADA_MGMT_TYPES.RTU_ADVERT or
|
self.type == SCADA_MGMT_TYPES.RTU_ADVERT
|
||||||
self.type == SCADA_MGMT_TYPES.RTU_HEARTBEAT
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- make a SCADA management packet
|
-- make a SCADA management packet
|
||||||
local make = function (packet_type, data)
|
---@param packet_type SCADA_MGMT_TYPES
|
||||||
|
---@param data table
|
||||||
|
public.make = function (packet_type, data)
|
||||||
-- packet accessor properties
|
-- packet accessor properties
|
||||||
self.type = packet_type
|
self.type = packet_type
|
||||||
self.length = #data
|
self.length = #data
|
||||||
@ -343,7 +347,9 @@ comms.mgmt_packet = function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- decode a SCADA management packet from a SCADA frame
|
-- decode a SCADA management packet from a SCADA frame
|
||||||
local decode = function (frame)
|
---@param frame scada_packet
|
||||||
|
---@return boolean success
|
||||||
|
public.decode = function (frame)
|
||||||
if frame then
|
if frame then
|
||||||
self.frame = frame
|
self.frame = frame
|
||||||
|
|
||||||
@ -352,7 +358,7 @@ comms.mgmt_packet = function ()
|
|||||||
|
|
||||||
if ok then
|
if ok then
|
||||||
local data = frame.data()
|
local data = frame.data()
|
||||||
make(data[1], { table.unpack(data, 2, #data) })
|
public.make(data[1], { table.unpack(data, 2, #data) })
|
||||||
ok = _scada_type_valid()
|
ok = _scada_type_valid()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -368,10 +374,10 @@ comms.mgmt_packet = function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get raw to send
|
-- get raw to send
|
||||||
local raw_sendable = function () return self.raw end
|
public.raw_sendable = function () return self.raw end
|
||||||
|
|
||||||
-- get this packet
|
-- get this packet
|
||||||
local get = function ()
|
public.get = function ()
|
||||||
return {
|
return {
|
||||||
scada_frame = self.frame,
|
scada_frame = self.frame,
|
||||||
type = self.type,
|
type = self.type,
|
||||||
@ -380,15 +386,7 @@ comms.mgmt_packet = function ()
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return public
|
||||||
-- construct
|
|
||||||
make = make,
|
|
||||||
decode = decode,
|
|
||||||
-- raw access
|
|
||||||
raw_sendable = raw_sendable,
|
|
||||||
-- formatted access
|
|
||||||
get = get
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- SCADA coordinator packet
|
-- SCADA coordinator packet
|
||||||
@ -402,13 +400,18 @@ comms.coord_packet = function ()
|
|||||||
data = nil
|
data = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@class coord_packet
|
||||||
|
local public = {}
|
||||||
|
|
||||||
local _coord_type_valid = function ()
|
local _coord_type_valid = function ()
|
||||||
-- @todo
|
-- @todo
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- make a coordinator packet
|
-- make a coordinator packet
|
||||||
local make = function (packet_type, data)
|
---@param packet_type any
|
||||||
|
---@param data table
|
||||||
|
public.make = function (packet_type, data)
|
||||||
-- packet accessor properties
|
-- packet accessor properties
|
||||||
self.type = packet_type
|
self.type = packet_type
|
||||||
self.length = #data
|
self.length = #data
|
||||||
@ -422,7 +425,9 @@ comms.coord_packet = function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- decode a coordinator packet from a SCADA frame
|
-- decode a coordinator packet from a SCADA frame
|
||||||
local decode = function (frame)
|
---@param frame scada_packet
|
||||||
|
---@return boolean success
|
||||||
|
public.decode = function (frame)
|
||||||
if frame then
|
if frame then
|
||||||
self.frame = frame
|
self.frame = frame
|
||||||
|
|
||||||
@ -431,7 +436,7 @@ comms.coord_packet = function ()
|
|||||||
|
|
||||||
if ok then
|
if ok then
|
||||||
local data = frame.data()
|
local data = frame.data()
|
||||||
make(data[1], { table.unpack(data, 2, #data) })
|
public.make(data[1], { table.unpack(data, 2, #data) })
|
||||||
ok = _coord_type_valid()
|
ok = _coord_type_valid()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -447,10 +452,10 @@ comms.coord_packet = function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get raw to send
|
-- get raw to send
|
||||||
local raw_sendable = function () return self.raw end
|
public.raw_sendable = function () return self.raw end
|
||||||
|
|
||||||
-- get this packet
|
-- get this packet
|
||||||
local get = function ()
|
public.get = function ()
|
||||||
return {
|
return {
|
||||||
scada_frame = self.frame,
|
scada_frame = self.frame,
|
||||||
type = self.type,
|
type = self.type,
|
||||||
@ -459,15 +464,7 @@ comms.coord_packet = function ()
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return public
|
||||||
-- construct
|
|
||||||
make = make,
|
|
||||||
decode = decode,
|
|
||||||
-- raw access
|
|
||||||
raw_sendable = raw_sendable,
|
|
||||||
-- formatted access
|
|
||||||
get = get
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- coordinator API (CAPI) packet
|
-- coordinator API (CAPI) packet
|
||||||
@ -481,13 +478,18 @@ comms.capi_packet = function ()
|
|||||||
data = nil
|
data = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@class capi_packet
|
||||||
|
local public = {}
|
||||||
|
|
||||||
local _coord_type_valid = function ()
|
local _coord_type_valid = function ()
|
||||||
-- @todo
|
-- @todo
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- make a coordinator packet
|
-- make a coordinator API packet
|
||||||
local make = function (packet_type, data)
|
---@param packet_type any
|
||||||
|
---@param data table
|
||||||
|
public.make = function (packet_type, data)
|
||||||
-- packet accessor properties
|
-- packet accessor properties
|
||||||
self.type = packet_type
|
self.type = packet_type
|
||||||
self.length = #data
|
self.length = #data
|
||||||
@ -500,8 +502,10 @@ comms.capi_packet = function ()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- decode a coordinator packet from a SCADA frame
|
-- decode a coordinator API packet from a SCADA frame
|
||||||
local decode = function (frame)
|
---@param frame scada_packet
|
||||||
|
---@return boolean success
|
||||||
|
public.decode = function (frame)
|
||||||
if frame then
|
if frame then
|
||||||
self.frame = frame
|
self.frame = frame
|
||||||
|
|
||||||
@ -510,7 +514,7 @@ comms.capi_packet = function ()
|
|||||||
|
|
||||||
if ok then
|
if ok then
|
||||||
local data = frame.data()
|
local data = frame.data()
|
||||||
make(data[1], { table.unpack(data, 2, #data) })
|
public.make(data[1], { table.unpack(data, 2, #data) })
|
||||||
ok = _coord_type_valid()
|
ok = _coord_type_valid()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -526,10 +530,10 @@ comms.capi_packet = function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get raw to send
|
-- get raw to send
|
||||||
local raw_sendable = function () return self.raw end
|
public.raw_sendable = function () return self.raw end
|
||||||
|
|
||||||
-- get this packet
|
-- get this packet
|
||||||
local get = function ()
|
public.get = function ()
|
||||||
return {
|
return {
|
||||||
scada_frame = self.frame,
|
scada_frame = self.frame,
|
||||||
type = self.type,
|
type = self.type,
|
||||||
@ -538,18 +542,12 @@ comms.capi_packet = function ()
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return public
|
||||||
-- construct
|
|
||||||
make = make,
|
|
||||||
decode = decode,
|
|
||||||
-- raw access
|
|
||||||
raw_sendable = raw_sendable,
|
|
||||||
-- formatted access
|
|
||||||
get = get
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- convert rtu_t to RTU advertisement type
|
-- convert rtu_t to RTU advertisement type
|
||||||
|
---@param type rtu_t
|
||||||
|
---@return RTU_ADVERT_TYPES|nil
|
||||||
comms.rtu_t_to_advert_type = function (type)
|
comms.rtu_t_to_advert_type = function (type)
|
||||||
if type == rtu_t.redstone then
|
if type == rtu_t.redstone then
|
||||||
return RTU_ADVERT_TYPES.REDSTONE
|
return RTU_ADVERT_TYPES.REDSTONE
|
||||||
@ -571,6 +569,8 @@ comms.rtu_t_to_advert_type = function (type)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- convert RTU advertisement type to rtu_t
|
-- convert RTU advertisement type to rtu_t
|
||||||
|
---@param atype RTU_ADVERT_TYPES
|
||||||
|
---@return rtu_t|nil
|
||||||
comms.advert_type_to_rtu_t = function (atype)
|
comms.advert_type_to_rtu_t = function (atype)
|
||||||
if atype == RTU_ADVERT_TYPES.REDSTONE then
|
if atype == RTU_ADVERT_TYPES.REDSTONE then
|
||||||
return rtu_t.redstone
|
return rtu_t.redstone
|
||||||
|
|||||||
@ -4,8 +4,10 @@ local util = require("scada-common.util")
|
|||||||
-- File System Logger
|
-- File System Logger
|
||||||
--
|
--
|
||||||
|
|
||||||
|
---@class log
|
||||||
local log = {}
|
local log = {}
|
||||||
|
|
||||||
|
---@alias MODE integer
|
||||||
local MODE = {
|
local MODE = {
|
||||||
APPEND = 0,
|
APPEND = 0,
|
||||||
NEW = 1
|
NEW = 1
|
||||||
@ -13,6 +15,7 @@ local MODE = {
|
|||||||
|
|
||||||
log.MODE = MODE
|
log.MODE = MODE
|
||||||
|
|
||||||
|
-- whether to log debug messages or not
|
||||||
local LOG_DEBUG = true
|
local LOG_DEBUG = true
|
||||||
|
|
||||||
local _log_sys = {
|
local _log_sys = {
|
||||||
@ -21,9 +24,12 @@ local _log_sys = {
|
|||||||
file = nil
|
file = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@type function
|
||||||
local free_space = fs.getFreeSpace
|
local free_space = fs.getFreeSpace
|
||||||
|
|
||||||
-- initialize logger
|
-- initialize logger
|
||||||
|
---@param path string file path
|
||||||
|
---@param write_mode MODE
|
||||||
log.init = function (path, write_mode)
|
log.init = function (path, write_mode)
|
||||||
_log_sys.path = path
|
_log_sys.path = path
|
||||||
_log_sys.mode = write_mode
|
_log_sys.mode = write_mode
|
||||||
@ -36,6 +42,7 @@ log.init = function (path, write_mode)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- private log write function
|
-- private log write function
|
||||||
|
---@param msg string
|
||||||
local _log = function (msg)
|
local _log = function (msg)
|
||||||
local time_stamp = os.date("[%c] ")
|
local time_stamp = os.date("[%c] ")
|
||||||
local stamped = time_stamp .. msg
|
local stamped = time_stamp .. msg
|
||||||
@ -70,6 +77,8 @@ local _log = function (msg)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- log debug messages
|
-- log debug messages
|
||||||
|
---@param msg string message
|
||||||
|
---@param trace? boolean include file trace
|
||||||
log.debug = function (msg, trace)
|
log.debug = function (msg, trace)
|
||||||
if LOG_DEBUG then
|
if LOG_DEBUG then
|
||||||
local dbg_info = ""
|
local dbg_info = ""
|
||||||
@ -90,16 +99,20 @@ log.debug = function (msg, trace)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- log info messages
|
-- log info messages
|
||||||
|
---@param msg string message
|
||||||
log.info = function (msg)
|
log.info = function (msg)
|
||||||
_log("[INF] " .. msg)
|
_log("[INF] " .. msg)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- log warning messages
|
-- log warning messages
|
||||||
|
---@param msg string message
|
||||||
log.warning = function (msg)
|
log.warning = function (msg)
|
||||||
_log("[WRN] " .. msg)
|
_log("[WRN] " .. msg)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- log error messages
|
-- log error messages
|
||||||
|
---@param msg string message
|
||||||
|
---@param trace? boolean include file trace
|
||||||
log.error = function (msg, trace)
|
log.error = function (msg, trace)
|
||||||
local dbg_info = ""
|
local dbg_info = ""
|
||||||
|
|
||||||
@ -118,6 +131,7 @@ log.error = function (msg, trace)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- log fatal errors
|
-- log fatal errors
|
||||||
|
---@param msg string message
|
||||||
log.fatal = function (msg)
|
log.fatal = function (msg)
|
||||||
_log("[FTL] " .. msg)
|
_log("[FTL] " .. msg)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
local mqueue = {}
|
local mqueue = {}
|
||||||
|
|
||||||
|
---@alias TYPE integer
|
||||||
local TYPE = {
|
local TYPE = {
|
||||||
COMMAND = 0,
|
COMMAND = 0,
|
||||||
DATA = 1,
|
DATA = 1,
|
||||||
@ -12,41 +13,61 @@ local TYPE = {
|
|||||||
|
|
||||||
mqueue.TYPE = TYPE
|
mqueue.TYPE = TYPE
|
||||||
|
|
||||||
|
-- create a new message queue
|
||||||
mqueue.new = function ()
|
mqueue.new = function ()
|
||||||
local queue = {}
|
local queue = {}
|
||||||
|
|
||||||
local insert = table.insert
|
local insert = table.insert
|
||||||
local remove = table.remove
|
local remove = table.remove
|
||||||
|
|
||||||
local length = function ()
|
---@class queue_item
|
||||||
return #queue
|
local queue_item = {
|
||||||
end
|
qtype = 0, ---@type TYPE
|
||||||
|
message = 0 ---@type any
|
||||||
|
}
|
||||||
|
|
||||||
local empty = function ()
|
---@class mqueue
|
||||||
return #queue == 0
|
local public = {}
|
||||||
end
|
|
||||||
|
|
||||||
local ready = function ()
|
-- get queue length
|
||||||
return #queue ~= 0
|
public.length = function () return #queue end
|
||||||
end
|
|
||||||
|
|
||||||
|
-- check if queue is empty
|
||||||
|
---@return boolean is_empty
|
||||||
|
public.empty = function () return #queue == 0 end
|
||||||
|
|
||||||
|
-- check if queue has contents
|
||||||
|
public.ready = function () return #queue ~= 0 end
|
||||||
|
|
||||||
|
-- push a new item onto the queue
|
||||||
|
---@param qtype TYPE
|
||||||
|
---@param message string
|
||||||
local _push = function (qtype, message)
|
local _push = function (qtype, message)
|
||||||
insert(queue, { qtype = qtype, message = message })
|
insert(queue, { qtype = qtype, message = message })
|
||||||
end
|
end
|
||||||
|
|
||||||
local push_command = function (message)
|
-- push a command onto the queue
|
||||||
|
---@param message any
|
||||||
|
public.push_command = function (message)
|
||||||
_push(TYPE.COMMAND, message)
|
_push(TYPE.COMMAND, message)
|
||||||
end
|
end
|
||||||
|
|
||||||
local push_data = function (key, value)
|
-- push data onto the queue
|
||||||
|
---@param key any
|
||||||
|
---@param value any
|
||||||
|
public.push_data = function (key, value)
|
||||||
_push(TYPE.DATA, { key = key, val = value })
|
_push(TYPE.DATA, { key = key, val = value })
|
||||||
end
|
end
|
||||||
|
|
||||||
local push_packet = function (message)
|
-- push a packet onto the queue
|
||||||
_push(TYPE.PACKET, message)
|
---@param packet scada_packet|modbus_packet|rplc_packet|coord_packet|capi_packet
|
||||||
|
public.push_packet = function (packet)
|
||||||
|
_push(TYPE.PACKET, packet)
|
||||||
end
|
end
|
||||||
|
|
||||||
local pop = function ()
|
-- get an item off the queue
|
||||||
|
---@return queue_item|nil
|
||||||
|
public.pop = function ()
|
||||||
if #queue > 0 then
|
if #queue > 0 then
|
||||||
return remove(queue, 1)
|
return remove(queue, 1)
|
||||||
else
|
else
|
||||||
@ -54,15 +75,7 @@ mqueue.new = function ()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return public
|
||||||
length = length,
|
|
||||||
empty = empty,
|
|
||||||
ready = ready,
|
|
||||||
push_packet = push_packet,
|
|
||||||
push_data = push_data,
|
|
||||||
push_command = push_command,
|
|
||||||
pop = pop
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return mqueue
|
return mqueue
|
||||||
|
|||||||
@ -4,9 +4,10 @@ local log = require("scada-common.log")
|
|||||||
-- Protected Peripheral Manager
|
-- Protected Peripheral Manager
|
||||||
--
|
--
|
||||||
|
|
||||||
|
---@class ppm
|
||||||
local ppm = {}
|
local ppm = {}
|
||||||
|
|
||||||
local ACCESS_FAULT = nil
|
local ACCESS_FAULT = nil ---@type nil
|
||||||
|
|
||||||
ppm.ACCESS_FAULT = ACCESS_FAULT
|
ppm.ACCESS_FAULT = ACCESS_FAULT
|
||||||
|
|
||||||
@ -22,9 +23,12 @@ local _ppm_sys = {
|
|||||||
mute = false
|
mute = false
|
||||||
}
|
}
|
||||||
|
|
||||||
-- wrap peripheral calls with lua protected call
|
-- wrap peripheral calls with lua protected call as we don't want a disconnect to crash a program
|
||||||
-- we don't want a disconnect to crash a program
|
---
|
||||||
-- also provides peripheral-specific fault checks (auto-clear fault defaults to true)
|
---also provides peripheral-specific fault checks (auto-clear fault defaults to true)
|
||||||
|
---
|
||||||
|
---assumes iface is a valid peripheral
|
||||||
|
---@param iface string CC peripheral interface
|
||||||
local peri_init = function (iface)
|
local peri_init = function (iface)
|
||||||
local self = {
|
local self = {
|
||||||
faulted = false,
|
faulted = false,
|
||||||
@ -150,6 +154,8 @@ ppm.mount_all = function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- mount a particular device
|
-- mount a particular device
|
||||||
|
---@param iface string CC peripheral interface
|
||||||
|
---@return string|nil type, table|nil device
|
||||||
ppm.mount = function (iface)
|
ppm.mount = function (iface)
|
||||||
local ifaces = peripheral.getNames()
|
local ifaces = peripheral.getNames()
|
||||||
local pm_dev = nil
|
local pm_dev = nil
|
||||||
@ -171,33 +177,44 @@ ppm.mount = function (iface)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- handle peripheral_detach event
|
-- handle peripheral_detach event
|
||||||
|
---@param iface string CC peripheral interface
|
||||||
|
---@return string|nil type, table|nil device
|
||||||
ppm.handle_unmount = function (iface)
|
ppm.handle_unmount = function (iface)
|
||||||
|
local pm_dev = nil
|
||||||
|
local pm_type = nil
|
||||||
|
|
||||||
-- what got disconnected?
|
-- what got disconnected?
|
||||||
local lost_dev = _ppm_sys.mounts[iface]
|
local lost_dev = _ppm_sys.mounts[iface]
|
||||||
|
|
||||||
if lost_dev then
|
if lost_dev then
|
||||||
local type = lost_dev.type
|
pm_type = lost_dev.type
|
||||||
log.warning("PPM: lost device " .. type .. " mounted to " .. iface)
|
pm_dev = lost_dev.dev
|
||||||
|
|
||||||
|
log.warning("PPM: lost device " .. pm_type .. " mounted to " .. iface)
|
||||||
else
|
else
|
||||||
log.error("PPM: lost device unknown to the PPM mounted to " .. iface)
|
log.error("PPM: lost device unknown to the PPM mounted to " .. iface)
|
||||||
end
|
end
|
||||||
|
|
||||||
return lost_dev
|
return pm_type, pm_dev
|
||||||
end
|
end
|
||||||
|
|
||||||
-- GENERAL ACCESSORS --
|
-- GENERAL ACCESSORS --
|
||||||
|
|
||||||
-- list all available peripherals
|
-- list all available peripherals
|
||||||
|
---@return table names
|
||||||
ppm.list_avail = function ()
|
ppm.list_avail = function ()
|
||||||
return peripheral.getNames()
|
return peripheral.getNames()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- list mounted peripherals
|
-- list mounted peripherals
|
||||||
|
---@return table mounts
|
||||||
ppm.list_mounts = function ()
|
ppm.list_mounts = function ()
|
||||||
return _ppm_sys.mounts
|
return _ppm_sys.mounts
|
||||||
end
|
end
|
||||||
|
|
||||||
-- get a mounted peripheral by side/interface
|
-- get a mounted peripheral by side/interface
|
||||||
|
---@param iface string CC peripheral interface
|
||||||
|
---@return table|nil device function table
|
||||||
ppm.get_periph = function (iface)
|
ppm.get_periph = function (iface)
|
||||||
if _ppm_sys.mounts[iface] then
|
if _ppm_sys.mounts[iface] then
|
||||||
return _ppm_sys.mounts[iface].dev
|
return _ppm_sys.mounts[iface].dev
|
||||||
@ -205,6 +222,8 @@ ppm.get_periph = function (iface)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get a mounted peripheral type by side/interface
|
-- get a mounted peripheral type by side/interface
|
||||||
|
---@param iface string CC peripheral interface
|
||||||
|
---@return string|nil type
|
||||||
ppm.get_type = function (iface)
|
ppm.get_type = function (iface)
|
||||||
if _ppm_sys.mounts[iface] then
|
if _ppm_sys.mounts[iface] then
|
||||||
return _ppm_sys.mounts[iface].type
|
return _ppm_sys.mounts[iface].type
|
||||||
@ -212,6 +231,8 @@ ppm.get_type = function (iface)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get all mounted peripherals by type
|
-- get all mounted peripherals by type
|
||||||
|
---@param name string type name
|
||||||
|
---@return table devices device function tables
|
||||||
ppm.get_all_devices = function (name)
|
ppm.get_all_devices = function (name)
|
||||||
local devices = {}
|
local devices = {}
|
||||||
|
|
||||||
@ -225,6 +246,8 @@ ppm.get_all_devices = function (name)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get a mounted peripheral by type (if multiple, returns the first)
|
-- get a mounted peripheral by type (if multiple, returns the first)
|
||||||
|
---@param name string type name
|
||||||
|
---@return table|nil device function table
|
||||||
ppm.get_device = function (name)
|
ppm.get_device = function (name)
|
||||||
local device = nil
|
local device = nil
|
||||||
|
|
||||||
@ -241,11 +264,13 @@ end
|
|||||||
-- SPECIFIC DEVICE ACCESSORS --
|
-- SPECIFIC DEVICE ACCESSORS --
|
||||||
|
|
||||||
-- get the fission reactor (if multiple, returns the first)
|
-- get the fission reactor (if multiple, returns the first)
|
||||||
|
---@return table|nil reactor function table
|
||||||
ppm.get_fission_reactor = function ()
|
ppm.get_fission_reactor = function ()
|
||||||
return ppm.get_device("fissionReactor")
|
return ppm.get_device("fissionReactor")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- get the wireless modem (if multiple, returns the first)
|
-- get the wireless modem (if multiple, returns the first)
|
||||||
|
---@return table|nil modem function table
|
||||||
ppm.get_wireless_modem = function ()
|
ppm.get_wireless_modem = function ()
|
||||||
local w_modem = nil
|
local w_modem = nil
|
||||||
|
|
||||||
@ -260,6 +285,7 @@ ppm.get_wireless_modem = function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- list all connected monitors
|
-- list all connected monitors
|
||||||
|
---@return table monitors
|
||||||
ppm.list_monitors = function ()
|
ppm.list_monitors = function ()
|
||||||
return ppm.get_all_devices("monitor")
|
return ppm.get_all_devices("monitor")
|
||||||
end
|
end
|
||||||
|
|||||||
@ -8,16 +8,19 @@ local rsio = {}
|
|||||||
-- RS I/O CONSTANTS --
|
-- RS I/O CONSTANTS --
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
|
---@alias IO_LVL integer
|
||||||
local IO_LVL = {
|
local IO_LVL = {
|
||||||
LOW = 0,
|
LOW = 0,
|
||||||
HIGH = 1
|
HIGH = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@alias IO_DIR integer
|
||||||
local IO_DIR = {
|
local IO_DIR = {
|
||||||
IN = 0,
|
IN = 0,
|
||||||
OUT = 1
|
OUT = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@alias IO_MODE integer
|
||||||
local IO_MODE = {
|
local IO_MODE = {
|
||||||
DIGITAL_OUT = 0,
|
DIGITAL_OUT = 0,
|
||||||
DIGITAL_IN = 1,
|
DIGITAL_IN = 1,
|
||||||
@ -25,6 +28,7 @@ local IO_MODE = {
|
|||||||
ANALOG_IN = 3
|
ANALOG_IN = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@alias RS_IO integer
|
||||||
local RS_IO = {
|
local RS_IO = {
|
||||||
-- digital inputs --
|
-- digital inputs --
|
||||||
|
|
||||||
@ -73,6 +77,7 @@ rsio.IO = RS_IO
|
|||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
-- channel to string
|
-- channel to string
|
||||||
|
---@param channel RS_IO
|
||||||
rsio.to_string = function (channel)
|
rsio.to_string = function (channel)
|
||||||
local names = {
|
local names = {
|
||||||
"F_SCRAM",
|
"F_SCRAM",
|
||||||
@ -155,6 +160,8 @@ local RS_DIO_MAP = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
-- get the mode of a channel
|
-- get the mode of a channel
|
||||||
|
---@param channel RS_IO
|
||||||
|
---@return IO_MODE
|
||||||
rsio.get_io_mode = function (channel)
|
rsio.get_io_mode = function (channel)
|
||||||
local modes = {
|
local modes = {
|
||||||
IO_MODE.DIGITAL_IN, -- F_SCRAM
|
IO_MODE.DIGITAL_IN, -- F_SCRAM
|
||||||
@ -194,11 +201,15 @@ end
|
|||||||
local RS_SIDES = rs.getSides()
|
local RS_SIDES = rs.getSides()
|
||||||
|
|
||||||
-- check if a channel is valid
|
-- check if a channel is valid
|
||||||
|
---@param channel RS_IO
|
||||||
|
---@return boolean valid
|
||||||
rsio.is_valid_channel = function (channel)
|
rsio.is_valid_channel = function (channel)
|
||||||
return channel ~= nil and channel > 0 and channel <= RS_IO.A_T_FLOW_RATE
|
return (channel ~= nil) and (channel > 0) and (channel <= RS_IO.A_T_FLOW_RATE)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- check if a side is valid
|
-- check if a side is valid
|
||||||
|
---@param side string
|
||||||
|
---@return boolean valid
|
||||||
rsio.is_valid_side = function (side)
|
rsio.is_valid_side = function (side)
|
||||||
if side ~= nil then
|
if side ~= nil then
|
||||||
for i = 0, #RS_SIDES do
|
for i = 0, #RS_SIDES do
|
||||||
@ -209,6 +220,8 @@ rsio.is_valid_side = function (side)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- check if a color is a valid single color
|
-- check if a color is a valid single color
|
||||||
|
---@param color integer
|
||||||
|
---@return boolean valid
|
||||||
rsio.is_color = function (color)
|
rsio.is_color = function (color)
|
||||||
return (color > 0) and (_B_AND(color, (color - 1)) == 0);
|
return (color > 0) and (_B_AND(color, (color - 1)) == 0);
|
||||||
end
|
end
|
||||||
@ -218,6 +231,8 @@ end
|
|||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
-- get digital IO level reading
|
-- get digital IO level reading
|
||||||
|
---@param rs_value boolean
|
||||||
|
---@return IO_LVL
|
||||||
rsio.digital_read = function (rs_value)
|
rsio.digital_read = function (rs_value)
|
||||||
if rs_value then
|
if rs_value then
|
||||||
return IO_LVL.HIGH
|
return IO_LVL.HIGH
|
||||||
@ -227,6 +242,9 @@ rsio.digital_read = function (rs_value)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- returns the level corresponding to active
|
-- returns the level corresponding to active
|
||||||
|
---@param channel RS_IO
|
||||||
|
---@param active boolean
|
||||||
|
---@return IO_LVL
|
||||||
rsio.digital_write = function (channel, active)
|
rsio.digital_write = function (channel, active)
|
||||||
if channel < RS_IO.WASTE_PO or channel > RS_IO.R_PLC_TIMEOUT then
|
if channel < RS_IO.WASTE_PO or channel > RS_IO.R_PLC_TIMEOUT then
|
||||||
return IO_LVL.LOW
|
return IO_LVL.LOW
|
||||||
@ -236,6 +254,9 @@ rsio.digital_write = function (channel, active)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- returns true if the level corresponds to active
|
-- returns true if the level corresponds to active
|
||||||
|
---@param channel RS_IO
|
||||||
|
---@param level IO_LVL
|
||||||
|
---@return boolean
|
||||||
rsio.digital_is_active = function (channel, level)
|
rsio.digital_is_active = function (channel, level)
|
||||||
if channel > RS_IO.R_ENABLE or channel > RS_IO.R_PLC_TIMEOUT then
|
if channel > RS_IO.R_ENABLE or channel > RS_IO.R_PLC_TIMEOUT then
|
||||||
return false
|
return false
|
||||||
|
|||||||
@ -2,8 +2,10 @@
|
|||||||
-- Global Types
|
-- Global Types
|
||||||
--
|
--
|
||||||
|
|
||||||
|
---@class types
|
||||||
local types = {}
|
local types = {}
|
||||||
|
|
||||||
|
---@alias rtu_t string
|
||||||
types.rtu_t = {
|
types.rtu_t = {
|
||||||
redstone = "redstone",
|
redstone = "redstone",
|
||||||
boiler = "boiler",
|
boiler = "boiler",
|
||||||
@ -14,6 +16,7 @@ types.rtu_t = {
|
|||||||
induction_matrix = "induction_matrix"
|
induction_matrix = "induction_matrix"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@alias rps_status_t string
|
||||||
types.rps_status_t = {
|
types.rps_status_t = {
|
||||||
ok = "ok",
|
ok = "ok",
|
||||||
dmg_crit = "dmg_crit",
|
dmg_crit = "dmg_crit",
|
||||||
@ -30,6 +33,7 @@ types.rps_status_t = {
|
|||||||
-- MODBUS
|
-- MODBUS
|
||||||
|
|
||||||
-- modbus function codes
|
-- modbus function codes
|
||||||
|
---@alias MODBUS_FCODE integer
|
||||||
types.MODBUS_FCODE = {
|
types.MODBUS_FCODE = {
|
||||||
READ_COILS = 0x01,
|
READ_COILS = 0x01,
|
||||||
READ_DISCRETE_INPUTS = 0x02,
|
READ_DISCRETE_INPUTS = 0x02,
|
||||||
@ -43,6 +47,7 @@ types.MODBUS_FCODE = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
-- modbus exception codes
|
-- modbus exception codes
|
||||||
|
---@alias MODBUS_EXCODE integer
|
||||||
types.MODBUS_EXCODE = {
|
types.MODBUS_EXCODE = {
|
||||||
ILLEGAL_FUNCTION = 0x01,
|
ILLEGAL_FUNCTION = 0x01,
|
||||||
ILLEGAL_DATA_ADDR = 0x02,
|
ILLEGAL_DATA_ADDR = 0x02,
|
||||||
|
|||||||
@ -1,3 +1,8 @@
|
|||||||
|
--
|
||||||
|
-- Utility Functions
|
||||||
|
--
|
||||||
|
|
||||||
|
---@class util
|
||||||
local util = {}
|
local util = {}
|
||||||
|
|
||||||
-- PRINT --
|
-- PRINT --
|
||||||
@ -24,16 +29,22 @@ end
|
|||||||
|
|
||||||
-- TIME --
|
-- TIME --
|
||||||
|
|
||||||
|
-- current time
|
||||||
|
---@return integer milliseconds
|
||||||
util.time_ms = function ()
|
util.time_ms = function ()
|
||||||
---@diagnostic disable-next-line: undefined-field
|
---@diagnostic disable-next-line: undefined-field
|
||||||
return os.epoch('local')
|
return os.epoch('local')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- current time
|
||||||
|
---@return integer seconds
|
||||||
util.time_s = function ()
|
util.time_s = function ()
|
||||||
---@diagnostic disable-next-line: undefined-field
|
---@diagnostic disable-next-line: undefined-field
|
||||||
return os.epoch('local') / 1000
|
return os.epoch('local') / 1000
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- current time
|
||||||
|
---@return integer milliseconds
|
||||||
util.time = function ()
|
util.time = function ()
|
||||||
return util.time_ms()
|
return util.time_ms()
|
||||||
end
|
end
|
||||||
@ -41,19 +52,24 @@ end
|
|||||||
-- PARALLELIZATION --
|
-- PARALLELIZATION --
|
||||||
|
|
||||||
-- protected sleep call so we still are in charge of catching termination
|
-- protected sleep call so we still are in charge of catching termination
|
||||||
-- EVENT_CONSUMER: this function consumes events
|
---@param t integer seconds
|
||||||
|
--- EVENT_CONSUMER: this function consumes events
|
||||||
util.psleep = function (t)
|
util.psleep = function (t)
|
||||||
---@diagnostic disable-next-line: undefined-field
|
---@diagnostic disable-next-line: undefined-field
|
||||||
pcall(os.sleep, t)
|
pcall(os.sleep, t)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- no-op to provide a brief pause (and a yield)
|
-- no-op to provide a brief pause (1 tick) to yield
|
||||||
-- EVENT_CONSUMER: this function consumes events
|
---
|
||||||
|
--- EVENT_CONSUMER: this function consumes events
|
||||||
util.nop = function ()
|
util.nop = function ()
|
||||||
util.psleep(0.05)
|
util.psleep(0.05)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- attempt to maintain a minimum loop timing (duration of execution)
|
-- attempt to maintain a minimum loop timing (duration of execution)
|
||||||
|
---@param target_timing integer minimum amount of milliseconds to wait for
|
||||||
|
---@param last_update integer millisecond time of last update
|
||||||
|
---@return integer time_now
|
||||||
-- EVENT_CONSUMER: this function consumes events
|
-- EVENT_CONSUMER: this function consumes events
|
||||||
util.adaptive_delay = function (target_timing, last_update)
|
util.adaptive_delay = function (target_timing, last_update)
|
||||||
local sleep_for = target_timing - (util.time() - last_update)
|
local sleep_for = target_timing - (util.time() - last_update)
|
||||||
@ -64,6 +80,37 @@ util.adaptive_delay = function (target_timing, last_update)
|
|||||||
return util.time()
|
return util.time()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- MEKANISM POWER --
|
||||||
|
|
||||||
|
-- function kFE(fe) return fe / 1000 end
|
||||||
|
-- function MFE(fe) return fe / 1000000 end
|
||||||
|
-- function GFE(fe) return fe / 1000000000 end
|
||||||
|
-- function TFE(fe) return fe / 1000000000000 end
|
||||||
|
|
||||||
|
-- -- FLOATING POINT PRINTS --
|
||||||
|
|
||||||
|
-- local function fractional_1s(number)
|
||||||
|
-- return number == math.round(number)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- local function fractional_10ths(number)
|
||||||
|
-- number = number * 10
|
||||||
|
-- return number == math.round(number)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- local function fractional_100ths(number)
|
||||||
|
-- number = number * 100
|
||||||
|
-- return number == math.round(number)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- function power_format(fe)
|
||||||
|
-- if fe < 1000 then
|
||||||
|
-- return string.format("%.2f FE", fe)
|
||||||
|
-- elseif fe < 1000000 then
|
||||||
|
-- return string.format("%.3f kFE", kFE(fe))
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
-- WATCHDOG --
|
-- WATCHDOG --
|
||||||
|
|
||||||
-- ComputerCraft OS Timer based Watchdog
|
-- ComputerCraft OS Timer based Watchdog
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user