#118 RTU/PLC code cleanup

This commit is contained in:
Mikayla Fischler
2023-02-21 23:50:43 -05:00
parent ce0198f389
commit 79494f0587
14 changed files with 222 additions and 208 deletions

View File

@@ -7,22 +7,15 @@ local MODBUS_FCODE = types.MODBUS_FCODE
local MODBUS_EXCODE = types.MODBUS_EXCODE
-- new modbus comms handler object
---@nodiscard
---@param rtu_dev rtu_device|rtu_rs_device RTU device
---@param use_parallel_read boolean whether or not to use parallel calls when reading
function modbus.new(rtu_dev, use_parallel_read)
local self = {
rtu = rtu_dev,
use_parallel = use_parallel_read
}
---@class modbus
local public = {}
local insert = table.insert
-- read a span of coils (digital outputs)
--
-- read a span of coils (digital outputs)<br>
-- returns a table of readings or a MODBUS_EXCODE error code
---@nodiscard
---@param c_addr_start integer
---@param count integer
---@return boolean ok, table|MODBUS_EXCODE readings
@@ -30,20 +23,20 @@ function modbus.new(rtu_dev, use_parallel_read)
local tasks = {}
local readings = {} ---@type table|MODBUS_EXCODE
local access_fault = false
local _, coils, _, _ = self.rtu.io_count()
local _, coils, _, _ = rtu_dev.io_count()
local return_ok = ((c_addr_start + count) <= (coils + 1)) and (count > 0)
if return_ok then
for i = 1, count do
local addr = c_addr_start + i - 1
if self.use_parallel then
if use_parallel_read then
insert(tasks, function ()
local reading, fault = self.rtu.read_coil(addr)
local reading, fault = rtu_dev.read_coil(addr)
if fault then access_fault = true else readings[i] = reading end
end)
else
readings[i], access_fault = self.rtu.read_coil(addr)
readings[i], access_fault = rtu_dev.read_coil(addr)
if access_fault then
return_ok = false
@@ -54,7 +47,7 @@ function modbus.new(rtu_dev, use_parallel_read)
end
-- run parallel tasks if configured
if self.use_parallel then
if use_parallel_read then
parallel.waitForAll(table.unpack(tasks))
end
@@ -69,9 +62,9 @@ function modbus.new(rtu_dev, use_parallel_read)
return return_ok, readings
end
-- read a span of discrete inputs (digital inputs)
--
-- read a span of discrete inputs (digital inputs)<br>
-- returns a table of readings or a MODBUS_EXCODE error code
---@nodiscard
---@param di_addr_start integer
---@param count integer
---@return boolean ok, table|MODBUS_EXCODE readings
@@ -79,20 +72,20 @@ function modbus.new(rtu_dev, use_parallel_read)
local tasks = {}
local readings = {} ---@type table|MODBUS_EXCODE
local access_fault = false
local discrete_inputs, _, _, _ = self.rtu.io_count()
local discrete_inputs, _, _, _ = rtu_dev.io_count()
local return_ok = ((di_addr_start + count) <= (discrete_inputs + 1)) and (count > 0)
if return_ok then
for i = 1, count do
local addr = di_addr_start + i - 1
if self.use_parallel then
if use_parallel_read then
insert(tasks, function ()
local reading, fault = self.rtu.read_di(addr)
local reading, fault = rtu_dev.read_di(addr)
if fault then access_fault = true else readings[i] = reading end
end)
else
readings[i], access_fault = self.rtu.read_di(addr)
readings[i], access_fault = rtu_dev.read_di(addr)
if access_fault then
return_ok = false
@@ -103,7 +96,7 @@ function modbus.new(rtu_dev, use_parallel_read)
end
-- run parallel tasks if configured
if self.use_parallel then
if use_parallel_read then
parallel.waitForAll(table.unpack(tasks))
end
@@ -118,9 +111,9 @@ function modbus.new(rtu_dev, use_parallel_read)
return return_ok, readings
end
-- read a span of holding registers (analog outputs)
--
-- read a span of holding registers (analog outputs)<br>
-- returns a table of readings or a MODBUS_EXCODE error code
---@nodiscard
---@param hr_addr_start integer
---@param count integer
---@return boolean ok, table|MODBUS_EXCODE readings
@@ -128,20 +121,20 @@ function modbus.new(rtu_dev, use_parallel_read)
local tasks = {}
local readings = {} ---@type table|MODBUS_EXCODE
local access_fault = false
local _, _, _, hold_regs = self.rtu.io_count()
local _, _, _, hold_regs = rtu_dev.io_count()
local return_ok = ((hr_addr_start + count) <= (hold_regs + 1)) and (count > 0)
if return_ok then
for i = 1, count do
local addr = hr_addr_start + i - 1
if self.use_parallel then
if use_parallel_read then
insert(tasks, function ()
local reading, fault = self.rtu.read_holding_reg(addr)
local reading, fault = rtu_dev.read_holding_reg(addr)
if fault then access_fault = true else readings[i] = reading end
end)
else
readings[i], access_fault = self.rtu.read_holding_reg(addr)
readings[i], access_fault = rtu_dev.read_holding_reg(addr)
if access_fault then
return_ok = false
@@ -152,7 +145,7 @@ function modbus.new(rtu_dev, use_parallel_read)
end
-- run parallel tasks if configured
if self.use_parallel then
if use_parallel_read then
parallel.waitForAll(table.unpack(tasks))
end
@@ -167,9 +160,9 @@ function modbus.new(rtu_dev, use_parallel_read)
return return_ok, readings
end
-- read a span of input registers (analog inputs)
--
-- read a span of input registers (analog inputs)<br>
-- returns a table of readings or a MODBUS_EXCODE error code
---@nodiscard
---@param ir_addr_start integer
---@param count integer
---@return boolean ok, table|MODBUS_EXCODE readings
@@ -177,20 +170,20 @@ function modbus.new(rtu_dev, use_parallel_read)
local tasks = {}
local readings = {} ---@type table|MODBUS_EXCODE
local access_fault = false
local _, _, input_regs, _ = self.rtu.io_count()
local _, _, input_regs, _ = rtu_dev.io_count()
local return_ok = ((ir_addr_start + count) <= (input_regs + 1)) and (count > 0)
if return_ok then
for i = 1, count do
local addr = ir_addr_start + i - 1
if self.use_parallel then
if use_parallel_read then
insert(tasks, function ()
local reading, fault = self.rtu.read_input_reg(addr)
local reading, fault = rtu_dev.read_input_reg(addr)
if fault then access_fault = true else readings[i] = reading end
end)
else
readings[i], access_fault = self.rtu.read_input_reg(addr)
readings[i], access_fault = rtu_dev.read_input_reg(addr)
if access_fault then
return_ok = false
@@ -201,7 +194,7 @@ function modbus.new(rtu_dev, use_parallel_read)
end
-- run parallel tasks if configured
if self.use_parallel then
if use_parallel_read then
parallel.waitForAll(table.unpack(tasks))
end
@@ -217,16 +210,17 @@ function modbus.new(rtu_dev, use_parallel_read)
end
-- write a single coil (digital output)
---@nodiscard
---@param c_addr integer
---@param value any
---@return boolean ok, MODBUS_EXCODE
local function _5_write_single_coil(c_addr, value)
local response = nil
local _, coils, _, _ = self.rtu.io_count()
local _, coils, _, _ = rtu_dev.io_count()
local return_ok = c_addr <= coils
if return_ok then
local access_fault = self.rtu.write_coil(c_addr, value)
local access_fault = rtu_dev.write_coil(c_addr, value)
if access_fault then
return_ok = false
@@ -240,16 +234,17 @@ function modbus.new(rtu_dev, use_parallel_read)
end
-- write a single holding register (analog output)
---@nodiscard
---@param hr_addr integer
---@param value any
---@return boolean ok, MODBUS_EXCODE
local function _6_write_single_holding_register(hr_addr, value)
local response = nil
local _, _, _, hold_regs = self.rtu.io_count()
local _, _, _, hold_regs = rtu_dev.io_count()
local return_ok = hr_addr <= hold_regs
if return_ok then
local access_fault = self.rtu.write_holding_reg(hr_addr, value)
local access_fault = rtu_dev.write_holding_reg(hr_addr, value)
if access_fault then
return_ok = false
@@ -263,19 +258,20 @@ function modbus.new(rtu_dev, use_parallel_read)
end
-- write multiple coils (digital outputs)
---@nodiscard
---@param c_addr_start integer
---@param values any
---@return boolean ok, MODBUS_EXCODE
local function _15_write_multiple_coils(c_addr_start, values)
local response = nil
local _, coils, _, _ = self.rtu.io_count()
local _, coils, _, _ = rtu_dev.io_count()
local count = #values
local return_ok = ((c_addr_start + count) <= (coils + 1)) and (count > 0)
if return_ok then
for i = 1, count do
local addr = c_addr_start + i - 1
local access_fault = self.rtu.write_coil(addr, values[i])
local access_fault = rtu_dev.write_coil(addr, values[i])
if access_fault then
return_ok = false
@@ -291,19 +287,20 @@ function modbus.new(rtu_dev, use_parallel_read)
end
-- write multiple holding registers (analog outputs)
---@nodiscard
---@param hr_addr_start integer
---@param values any
---@return boolean ok, MODBUS_EXCODE
local function _16_write_multiple_holding_registers(hr_addr_start, values)
local response = nil
local _, _, _, hold_regs = self.rtu.io_count()
local _, _, _, hold_regs = rtu_dev.io_count()
local count = #values
local return_ok = ((hr_addr_start + count) <= (hold_regs + 1)) and (count > 0)
if return_ok then
for i = 1, count do
local addr = hr_addr_start + i - 1
local access_fault = self.rtu.write_holding_reg(addr, values[i])
local access_fault = rtu_dev.write_holding_reg(addr, values[i])
if access_fault then
return_ok = false
@@ -318,7 +315,11 @@ function modbus.new(rtu_dev, use_parallel_read)
return return_ok, response
end
---@class modbus
local public = {}
-- validate a request without actually executing it
---@nodiscard
---@param packet modbus_frame
---@return boolean return_code, modbus_packet reply
function public.check_request(packet)
@@ -360,6 +361,7 @@ function modbus.new(rtu_dev, use_parallel_read)
end
-- handle a MODBUS TCP packet and generate a reply
---@nodiscard
---@param packet modbus_frame
---@return boolean return_code, modbus_packet reply
function public.handle_packet(packet)
@@ -420,6 +422,7 @@ function modbus.new(rtu_dev, use_parallel_read)
end
-- return a SERVER_DEVICE_BUSY error reply
---@nodiscard
---@param packet modbus_frame MODBUS packet frame
---@return modbus_packet reply
function modbus.reply__srv_device_busy(packet)
@@ -432,6 +435,7 @@ function modbus.reply__srv_device_busy(packet)
end
-- return a NEG_ACKNOWLEDGE error reply
---@nodiscard
---@param packet modbus_frame MODBUS packet frame
---@return modbus_packet reply
function modbus.reply__neg_ack(packet)
@@ -444,6 +448,7 @@ function modbus.reply__neg_ack(packet)
end
-- return a GATEWAY_PATH_UNAVAILABLE error reply
---@nodiscard
---@param packet modbus_frame MODBUS packet frame
---@return modbus_packet reply
function modbus.reply__gw_unavailable(packet)