code cleanup and bugfixes
This commit is contained in:
parent
d7e38d6393
commit
168341db39
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -4,6 +4,8 @@
|
|||||||
"fs",
|
"fs",
|
||||||
"peripheral",
|
"peripheral",
|
||||||
"rs",
|
"rs",
|
||||||
"bit"
|
"bit",
|
||||||
|
"parallel",
|
||||||
|
"colors"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -558,8 +558,10 @@ plc.comms = function (id, modem, local_port, server_port, reactor, rps, conn_wat
|
|||||||
-- feed the watchdog first so it doesn't uhh...eat our packets :)
|
-- feed the watchdog first so it doesn't uhh...eat our packets :)
|
||||||
self.conn_watchdog.feed()
|
self.conn_watchdog.feed()
|
||||||
|
|
||||||
|
local protocol = packet.scada_frame.protocol()
|
||||||
|
|
||||||
-- handle packet
|
-- handle packet
|
||||||
if packet.scada_frame.protocol() == PROTOCOLS.RPLC then
|
if protocol == PROTOCOLS.RPLC then
|
||||||
if self.linked then
|
if self.linked then
|
||||||
if packet.type == RPLC_TYPES.LINK_REQ then
|
if packet.type == RPLC_TYPES.LINK_REQ then
|
||||||
-- link request confirmation
|
-- link request confirmation
|
||||||
@ -678,7 +680,7 @@ plc.comms = function (id, modem, local_port, server_port, reactor, rps, conn_wat
|
|||||||
else
|
else
|
||||||
log.debug("discarding non-link packet before linked")
|
log.debug("discarding non-link packet before linked")
|
||||||
end
|
end
|
||||||
elseif packet.scada_frame.protocol() == PROTOCOLS.SCADA_MGMT then
|
elseif protocol == PROTOCOLS.SCADA_MGMT then
|
||||||
if packet.type == SCADA_MGMT_TYPES.KEEP_ALIVE then
|
if packet.type == SCADA_MGMT_TYPES.KEEP_ALIVE then
|
||||||
-- keep alive request received, echo back
|
-- keep alive request received, echo back
|
||||||
if packet.length == 1 then
|
if packet.length == 1 then
|
||||||
|
|||||||
@ -11,7 +11,7 @@ local config = require("config")
|
|||||||
local plc = require("plc")
|
local plc = require("plc")
|
||||||
local threads = require("threads")
|
local threads = require("threads")
|
||||||
|
|
||||||
local R_PLC_VERSION = "alpha-v0.6.5"
|
local R_PLC_VERSION = "alpha-v0.6.6"
|
||||||
|
|
||||||
local print = util.print
|
local print = util.print
|
||||||
local println = util.println
|
local println = util.println
|
||||||
@ -46,7 +46,7 @@ local __shared_memory = {
|
|||||||
burn_rate_en = false,
|
burn_rate_en = false,
|
||||||
burn_rate = 0.0
|
burn_rate = 0.0
|
||||||
},
|
},
|
||||||
|
|
||||||
-- core PLC devices
|
-- core PLC devices
|
||||||
plc_dev = {
|
plc_dev = {
|
||||||
reactor = ppm.get_fission_reactor(),
|
reactor = ppm.get_fission_reactor(),
|
||||||
@ -82,7 +82,7 @@ if smem_dev.reactor == nil then
|
|||||||
plc_state.degraded = true
|
plc_state.degraded = true
|
||||||
plc_state.no_reactor = true
|
plc_state.no_reactor = true
|
||||||
end
|
end
|
||||||
if networked and smem_dev.modem == nil then
|
if __shared_memory.networked and smem_dev.modem == nil then
|
||||||
println("boot> wireless modem not found")
|
println("boot> wireless modem not found")
|
||||||
log.warning("no wireless modem on startup")
|
log.warning("no wireless modem on startup")
|
||||||
|
|
||||||
@ -95,7 +95,8 @@ if networked and smem_dev.modem == nil then
|
|||||||
plc_state.no_modem = true
|
plc_state.no_modem = true
|
||||||
end
|
end
|
||||||
|
|
||||||
function init()
|
-- PLC init
|
||||||
|
local init = function ()
|
||||||
if plc_state.init_ok then
|
if plc_state.init_ok then
|
||||||
-- just booting up, no fission allowed (neutrons stay put thanks)
|
-- just booting up, no fission allowed (neutrons stay put thanks)
|
||||||
smem_dev.reactor.scram()
|
smem_dev.reactor.scram()
|
||||||
@ -117,6 +118,7 @@ function init()
|
|||||||
log.debug("init> running without networking")
|
log.debug("init> running without networking")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@diagnostic disable-next-line: undefined-field
|
||||||
os.queueEvent("clock_start")
|
os.queueEvent("clock_start")
|
||||||
|
|
||||||
println("boot> completed");
|
println("boot> completed");
|
||||||
@ -155,7 +157,7 @@ if __shared_memory.networked then
|
|||||||
smem_sys.plc_comms.send_rps_status()
|
smem_sys.plc_comms.send_rps_status()
|
||||||
|
|
||||||
-- close connection
|
-- close connection
|
||||||
smem_sys.plc_comms.close(smem_sys.conn_watchdog)
|
smem_sys.plc_comms.close()
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- run threads, excluding comms
|
-- run threads, excluding comms
|
||||||
|
|||||||
@ -51,6 +51,7 @@ threads.thread__main = function (smem, init)
|
|||||||
|
|
||||||
-- event loop
|
-- event loop
|
||||||
while true do
|
while true do
|
||||||
|
---@diagnostic disable-next-line: undefined-field
|
||||||
local event, param1, param2, param3, param4, param5 = os.pullEventRaw()
|
local event, param1, param2, param3, param4, param5 = os.pullEventRaw()
|
||||||
|
|
||||||
-- handle event
|
-- handle event
|
||||||
@ -443,7 +444,7 @@ threads.thread__setpoint_control = function (smem)
|
|||||||
if running then
|
if running then
|
||||||
-- do not use the actual elapsed time, it could spike
|
-- do not use the actual elapsed time, it could spike
|
||||||
-- we do not want to have big jumps as that is what we are trying to avoid in the first place
|
-- we do not want to have big jumps as that is what we are trying to avoid in the first place
|
||||||
local min_elapsed_s = SETPOINT_CTRL_SLEEP / 1000.0
|
local min_elapsed_s = SP_CTRL_SLEEP / 1000.0
|
||||||
|
|
||||||
-- clear so we can later evaluate if we should keep running
|
-- clear so we can later evaluate if we should keep running
|
||||||
running = false
|
running = false
|
||||||
|
|||||||
@ -27,7 +27,7 @@ redstone_rtu.new = function ()
|
|||||||
return digital_read(rs.getInput(side))
|
return digital_read(rs.getInput(side))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self.rtu.connect_di(f_read)
|
self.rtu.connect_di(f_read)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ redstone_rtu.new = function ()
|
|||||||
rs.setOutput(side, digital_is_active(channel, level))
|
rs.setOutput(side, digital_is_active(channel, level))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self.rtu.connect_coil(f_read, f_write)
|
self.rtu.connect_coil(f_read, f_write)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -64,7 +64,7 @@ modbus.new = function (rtu_dev, use_parallel_read)
|
|||||||
local access_fault = false
|
local access_fault = false
|
||||||
local discrete_inputs, _, _, _ = self.rtu.io_count()
|
local discrete_inputs, _, _, _ = self.rtu.io_count()
|
||||||
local return_ok = ((di_addr_start + count) <= discrete_inputs) and (count > 0)
|
local return_ok = ((di_addr_start + count) <= discrete_inputs) and (count > 0)
|
||||||
|
|
||||||
if return_ok then
|
if return_ok then
|
||||||
for i = 1, count do
|
for i = 1, count do
|
||||||
local addr = di_addr_start + i - 1
|
local addr = di_addr_start + i - 1
|
||||||
@ -197,7 +197,7 @@ modbus.new = function (rtu_dev, use_parallel_read)
|
|||||||
|
|
||||||
if access_fault then
|
if access_fault then
|
||||||
return_ok = false
|
return_ok = false
|
||||||
readings = MODBUS_EXCODE.SERVER_DEVICE_FAIL
|
response = MODBUS_EXCODE.SERVER_DEVICE_FAIL
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
response = MODBUS_EXCODE.ILLEGAL_DATA_ADDR
|
response = MODBUS_EXCODE.ILLEGAL_DATA_ADDR
|
||||||
@ -210,13 +210,13 @@ modbus.new = function (rtu_dev, use_parallel_read)
|
|||||||
local response = nil
|
local response = nil
|
||||||
local _, _, _, hold_regs = self.rtu.io_count()
|
local _, _, _, hold_regs = self.rtu.io_count()
|
||||||
local return_ok = hr_addr <= hold_regs
|
local return_ok = hr_addr <= hold_regs
|
||||||
|
|
||||||
if return_ok then
|
if return_ok then
|
||||||
local access_fault = self.rtu.write_holding_reg(hr_addr, value)
|
local access_fault = self.rtu.write_holding_reg(hr_addr, value)
|
||||||
|
|
||||||
if access_fault then
|
if access_fault then
|
||||||
return_ok = false
|
return_ok = false
|
||||||
readings = MODBUS_EXCODE.SERVER_DEVICE_FAIL
|
response = MODBUS_EXCODE.SERVER_DEVICE_FAIL
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
response = MODBUS_EXCODE.ILLEGAL_DATA_ADDR
|
response = MODBUS_EXCODE.ILLEGAL_DATA_ADDR
|
||||||
@ -238,7 +238,7 @@ modbus.new = function (rtu_dev, use_parallel_read)
|
|||||||
|
|
||||||
if access_fault then
|
if access_fault then
|
||||||
return_ok = false
|
return_ok = false
|
||||||
readings = MODBUS_EXCODE.SERVER_DEVICE_FAIL
|
response = MODBUS_EXCODE.SERVER_DEVICE_FAIL
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -262,7 +262,7 @@ modbus.new = function (rtu_dev, use_parallel_read)
|
|||||||
|
|
||||||
if access_fault then
|
if access_fault then
|
||||||
return_ok = false
|
return_ok = false
|
||||||
readings = MODBUS_EXCODE.SERVER_DEVICE_FAIL
|
response = MODBUS_EXCODE.SERVER_DEVICE_FAIL
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
12
rtu/rtu.lua
12
rtu/rtu.lua
@ -1,6 +1,8 @@
|
|||||||
local comms = require("scada-common.comms")
|
local comms = require("scada-common.comms")
|
||||||
local ppm = require("scada-common.ppm")
|
local ppm = require("scada-common.ppm")
|
||||||
|
local log = require("scada-common.log")
|
||||||
local types = require("scada-common.types")
|
local types = require("scada-common.types")
|
||||||
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
local modbus = require("modbus")
|
local modbus = require("modbus")
|
||||||
|
|
||||||
@ -12,6 +14,11 @@ local PROTOCOLS = comms.PROTOCOLS
|
|||||||
local SCADA_MGMT_TYPES = comms.SCADA_MGMT_TYPES
|
local SCADA_MGMT_TYPES = comms.SCADA_MGMT_TYPES
|
||||||
local RTU_ADVERT_TYPES = comms.RTU_ADVERT_TYPES
|
local RTU_ADVERT_TYPES = comms.RTU_ADVERT_TYPES
|
||||||
|
|
||||||
|
local print = util.print
|
||||||
|
local println = util.println
|
||||||
|
local print_ts = util.print_ts
|
||||||
|
local println_ts = util.println_ts
|
||||||
|
|
||||||
rtu.init_unit = function ()
|
rtu.init_unit = function ()
|
||||||
local self = {
|
local self = {
|
||||||
discrete_inputs = {},
|
discrete_inputs = {},
|
||||||
@ -136,6 +143,8 @@ rtu.comms = function (modem, local_port, server_port, conn_watchdog)
|
|||||||
conn_watchdog = conn_watchdog
|
conn_watchdog = conn_watchdog
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local insert = table.insert
|
||||||
|
|
||||||
-- open modem
|
-- open modem
|
||||||
if not self.modem.isOpen(self.l_port) then
|
if not self.modem.isOpen(self.l_port) then
|
||||||
self.modem.open(self.l_port)
|
self.modem.open(self.l_port)
|
||||||
@ -337,7 +346,7 @@ rtu.comms = function (modem, local_port, server_port, conn_watchdog)
|
|||||||
send_advertisement(units)
|
send_advertisement(units)
|
||||||
else
|
else
|
||||||
-- not supported
|
-- not supported
|
||||||
log.warning("RTU got unexpected SCADA message type " .. packet.type, true)
|
log.warning("RTU got unexpected SCADA message type " .. packet.type)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- should be unreachable assuming packet is from parse_packet()
|
-- should be unreachable assuming packet is from parse_packet()
|
||||||
@ -352,7 +361,6 @@ rtu.comms = function (modem, local_port, server_port, conn_watchdog)
|
|||||||
parse_packet = parse_packet,
|
parse_packet = parse_packet,
|
||||||
handle_packet = handle_packet,
|
handle_packet = handle_packet,
|
||||||
send_advertisement = send_advertisement,
|
send_advertisement = send_advertisement,
|
||||||
send_heartbeat = send_heartbeat,
|
|
||||||
unlink = unlink,
|
unlink = unlink,
|
||||||
close = close
|
close = close
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,7 @@ local imatrix_rtu = require("dev.imatrix_rtu")
|
|||||||
local turbine_rtu = require("dev.turbine_rtu")
|
local turbine_rtu = require("dev.turbine_rtu")
|
||||||
local turbinev_rtu = require("dev.turbinev_rtu")
|
local turbinev_rtu = require("dev.turbinev_rtu")
|
||||||
|
|
||||||
local RTU_VERSION = "alpha-v0.6.1"
|
local RTU_VERSION = "alpha-v0.6.2"
|
||||||
|
|
||||||
local rtu_t = types.rtu_t
|
local rtu_t = types.rtu_t
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
local comms = require("scada-common.comms")
|
local comms = require("scada-common.comms")
|
||||||
local log = require("scada-common.log")
|
local log = require("scada-common.log")
|
||||||
|
local mqueue = require("scada-common.mqueue")
|
||||||
local ppm = require("scada-common.ppm")
|
local ppm = require("scada-common.ppm")
|
||||||
local types = require("scada-common.types")
|
local types = require("scada-common.types")
|
||||||
local util = require("scada-common.util")
|
local util = require("scada-common.util")
|
||||||
@ -46,6 +47,7 @@ threads.thread__main = function (smem)
|
|||||||
|
|
||||||
-- event loop
|
-- event loop
|
||||||
while true do
|
while true do
|
||||||
|
---@diagnostic disable-next-line: undefined-field
|
||||||
local event, param1, param2, param3, param4, param5 = os.pullEventRaw()
|
local event, param1, param2, param3, param4, param5 = os.pullEventRaw()
|
||||||
|
|
||||||
if event == "timer" and param1 == loop_clock then
|
if event == "timer" and param1 == loop_clock then
|
||||||
@ -210,6 +212,7 @@ threads.thread__unit_comms = function (smem, unit)
|
|||||||
|
|
||||||
-- load in from shared memory
|
-- load in from shared memory
|
||||||
local rtu_state = smem.rtu_state
|
local rtu_state = smem.rtu_state
|
||||||
|
local rtu_comms = smem.rtu_sys.rtu_comms
|
||||||
local packet_queue = unit.pkt_queue
|
local packet_queue = unit.pkt_queue
|
||||||
|
|
||||||
local last_update = util.time()
|
local last_update = util.time()
|
||||||
@ -228,7 +231,7 @@ threads.thread__unit_comms = function (smem, unit)
|
|||||||
-- received a packet
|
-- received a packet
|
||||||
unit.modbus_busy = true
|
unit.modbus_busy = true
|
||||||
local return_code, reply = unit.modbus_io.handle_packet(packet)
|
local return_code, reply = unit.modbus_io.handle_packet(packet)
|
||||||
rtu.send_modbus(reply)
|
rtu_comms.send_modbus(reply)
|
||||||
unit.modbus_busy = false
|
unit.modbus_busy = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,10 @@ 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
|
||||||
|
|
||||||
|
local PERIODICS = {
|
||||||
|
KEEP_ALIVE = 2.0
|
||||||
|
}
|
||||||
|
|
||||||
rtu.new_session = function (id, in_queue, out_queue)
|
rtu.new_session = function (id, in_queue, out_queue)
|
||||||
local log_header = "rtu_session(" .. id .. "): "
|
local log_header = "rtu_session(" .. id .. "): "
|
||||||
|
|
||||||
@ -97,7 +101,6 @@ rtu.new_session = function (id, in_queue, out_queue)
|
|||||||
-- RTU unit advertisement
|
-- RTU unit advertisement
|
||||||
for i = 1, packet.length do
|
for i = 1, packet.length do
|
||||||
local unit = packet.data[i]
|
local unit = packet.data[i]
|
||||||
unit
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "handler received unsupported SCADA_MGMT packet type " .. pkt.type)
|
log.debug(log_header .. "handler received unsupported SCADA_MGMT packet type " .. pkt.type)
|
||||||
|
|||||||
@ -97,7 +97,7 @@ local function _free_closed(sessions)
|
|||||||
for i = 1, #sessions do
|
for i = 1, #sessions do
|
||||||
local session = sessions[i]
|
local session = sessions[i]
|
||||||
if session ~= nil then
|
if session ~= nil then
|
||||||
if sessions[i].open then
|
if session.open then
|
||||||
if sessions[move_to] == nil then
|
if sessions[move_to] == nil then
|
||||||
sessions[move_to] = session
|
sessions[move_to] = session
|
||||||
sessions[i] = nil
|
sessions[i] = nil
|
||||||
|
|||||||
@ -45,18 +45,18 @@ unit.new = function (for_reactor)
|
|||||||
table.insert(self.turbines, turbine)
|
table.insert(self.turbines, turbine)
|
||||||
end
|
end
|
||||||
|
|
||||||
public.add_boiler = function (turbine)
|
public.add_boiler = function (boiler)
|
||||||
table.insert(self.boilers, boiler)
|
table.insert(self.boilers, boiler)
|
||||||
end
|
end
|
||||||
|
|
||||||
public.add_redstone = function (field, accessor)
|
public.add_redstone = function (field, accessor)
|
||||||
-- ensure field exists
|
-- ensure field exists
|
||||||
if redstone[field] == nil then
|
if self.redstone[field] == nil then
|
||||||
redstone[field] = {}
|
self.redstone[field] = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
-- insert into list
|
-- insert into list
|
||||||
table.insert(redstone[field], accessor)
|
table.insert(self.redstone[field], accessor)
|
||||||
end
|
end
|
||||||
|
|
||||||
local _update_annunciator = function ()
|
local _update_annunciator = function ()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user