Merge pull request #598 from MikaylaFischler/559-modbus-device-busy-unrecoverable
559 modbus device busy unrecoverable
This commit is contained in:
commit
cbc84c5998
12
rtu/rtu.lua
12
rtu/rtu.lua
@ -481,16 +481,14 @@ function rtu.comms(version, nic, conn_watchdog)
|
|||||||
-- check validity then pass off to unit comms thread
|
-- check validity then pass off to unit comms thread
|
||||||
return_code, reply = unit.modbus_io.check_request(packet)
|
return_code, reply = unit.modbus_io.check_request(packet)
|
||||||
if return_code then
|
if return_code then
|
||||||
-- check if there are more than 3 active transactions
|
-- check if there are more than 3 active transactions, which will be treated as busy
|
||||||
-- still queue the packet, but this may indicate a problem
|
|
||||||
if unit.pkt_queue.length() > 3 then
|
if unit.pkt_queue.length() > 3 then
|
||||||
reply = modbus.reply__srv_device_busy(packet)
|
reply = modbus.reply__srv_device_busy(packet)
|
||||||
log.debug("queueing new request with " .. unit.pkt_queue.length() ..
|
log.warning("device busy, discarding new request" .. unit_dbg_tag)
|
||||||
" transactions already in the queue" .. unit_dbg_tag)
|
else
|
||||||
end
|
-- queue the command if not busy
|
||||||
|
|
||||||
-- always queue the command even if busy
|
|
||||||
unit.pkt_queue.push_packet(packet)
|
unit.pkt_queue.push_packet(packet)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
log.warning("cannot perform requested MODBUS operation" .. unit_dbg_tag)
|
log.warning("cannot perform requested MODBUS operation" .. unit_dbg_tag)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -31,7 +31,7 @@ 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 = "v1.10.21"
|
local RTU_VERSION = "v1.11.0"
|
||||||
|
|
||||||
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
||||||
local RTU_HW_STATE = databus.RTU_HW_STATE
|
local RTU_HW_STATE = databus.RTU_HW_STATE
|
||||||
|
|||||||
@ -105,27 +105,39 @@ function boilerv.new(session_id, unit_id, advert, out_queue)
|
|||||||
-- PRIVATE FUNCTIONS --
|
-- PRIVATE FUNCTIONS --
|
||||||
|
|
||||||
-- query if the multiblock is formed
|
-- query if the multiblock is formed
|
||||||
local function _request_formed()
|
---@param time_now integer
|
||||||
|
local function _request_formed(time_now)
|
||||||
-- read discrete input 1 (start = 1, count = 1)
|
-- read discrete input 1 (start = 1, count = 1)
|
||||||
self.session.send_request(TXN_TYPES.FORMED, MODBUS_FCODE.READ_DISCRETE_INPUTS, { 1, 1 })
|
if self.session.send_request(TXN_TYPES.FORMED, MODBUS_FCODE.READ_DISCRETE_INPUTS, { 1, 1 }) ~= false then
|
||||||
|
self.periodics.next_formed_req = time_now + PERIODICS.FORMED
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the build of the device
|
-- query the build of the device
|
||||||
local function _request_build()
|
---@param time_now integer
|
||||||
|
local function _request_build(time_now)
|
||||||
-- read input registers 1 through 12 (start = 1, count = 12)
|
-- read input registers 1 through 12 (start = 1, count = 12)
|
||||||
self.session.send_request(TXN_TYPES.BUILD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 12 })
|
if self.session.send_request(TXN_TYPES.BUILD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 12 }) ~= false then
|
||||||
|
self.periodics.next_build_req = time_now + PERIODICS.BUILD
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the state of the device
|
-- query the state of the device
|
||||||
local function _request_state()
|
---@param time_now integer
|
||||||
|
local function _request_state(time_now)
|
||||||
-- read input registers 13 through 15 (start = 13, count = 3)
|
-- read input registers 13 through 15 (start = 13, count = 3)
|
||||||
self.session.send_request(TXN_TYPES.STATE, MODBUS_FCODE.READ_INPUT_REGS, { 13, 3 })
|
if self.session.send_request(TXN_TYPES.STATE, MODBUS_FCODE.READ_INPUT_REGS, { 13, 3 }) ~= false then
|
||||||
|
self.periodics.next_state_req = time_now + PERIODICS.STATE
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the tanks of the device
|
-- query the tanks of the device
|
||||||
local function _request_tanks()
|
---@param time_now integer
|
||||||
|
local function _request_tanks(time_now)
|
||||||
-- read input registers 16 through 27 (start = 16, count = 12)
|
-- read input registers 16 through 27 (start = 16, count = 12)
|
||||||
self.session.send_request(TXN_TYPES.TANKS, MODBUS_FCODE.READ_INPUT_REGS, { 16, 12 })
|
if self.session.send_request(TXN_TYPES.TANKS, MODBUS_FCODE.READ_INPUT_REGS, { 16, 12 }) ~= false then
|
||||||
|
self.periodics.next_tanks_req = time_now + PERIODICS.TANKS
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- PUBLIC FUNCTIONS --
|
-- PUBLIC FUNCTIONS --
|
||||||
@ -210,26 +222,12 @@ function boilerv.new(session_id, unit_id, advert, out_queue)
|
|||||||
-- update this runner
|
-- update this runner
|
||||||
---@param time_now integer milliseconds
|
---@param time_now integer milliseconds
|
||||||
function public.update(time_now)
|
function public.update(time_now)
|
||||||
if self.periodics.next_formed_req <= time_now then
|
if self.periodics.next_formed_req <= time_now then _request_formed(time_now) end
|
||||||
_request_formed()
|
|
||||||
self.periodics.next_formed_req = time_now + PERIODICS.FORMED
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.db.formed then
|
if self.db.formed then
|
||||||
if not self.has_build and self.periodics.next_build_req <= time_now then
|
if not self.has_build and self.periodics.next_build_req <= time_now then _request_build(time_now) end
|
||||||
_request_build()
|
if self.periodics.next_state_req <= time_now then _request_state(time_now) end
|
||||||
self.periodics.next_build_req = time_now + PERIODICS.BUILD
|
if self.periodics.next_tanks_req <= time_now then _request_tanks(time_now) end
|
||||||
end
|
|
||||||
|
|
||||||
if self.periodics.next_state_req <= time_now then
|
|
||||||
_request_state()
|
|
||||||
self.periodics.next_state_req = time_now + PERIODICS.STATE
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.periodics.next_tanks_req <= time_now then
|
|
||||||
_request_tanks()
|
|
||||||
self.periodics.next_tanks_req = time_now + PERIODICS.TANKS
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
self.session.post_update()
|
self.session.post_update()
|
||||||
|
|||||||
@ -42,6 +42,8 @@ local PERIODICS = {
|
|||||||
TANKS = 500
|
TANKS = 500
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local WRITE_BUSY_WAIT = 1000
|
||||||
|
|
||||||
-- create a new dynamicv rtu session runner
|
-- create a new dynamicv rtu session runner
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
---@param session_id integer RTU gateway session ID
|
---@param session_id integer RTU gateway session ID
|
||||||
@ -63,6 +65,8 @@ function dynamicv.new(session_id, unit_id, advert, out_queue)
|
|||||||
local self = {
|
local self = {
|
||||||
session = unit_session.new(session_id, unit_id, advert, out_queue, log_tag, TXN_TAGS),
|
session = unit_session.new(session_id, unit_id, advert, out_queue, log_tag, TXN_TAGS),
|
||||||
has_build = false,
|
has_build = false,
|
||||||
|
mode_cmd = nil, ---@type container_mode|nil
|
||||||
|
resend_mode = false,
|
||||||
periodics = {
|
periodics = {
|
||||||
next_formed_req = 0,
|
next_formed_req = 0,
|
||||||
next_build_req = 0,
|
next_build_req = 0,
|
||||||
@ -101,45 +105,77 @@ function dynamicv.new(session_id, unit_id, advert, out_queue)
|
|||||||
|
|
||||||
-- increment the container mode
|
-- increment the container mode
|
||||||
local function _inc_cont_mode()
|
local function _inc_cont_mode()
|
||||||
|
-- set mode command
|
||||||
|
if self.mode_cmd == "BOTH" then self.mode_cmd = "FILL"
|
||||||
|
elseif self.mode_cmd == "FILL" then self.mode_cmd = "EMPTY"
|
||||||
|
elseif self.mode_cmd == "EMPTY" then self.mode_cmd = "BOTH"
|
||||||
|
end
|
||||||
|
|
||||||
-- write coil 1 with unused value 0
|
-- write coil 1 with unused value 0
|
||||||
self.session.send_request(TXN_TYPES.INC_CONT, MODBUS_FCODE.WRITE_SINGLE_COIL, { 1, 0 })
|
if self.session.send_request(TXN_TYPES.INC_CONT, MODBUS_FCODE.WRITE_SINGLE_COIL, { 1, 0 }, WRITE_BUSY_WAIT) == false then
|
||||||
|
self.resend_mode = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- decrement the container mode
|
-- decrement the container mode
|
||||||
local function _dec_cont_mode()
|
local function _dec_cont_mode()
|
||||||
|
-- set mode command
|
||||||
|
if self.mode_cmd == "BOTH" then self.mode_cmd = "EMPTY"
|
||||||
|
elseif self.mode_cmd == "EMPTY" then self.mode_cmd = "FILL"
|
||||||
|
elseif self.mode_cmd == "FILL" then self.mode_cmd = "BOTH"
|
||||||
|
end
|
||||||
|
|
||||||
-- write coil 2 with unused value 0
|
-- write coil 2 with unused value 0
|
||||||
self.session.send_request(TXN_TYPES.DEC_CONT, MODBUS_FCODE.WRITE_SINGLE_COIL, { 2, 0 })
|
if self.session.send_request(TXN_TYPES.DEC_CONT, MODBUS_FCODE.WRITE_SINGLE_COIL, { 2, 0 , WRITE_BUSY_WAIT}) == false then
|
||||||
|
self.resend_mode = false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- set the container mode
|
-- set the container mode
|
||||||
---@param mode container_mode
|
---@param mode container_mode
|
||||||
local function _set_cont_mode(mode)
|
local function _set_cont_mode(mode)
|
||||||
|
self.mode_cmd = mode
|
||||||
|
|
||||||
-- write holding register 1
|
-- write holding register 1
|
||||||
self.session.send_request(TXN_TYPES.SET_CONT, MODBUS_FCODE.WRITE_SINGLE_HOLD_REG, { 1, mode })
|
if self.session.send_request(TXN_TYPES.SET_CONT, MODBUS_FCODE.WRITE_SINGLE_HOLD_REG, { 1, mode }, WRITE_BUSY_WAIT) == false then
|
||||||
|
self.resend_mode = false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query if the multiblock is formed
|
-- query if the multiblock is formed
|
||||||
local function _request_formed()
|
---@param time_now integer
|
||||||
|
local function _request_formed(time_now)
|
||||||
-- read discrete input 1 (start = 1, count = 1)
|
-- read discrete input 1 (start = 1, count = 1)
|
||||||
self.session.send_request(TXN_TYPES.FORMED, MODBUS_FCODE.READ_DISCRETE_INPUTS, { 1, 1 })
|
if self.session.send_request(TXN_TYPES.FORMED, MODBUS_FCODE.READ_DISCRETE_INPUTS, { 1, 1 }) ~= false then
|
||||||
|
self.periodics.next_formed_req = time_now + PERIODICS.FORMED
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the build of the device
|
-- query the build of the device
|
||||||
local function _request_build()
|
---@param time_now integer
|
||||||
|
local function _request_build(time_now)
|
||||||
-- read input registers 1 through 7 (start = 1, count = 7)
|
-- read input registers 1 through 7 (start = 1, count = 7)
|
||||||
self.session.send_request(TXN_TYPES.BUILD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 7 })
|
if self.session.send_request(TXN_TYPES.BUILD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 7 }) ~= false then
|
||||||
|
self.periodics.next_build_req = time_now + PERIODICS.BUILD
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the state of the device
|
-- query the state of the device
|
||||||
local function _request_state()
|
---@param time_now integer
|
||||||
|
local function _request_state(time_now)
|
||||||
-- read holding register 1 (start = 1, count = 1)
|
-- read holding register 1 (start = 1, count = 1)
|
||||||
self.session.send_request(TXN_TYPES.STATE, MODBUS_FCODE.READ_MUL_HOLD_REGS, { 1, 1 })
|
if self.session.send_request(TXN_TYPES.STATE, MODBUS_FCODE.READ_MUL_HOLD_REGS, { 1, 1 }) ~= false then
|
||||||
|
self.periodics.next_state_req = time_now + PERIODICS.STATE
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the tanks of the device
|
-- query the tanks of the device
|
||||||
local function _request_tanks()
|
---@param time_now integer
|
||||||
|
local function _request_tanks(time_now)
|
||||||
-- read input registers 8 through 9 (start = 8, count = 2)
|
-- read input registers 8 through 9 (start = 8, count = 2)
|
||||||
self.session.send_request(TXN_TYPES.TANKS, MODBUS_FCODE.READ_INPUT_REGS, { 8, 2 })
|
if self.session.send_request(TXN_TYPES.TANKS, MODBUS_FCODE.READ_INPUT_REGS, { 8, 2 }) ~= false then
|
||||||
|
self.periodics.next_tanks_req = time_now + PERIODICS.TANKS
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- PUBLIC FUNCTIONS --
|
-- PUBLIC FUNCTIONS --
|
||||||
@ -182,6 +218,10 @@ function dynamicv.new(session_id, unit_id, advert, out_queue)
|
|||||||
if m_pkt.length == 1 then
|
if m_pkt.length == 1 then
|
||||||
self.db.state.last_update = util.time_ms()
|
self.db.state.last_update = util.time_ms()
|
||||||
self.db.state.container_mode = m_pkt.data[1]
|
self.db.state.container_mode = m_pkt.data[1]
|
||||||
|
|
||||||
|
if self.mode_cmd == nil then
|
||||||
|
self.mode_cmd = self.db.state.container_mode
|
||||||
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
|
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
|
||||||
end
|
end
|
||||||
@ -247,30 +287,22 @@ function dynamicv.new(session_id, unit_id, advert, out_queue)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- try to resend mode if needed
|
||||||
|
if self.resend_mode then
|
||||||
|
self.resend_mode = false
|
||||||
|
_set_cont_mode(self.mode_cmd)
|
||||||
|
end
|
||||||
|
|
||||||
time_now = util.time()
|
time_now = util.time()
|
||||||
|
|
||||||
-- handle periodics
|
-- handle periodics
|
||||||
|
|
||||||
if self.periodics.next_formed_req <= time_now then
|
if self.periodics.next_formed_req <= time_now then _request_formed(time_now) end
|
||||||
_request_formed()
|
|
||||||
self.periodics.next_formed_req = time_now + PERIODICS.FORMED
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.db.formed then
|
if self.db.formed then
|
||||||
if not self.has_build and self.periodics.next_build_req <= time_now then
|
if not self.has_build and self.periodics.next_build_req <= time_now then _request_build(time_now) end
|
||||||
_request_build()
|
if self.periodics.next_state_req <= time_now then _request_state(time_now) end
|
||||||
self.periodics.next_build_req = time_now + PERIODICS.BUILD
|
if self.periodics.next_tanks_req <= time_now then _request_tanks(time_now) end
|
||||||
end
|
|
||||||
|
|
||||||
if self.periodics.next_state_req <= time_now then
|
|
||||||
_request_state()
|
|
||||||
self.periodics.next_state_req = time_now + PERIODICS.STATE
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.periodics.next_tanks_req <= time_now then
|
|
||||||
_request_tanks()
|
|
||||||
self.periodics.next_tanks_req = time_now + PERIODICS.TANKS
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
self.session.post_update()
|
self.session.post_update()
|
||||||
|
|||||||
@ -58,9 +58,12 @@ function envd.new(session_id, unit_id, advert, out_queue)
|
|||||||
-- PRIVATE FUNCTIONS --
|
-- PRIVATE FUNCTIONS --
|
||||||
|
|
||||||
-- query the radiation readings of the device
|
-- query the radiation readings of the device
|
||||||
local function _request_radiation()
|
---@param time_now integer
|
||||||
|
local function _request_radiation(time_now)
|
||||||
-- read input registers 1 and 2 (start = 1, count = 2)
|
-- read input registers 1 and 2 (start = 1, count = 2)
|
||||||
self.session.send_request(TXN_TYPES.RAD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 2 })
|
if self.session.send_request(TXN_TYPES.RAD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 2 }) ~= false then
|
||||||
|
self.periodics.next_rad_req = time_now + PERIODICS.RAD
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- PUBLIC FUNCTIONS --
|
-- PUBLIC FUNCTIONS --
|
||||||
@ -90,10 +93,7 @@ function envd.new(session_id, unit_id, advert, out_queue)
|
|||||||
-- update this runner
|
-- update this runner
|
||||||
---@param time_now integer milliseconds
|
---@param time_now integer milliseconds
|
||||||
function public.update(time_now)
|
function public.update(time_now)
|
||||||
if self.periodics.next_rad_req <= time_now then
|
if self.periodics.next_rad_req <= time_now then _request_radiation(time_now) end
|
||||||
_request_radiation()
|
|
||||||
self.periodics.next_rad_req = time_now + PERIODICS.RAD
|
|
||||||
end
|
|
||||||
|
|
||||||
self.session.post_update()
|
self.session.post_update()
|
||||||
end
|
end
|
||||||
|
|||||||
@ -89,27 +89,39 @@ function imatrix.new(session_id, unit_id, advert, out_queue)
|
|||||||
-- PRIVATE FUNCTIONS --
|
-- PRIVATE FUNCTIONS --
|
||||||
|
|
||||||
-- query if the multiblock is formed
|
-- query if the multiblock is formed
|
||||||
local function _request_formed()
|
---@param time_now integer
|
||||||
|
local function _request_formed(time_now)
|
||||||
-- read discrete input 1 (start = 1, count = 1)
|
-- read discrete input 1 (start = 1, count = 1)
|
||||||
self.session.send_request(TXN_TYPES.FORMED, MODBUS_FCODE.READ_DISCRETE_INPUTS, { 1, 1 })
|
if self.session.send_request(TXN_TYPES.FORMED, MODBUS_FCODE.READ_DISCRETE_INPUTS, { 1, 1 }) ~= false then
|
||||||
|
self.periodics.next_formed_req = time_now + PERIODICS.FORMED
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the build of the device
|
-- query the build of the device
|
||||||
local function _request_build()
|
---@param time_now integer
|
||||||
|
local function _request_build(time_now)
|
||||||
-- read input registers 1 through 9 (start = 1, count = 9)
|
-- read input registers 1 through 9 (start = 1, count = 9)
|
||||||
self.session.send_request(TXN_TYPES.BUILD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 9 })
|
if self.session.send_request(TXN_TYPES.BUILD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 9 }) ~= false then
|
||||||
|
self.periodics.next_build_req = time_now + PERIODICS.BUILD
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the state of the device
|
-- query the state of the device
|
||||||
local function _request_state()
|
---@param time_now integer
|
||||||
|
local function _request_state(time_now)
|
||||||
-- read input register 10 through 11 (start = 10, count = 2)
|
-- read input register 10 through 11 (start = 10, count = 2)
|
||||||
self.session.send_request(TXN_TYPES.STATE, MODBUS_FCODE.READ_INPUT_REGS, { 10, 2 })
|
if self.session.send_request(TXN_TYPES.STATE, MODBUS_FCODE.READ_INPUT_REGS, { 10, 2 }) ~= false then
|
||||||
|
self.periodics.next_state_req = time_now + PERIODICS.STATE
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the tanks of the device
|
-- query the tanks of the device
|
||||||
local function _request_tanks()
|
---@param time_now integer
|
||||||
|
local function _request_tanks(time_now)
|
||||||
-- read input registers 12 through 15 (start = 12, count = 3)
|
-- read input registers 12 through 15 (start = 12, count = 3)
|
||||||
self.session.send_request(TXN_TYPES.TANKS, MODBUS_FCODE.READ_INPUT_REGS, { 12, 3 })
|
if self.session.send_request(TXN_TYPES.TANKS, MODBUS_FCODE.READ_INPUT_REGS, { 12, 3 }) ~= false then
|
||||||
|
self.periodics.next_tanks_req = time_now + PERIODICS.TANKS
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- PUBLIC FUNCTIONS --
|
-- PUBLIC FUNCTIONS --
|
||||||
@ -181,26 +193,12 @@ function imatrix.new(session_id, unit_id, advert, out_queue)
|
|||||||
-- update this runner
|
-- update this runner
|
||||||
---@param time_now integer milliseconds
|
---@param time_now integer milliseconds
|
||||||
function public.update(time_now)
|
function public.update(time_now)
|
||||||
if self.periodics.next_formed_req <= time_now then
|
if self.periodics.next_formed_req <= time_now then _request_formed(time_now) end
|
||||||
_request_formed()
|
|
||||||
self.periodics.next_formed_req = time_now + PERIODICS.FORMED
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.db.formed then
|
if self.db.formed then
|
||||||
if not self.has_build and self.periodics.next_build_req <= time_now then
|
if not self.has_build and self.periodics.next_build_req <= time_now then _request_build(time_now) end
|
||||||
_request_build()
|
if self.periodics.next_state_req <= time_now then _request_state(time_now) end
|
||||||
self.periodics.next_build_req = time_now + PERIODICS.BUILD
|
if self.periodics.next_tanks_req <= time_now then _request_tanks(time_now) end
|
||||||
end
|
|
||||||
|
|
||||||
if self.periodics.next_state_req <= time_now then
|
|
||||||
_request_state()
|
|
||||||
self.periodics.next_state_req = time_now + PERIODICS.STATE
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.periodics.next_tanks_req <= time_now then
|
|
||||||
_request_tanks()
|
|
||||||
self.periodics.next_tanks_req = time_now + PERIODICS.TANKS
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
self.session.post_update()
|
self.session.post_update()
|
||||||
|
|||||||
@ -80,21 +80,30 @@ function sna.new(session_id, unit_id, advert, out_queue)
|
|||||||
-- PRIVATE FUNCTIONS --
|
-- PRIVATE FUNCTIONS --
|
||||||
|
|
||||||
-- query the build of the device
|
-- query the build of the device
|
||||||
local function _request_build()
|
---@param time_now integer
|
||||||
|
local function _request_build(time_now)
|
||||||
-- read input registers 1 through 2 (start = 1, count = 2)
|
-- read input registers 1 through 2 (start = 1, count = 2)
|
||||||
self.session.send_request(TXN_TYPES.BUILD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 2 })
|
if self.session.send_request(TXN_TYPES.BUILD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 2 }) ~= false then
|
||||||
|
self.periodics.next_build_req = time_now + PERIODICS.BUILD
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the state of the device
|
-- query the state of the device
|
||||||
local function _request_state()
|
---@param time_now integer
|
||||||
|
local function _request_state(time_now)
|
||||||
-- read input registers 3 through 4 (start = 3, count = 2)
|
-- read input registers 3 through 4 (start = 3, count = 2)
|
||||||
self.session.send_request(TXN_TYPES.STATE, MODBUS_FCODE.READ_INPUT_REGS, { 3, 2 })
|
if self.session.send_request(TXN_TYPES.STATE, MODBUS_FCODE.READ_INPUT_REGS, { 3, 2 }) ~= false then
|
||||||
|
self.periodics.next_state_req = time_now + PERIODICS.STATE
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the tanks of the device
|
-- query the tanks of the device
|
||||||
local function _request_tanks()
|
---@param time_now integer
|
||||||
|
local function _request_tanks(time_now)
|
||||||
-- read input registers 5 through 10 (start = 5, count = 6)
|
-- read input registers 5 through 10 (start = 5, count = 6)
|
||||||
self.session.send_request(TXN_TYPES.TANKS, MODBUS_FCODE.READ_INPUT_REGS, { 5, 6 })
|
if self.session.send_request(TXN_TYPES.TANKS, MODBUS_FCODE.READ_INPUT_REGS, { 5, 6 }) ~= false then
|
||||||
|
self.periodics.next_tanks_req = time_now + PERIODICS.TANKS
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- PUBLIC FUNCTIONS --
|
-- PUBLIC FUNCTIONS --
|
||||||
@ -152,20 +161,9 @@ function sna.new(session_id, unit_id, advert, out_queue)
|
|||||||
-- update this runner
|
-- update this runner
|
||||||
---@param time_now integer milliseconds
|
---@param time_now integer milliseconds
|
||||||
function public.update(time_now)
|
function public.update(time_now)
|
||||||
if not self.has_build and self.periodics.next_build_req <= time_now then
|
if not self.has_build and self.periodics.next_build_req <= time_now then _request_build(time_now) end
|
||||||
_request_build()
|
if self.periodics.next_state_req <= time_now then _request_state(time_now) end
|
||||||
self.periodics.next_build_req = time_now + PERIODICS.BUILD
|
if self.periodics.next_tanks_req <= time_now then _request_tanks(time_now) end
|
||||||
end
|
|
||||||
|
|
||||||
if self.periodics.next_state_req <= time_now then
|
|
||||||
_request_state()
|
|
||||||
self.periodics.next_state_req = time_now + PERIODICS.STATE
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.periodics.next_tanks_req <= time_now then
|
|
||||||
_request_tanks()
|
|
||||||
self.periodics.next_tanks_req = time_now + PERIODICS.TANKS
|
|
||||||
end
|
|
||||||
|
|
||||||
self.session.post_update()
|
self.session.post_update()
|
||||||
end
|
end
|
||||||
|
|||||||
@ -94,27 +94,39 @@ function sps.new(session_id, unit_id, advert, out_queue)
|
|||||||
-- PRIVATE FUNCTIONS --
|
-- PRIVATE FUNCTIONS --
|
||||||
|
|
||||||
-- query if the multiblock is formed
|
-- query if the multiblock is formed
|
||||||
local function _request_formed()
|
---@param time_now integer
|
||||||
|
local function _request_formed(time_now)
|
||||||
-- read discrete input 1 (start = 1, count = 1)
|
-- read discrete input 1 (start = 1, count = 1)
|
||||||
self.session.send_request(TXN_TYPES.FORMED, MODBUS_FCODE.READ_DISCRETE_INPUTS, { 1, 1 })
|
if self.session.send_request(TXN_TYPES.FORMED, MODBUS_FCODE.READ_DISCRETE_INPUTS, { 1, 1 }) ~= false then
|
||||||
|
self.periodics.next_formed_req = time_now + PERIODICS.FORMED
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the build of the device
|
-- query the build of the device
|
||||||
local function _request_build()
|
---@param time_now integer
|
||||||
|
local function _request_build(time_now)
|
||||||
-- read input registers 1 through 9 (start = 1, count = 9)
|
-- read input registers 1 through 9 (start = 1, count = 9)
|
||||||
self.session.send_request(TXN_TYPES.BUILD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 9 })
|
if self.session.send_request(TXN_TYPES.BUILD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 9 }) ~= false then
|
||||||
|
self.periodics.next_build_req = time_now + PERIODICS.BUILD
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the state of the device
|
-- query the state of the device
|
||||||
local function _request_state()
|
---@param time_now integer
|
||||||
|
local function _request_state(time_now)
|
||||||
-- read input register 10 (start = 10, count = 1)
|
-- read input register 10 (start = 10, count = 1)
|
||||||
self.session.send_request(TXN_TYPES.STATE, MODBUS_FCODE.READ_INPUT_REGS, { 10, 1 })
|
if self.session.send_request(TXN_TYPES.STATE, MODBUS_FCODE.READ_INPUT_REGS, { 10, 1 }) ~= false then
|
||||||
|
self.periodics.next_state_req = time_now + PERIODICS.STATE
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the tanks of the device
|
-- query the tanks of the device
|
||||||
local function _request_tanks()
|
---@param time_now integer
|
||||||
|
local function _request_tanks(time_now)
|
||||||
-- read input registers 11 through 19 (start = 11, count = 9)
|
-- read input registers 11 through 19 (start = 11, count = 9)
|
||||||
self.session.send_request(TXN_TYPES.TANKS, MODBUS_FCODE.READ_INPUT_REGS, { 11, 9 })
|
if self.session.send_request(TXN_TYPES.TANKS, MODBUS_FCODE.READ_INPUT_REGS, { 11, 9 }) ~= false then
|
||||||
|
self.periodics.next_tanks_req = time_now + PERIODICS.TANKS
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- PUBLIC FUNCTIONS --
|
-- PUBLIC FUNCTIONS --
|
||||||
@ -191,26 +203,12 @@ function sps.new(session_id, unit_id, advert, out_queue)
|
|||||||
-- update this runner
|
-- update this runner
|
||||||
---@param time_now integer milliseconds
|
---@param time_now integer milliseconds
|
||||||
function public.update(time_now)
|
function public.update(time_now)
|
||||||
if self.periodics.next_formed_req <= time_now then
|
if self.periodics.next_formed_req <= time_now then _request_formed(time_now) end
|
||||||
_request_formed()
|
|
||||||
self.periodics.next_formed_req = time_now + PERIODICS.FORMED
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.db.formed then
|
if self.db.formed then
|
||||||
if not self.has_build and self.periodics.next_build_req <= time_now then
|
if not self.has_build and self.periodics.next_build_req <= time_now then _request_build(time_now) end
|
||||||
_request_build()
|
if self.periodics.next_state_req <= time_now then _request_state(time_now) end
|
||||||
self.periodics.next_build_req = time_now + PERIODICS.BUILD
|
if self.periodics.next_tanks_req <= time_now then _request_tanks(time_now) end
|
||||||
end
|
|
||||||
|
|
||||||
if self.periodics.next_state_req <= time_now then
|
|
||||||
_request_state()
|
|
||||||
self.periodics.next_state_req = time_now + PERIODICS.STATE
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.periodics.next_tanks_req <= time_now then
|
|
||||||
_request_tanks()
|
|
||||||
self.periodics.next_tanks_req = time_now + PERIODICS.TANKS
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
self.session.post_update()
|
self.session.post_update()
|
||||||
|
|||||||
@ -42,6 +42,8 @@ local PERIODICS = {
|
|||||||
TANKS = 1000
|
TANKS = 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local WRITE_BUSY_WAIT = 1000
|
||||||
|
|
||||||
-- create a new turbinev rtu session runner
|
-- create a new turbinev rtu session runner
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
---@param session_id integer RTU gateway session ID
|
---@param session_id integer RTU gateway session ID
|
||||||
@ -63,6 +65,8 @@ function turbinev.new(session_id, unit_id, advert, out_queue)
|
|||||||
local self = {
|
local self = {
|
||||||
session = unit_session.new(session_id, unit_id, advert, out_queue, log_tag, TXN_TAGS),
|
session = unit_session.new(session_id, unit_id, advert, out_queue, log_tag, TXN_TAGS),
|
||||||
has_build = false,
|
has_build = false,
|
||||||
|
mode_cmd = nil, ---@type dumping_mode|nil
|
||||||
|
resend_mode = false,
|
||||||
periodics = {
|
periodics = {
|
||||||
next_formed_req = 0,
|
next_formed_req = 0,
|
||||||
next_build_req = 0,
|
next_build_req = 0,
|
||||||
@ -116,45 +120,77 @@ function turbinev.new(session_id, unit_id, advert, out_queue)
|
|||||||
|
|
||||||
-- increment the dumping mode
|
-- increment the dumping mode
|
||||||
local function _inc_dump_mode()
|
local function _inc_dump_mode()
|
||||||
|
-- set mode command
|
||||||
|
if self.mode_cmd == "IDLE" then self.mode_cmd = "DUMPING_EXCESS"
|
||||||
|
elseif self.mode_cmd == "DUMPING_EXCESS" then self.mode_cmd = "DUMPING"
|
||||||
|
elseif self.mode_cmd == "DUMPING" then self.mode_cmd = "IDLE"
|
||||||
|
end
|
||||||
|
|
||||||
-- write coil 1 with unused value 0
|
-- write coil 1 with unused value 0
|
||||||
self.session.send_request(TXN_TYPES.INC_DUMP, MODBUS_FCODE.WRITE_SINGLE_COIL, { 1, 0 })
|
if self.session.send_request(TXN_TYPES.INC_DUMP, MODBUS_FCODE.WRITE_SINGLE_COIL, { 1, 0 }, WRITE_BUSY_WAIT) == false then
|
||||||
|
self.resend_mode = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- decrement the dumping mode
|
-- decrement the dumping mode
|
||||||
local function _dec_dump_mode()
|
local function _dec_dump_mode()
|
||||||
|
-- set mode command
|
||||||
|
if self.mode_cmd == "IDLE" then self.mode_cmd = "DUMPING"
|
||||||
|
elseif self.mode_cmd == "DUMPING_EXCESS" then self.mode_cmd = "IDLE"
|
||||||
|
elseif self.mode_cmd == "DUMPING" then self.mode_cmd = "DUMPING_EXCESS"
|
||||||
|
end
|
||||||
|
|
||||||
-- write coil 2 with unused value 0
|
-- write coil 2 with unused value 0
|
||||||
self.session.send_request(TXN_TYPES.DEC_DUMP, MODBUS_FCODE.WRITE_SINGLE_COIL, { 2, 0 })
|
if self.session.send_request(TXN_TYPES.DEC_DUMP, MODBUS_FCODE.WRITE_SINGLE_COIL, { 2, 0 }, WRITE_BUSY_WAIT) == false then
|
||||||
|
self.resend_mode = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- set the dumping mode
|
-- set the dumping mode
|
||||||
---@param mode dumping_mode
|
---@param mode dumping_mode
|
||||||
local function _set_dump_mode(mode)
|
local function _set_dump_mode(mode)
|
||||||
|
self.mode_cmd = mode
|
||||||
|
|
||||||
-- write holding register 1
|
-- write holding register 1
|
||||||
self.session.send_request(TXN_TYPES.SET_DUMP, MODBUS_FCODE.WRITE_SINGLE_HOLD_REG, { 1, mode })
|
if self.session.send_request(TXN_TYPES.SET_DUMP, MODBUS_FCODE.WRITE_SINGLE_HOLD_REG, { 1, mode }, WRITE_BUSY_WAIT) == false then
|
||||||
|
self.resend_mode = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query if the multiblock is formed
|
-- query if the multiblock is formed
|
||||||
local function _request_formed()
|
---@param time_now integer
|
||||||
|
local function _request_formed(time_now)
|
||||||
-- read discrete input 1 (start = 1, count = 1)
|
-- read discrete input 1 (start = 1, count = 1)
|
||||||
self.session.send_request(TXN_TYPES.FORMED, MODBUS_FCODE.READ_DISCRETE_INPUTS, { 1, 1 })
|
if self.session.send_request(TXN_TYPES.FORMED, MODBUS_FCODE.READ_DISCRETE_INPUTS, { 1, 1 }) ~= false then
|
||||||
|
self.periodics.next_formed_req = time_now + PERIODICS.FORMED
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the build of the device
|
-- query the build of the device
|
||||||
local function _request_build()
|
---@param time_now integer
|
||||||
|
local function _request_build(time_now)
|
||||||
-- read input registers 1 through 15 (start = 1, count = 15)
|
-- read input registers 1 through 15 (start = 1, count = 15)
|
||||||
self.session.send_request(TXN_TYPES.BUILD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 15 })
|
if self.session.send_request(TXN_TYPES.BUILD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 15 }) ~= false then
|
||||||
|
self.periodics.next_build_req = time_now + PERIODICS.BUILD
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the state of the device
|
-- query the state of the device
|
||||||
local function _request_state()
|
---@param time_now integer
|
||||||
|
local function _request_state(time_now)
|
||||||
-- read input registers 16 through 19 (start = 16, count = 4)
|
-- read input registers 16 through 19 (start = 16, count = 4)
|
||||||
self.session.send_request(TXN_TYPES.STATE, MODBUS_FCODE.READ_INPUT_REGS, { 16, 4 })
|
if self.session.send_request(TXN_TYPES.STATE, MODBUS_FCODE.READ_INPUT_REGS, { 16, 4 }) ~= false then
|
||||||
|
self.periodics.next_state_req = time_now + PERIODICS.STATE
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- query the tanks of the device
|
-- query the tanks of the device
|
||||||
local function _request_tanks()
|
---@param time_now integer
|
||||||
|
local function _request_tanks(time_now)
|
||||||
-- read input registers 20 through 25 (start = 20, count = 6)
|
-- read input registers 20 through 25 (start = 20, count = 6)
|
||||||
self.session.send_request(TXN_TYPES.TANKS, MODBUS_FCODE.READ_INPUT_REGS, { 20, 6 })
|
if self.session.send_request(TXN_TYPES.TANKS, MODBUS_FCODE.READ_INPUT_REGS, { 20, 6 }) ~= false then
|
||||||
|
self.periodics.next_tanks_req = time_now + PERIODICS.TANKS
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- PUBLIC FUNCTIONS --
|
-- PUBLIC FUNCTIONS --
|
||||||
@ -208,6 +244,10 @@ function turbinev.new(session_id, unit_id, advert, out_queue)
|
|||||||
self.db.state.prod_rate = m_pkt.data[2]
|
self.db.state.prod_rate = m_pkt.data[2]
|
||||||
self.db.state.steam_input_rate = m_pkt.data[3]
|
self.db.state.steam_input_rate = m_pkt.data[3]
|
||||||
self.db.state.dumping_mode = m_pkt.data[4]
|
self.db.state.dumping_mode = m_pkt.data[4]
|
||||||
|
|
||||||
|
if self.mode_cmd == nil then
|
||||||
|
self.mode_cmd = self.db.state.dumping_mode
|
||||||
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
|
log.debug(log_tag .. "MODBUS transaction reply length mismatch (" .. TXN_TAGS[txn_type] .. ")")
|
||||||
end
|
end
|
||||||
@ -277,30 +317,22 @@ function turbinev.new(session_id, unit_id, advert, out_queue)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- try to resend mode if needed
|
||||||
|
if self.resend_mode then
|
||||||
|
self.resend_mode = false
|
||||||
|
_set_dump_mode(self.mode_cmd)
|
||||||
|
end
|
||||||
|
|
||||||
time_now = util.time()
|
time_now = util.time()
|
||||||
|
|
||||||
-- handle periodics
|
-- handle periodics
|
||||||
|
|
||||||
if self.periodics.next_formed_req <= time_now then
|
if self.periodics.next_formed_req <= time_now then _request_formed(time_now) end
|
||||||
_request_formed()
|
|
||||||
self.periodics.next_formed_req = time_now + PERIODICS.FORMED
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.db.formed then
|
if self.db.formed then
|
||||||
if not self.has_build and self.periodics.next_build_req <= time_now then
|
if not self.has_build and self.periodics.next_build_req <= time_now then _request_build(time_now) end
|
||||||
_request_build()
|
if self.periodics.next_state_req <= time_now then _request_state(time_now) end
|
||||||
self.periodics.next_build_req = time_now + PERIODICS.BUILD
|
if self.periodics.next_tanks_req <= time_now then _request_tanks(time_now) end
|
||||||
end
|
|
||||||
|
|
||||||
if self.periodics.next_state_req <= time_now then
|
|
||||||
_request_state()
|
|
||||||
self.periodics.next_state_req = time_now + PERIODICS.STATE
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.periodics.next_tanks_req <= time_now then
|
|
||||||
_request_tanks()
|
|
||||||
self.periodics.next_tanks_req = time_now + PERIODICS.TANKS
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
self.session.post_update()
|
self.session.post_update()
|
||||||
|
|||||||
@ -22,6 +22,8 @@ local RTU_US_DATA = {
|
|||||||
unit_session.RTU_US_CMDS = RTU_US_CMDS
|
unit_session.RTU_US_CMDS = RTU_US_CMDS
|
||||||
unit_session.RTU_US_DATA = RTU_US_DATA
|
unit_session.RTU_US_DATA = RTU_US_DATA
|
||||||
|
|
||||||
|
local DEFAULT_BUSY_WAIT = 3000
|
||||||
|
|
||||||
-- create a new unit session runner
|
-- create a new unit session runner
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
---@param session_id integer RTU gateway session ID
|
---@param session_id integer RTU gateway session ID
|
||||||
@ -36,7 +38,8 @@ function unit_session.new(session_id, unit_id, advert, out_queue, log_tag, txn_t
|
|||||||
reactor = advert.reactor,
|
reactor = advert.reactor,
|
||||||
transaction_controller = txnctrl.new(),
|
transaction_controller = txnctrl.new(),
|
||||||
connected = true,
|
connected = true,
|
||||||
device_fail = false
|
device_fail = false,
|
||||||
|
last_busy = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
---@class _unit_session
|
---@class _unit_session
|
||||||
@ -53,14 +56,21 @@ function unit_session.new(session_id, unit_id, advert, out_queue, log_tag, txn_t
|
|||||||
---@param txn_type integer transaction type
|
---@param txn_type integer transaction type
|
||||||
---@param f_code MODBUS_FCODE function code
|
---@param f_code MODBUS_FCODE function code
|
||||||
---@param register_param (number|string)[] register range or register and values
|
---@param register_param (number|string)[] register range or register and values
|
||||||
---@return integer txn_id transaction ID of this transaction
|
---@param busy_wait integer|nil milliseconds to wait (>0), or uses the default
|
||||||
function protected.send_request(txn_type, f_code, register_param)
|
---@return integer|false txn_id transaction ID of this transaction or false if not sent due to being busy
|
||||||
|
function protected.send_request(txn_type, f_code, register_param, busy_wait)
|
||||||
|
local txn_id = false ---@type integer|false
|
||||||
|
|
||||||
|
busy_wait = busy_wait or DEFAULT_BUSY_WAIT
|
||||||
|
|
||||||
|
if (util.time_ms() - self.last_busy) >= busy_wait then
|
||||||
local m_pkt = comms.modbus_packet()
|
local m_pkt = comms.modbus_packet()
|
||||||
local txn_id = self.transaction_controller.create(txn_type)
|
txn_id = self.transaction_controller.create(txn_type)
|
||||||
|
|
||||||
m_pkt.make(txn_id, unit_id, f_code, register_param)
|
m_pkt.make(txn_id, unit_id, f_code, register_param)
|
||||||
|
|
||||||
out_queue.push_packet(m_pkt)
|
out_queue.push_packet(m_pkt)
|
||||||
|
end
|
||||||
|
|
||||||
return txn_id
|
return txn_id
|
||||||
end
|
end
|
||||||
@ -99,9 +109,9 @@ function unit_session.new(session_id, unit_id, advert, out_queue, log_tag, txn_t
|
|||||||
-- will have to wait on reply, renew the transaction
|
-- will have to wait on reply, renew the transaction
|
||||||
self.transaction_controller.renew(m_pkt.txn_id, txn_type)
|
self.transaction_controller.renew(m_pkt.txn_id, txn_type)
|
||||||
elseif ex == MODBUS_EXCODE.SERVER_DEVICE_BUSY then
|
elseif ex == MODBUS_EXCODE.SERVER_DEVICE_BUSY then
|
||||||
-- will have to wait on reply, renew the transaction
|
-- will have to try again later
|
||||||
self.transaction_controller.renew(m_pkt.txn_id, txn_type)
|
self.last_busy = util.time_ms()
|
||||||
log.debug(log_tag .. "MODBUS: device busy" .. txn_tag)
|
log.warning(log_tag .. "MODBUS: device busy" .. txn_tag)
|
||||||
elseif ex == MODBUS_EXCODE.NEG_ACKNOWLEDGE then
|
elseif ex == MODBUS_EXCODE.NEG_ACKNOWLEDGE then
|
||||||
-- general failure
|
-- general failure
|
||||||
log.error(log_tag .. "MODBUS: negative acknowledge (bad request)" .. txn_tag)
|
log.error(log_tag .. "MODBUS: negative acknowledge (bad request)" .. txn_tag)
|
||||||
|
|||||||
@ -22,7 +22,7 @@ local supervisor = require("supervisor.supervisor")
|
|||||||
|
|
||||||
local svsessions = require("supervisor.session.svsessions")
|
local svsessions = require("supervisor.session.svsessions")
|
||||||
|
|
||||||
local SUPERVISOR_VERSION = "v1.6.1"
|
local SUPERVISOR_VERSION = "v1.6.2"
|
||||||
|
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local println_ts = util.println_ts
|
local println_ts = util.println_ts
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user