Files
uarep-ctl/modbus/pymodbus/pdu.gd

188 lines
6.7 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

extends Node
## Contains base classes for modbus request/response/error packets
# В автозагрузке должно быть
# from pymodbus.exceptions import
# from pymodbus.constants import Defaults
# from pymodbus.utilities import rtuFrameSize
# Base PDU's
class ModbusPDU extends Object:
## Base class for all Modbus messages
## [param transaction_id]
## This value is used to uniquely identify a request
## response pair. It can be implemented as a simple counter
## [param protocol_id]
## This is a constant set at 0 to indicate Modbus. It is
## put here for ease of expansion.
## [param unit_id]
## This is used to route the request to the correct child. In
## the TCP modbus, it is used for routing (or not used at all. However,
## for the serial versions, it is used to specify which child to perform
## the requests against. The value 0x00 represents the broadcast address
## (also 0xff).
## [param check]
## This is used for LRC/CRC in the serial modbus protocols
## [param skip_encode]
## This is used when the message payload has already been encoded.
## Generally this will occur when the PayloadBuilder is being used
## to create a complicated message. By setting this to True, the
## request will pass the currently encoded message through instead
## of encoding it again.
var transaction_id
var protocol_id
var unit_id
var skip_encode
var check
var function_code = 0
var exception_code = 0
## Initializes the base data for a modbus request
func _init(kwargs: Dictionary):
transaction_id = kwargs.get('transaction', constants.Defaults.TransactionId)
protocol_id = kwargs.get('protocol', constants.Defaults.ProtocolId)
unit_id = kwargs.get('unit', constants.Defaults.UnitId)
skip_encode = kwargs.get('skip_encode', false)
check = 0x0000
## Encodes the message
## [b]raises[/b] A not implemented exception
func encode():
exceptions.NotImplementedException.new().raise()
## Decodes data part of the message.
## [param data] is a string object
## [b]raises[/b] A not implemented exception
func decode(data: PackedByteArray):
exceptions.NotImplementedException.new().raise()
## Calculates the size of a PDU.
## [param buffer] A buffer containing the data that have been received.
## [b]returns[/b] The number of bytes in the PDU.
func calculateRtuFrameSize(buffer: PackedByteArray):
var rc = self.get('_rtu_frame_size')
if rc != null:
return rc
rc = self.get('_rtu_byte_count_pos')
if rc != null:
return utilities.rtuFrameSize(buffer, rc)
else:
exceptions.NotImplementedException.new('Cannot determine RTU frame size for %s' % self).raise()
## Base class for a modbus request PDU
class ModbusRequest extends ModbusPDU:
func _init(kwargs: Dictionary):
# Proxy to the lower level initializer
super(kwargs)
## Builds an error response based on the function[br]
## [param exception] The exception to return[br]
## [b]raises[/b] An exception response[br]
func doException(exception):
var exc = exceptions.ExceptionResponse(function_code, exception)
log.error(exc)
return exc
class ModbusResponse extends ModbusPDU:
## Base class for a modbus response PDU
## [param should_respond]
## A flag that indicates if this response returns a result back
## to the client issuing the request
## [param _rtu_frame_size]
## Indicates the size of the modbus rtu response used for
## calculating how much to read.
var should_respond = true
## Proxy to the lower level initializer
func _init(kwargs: Dictionary):
super(kwargs)
## Checks if the error is a success or failure
func isError():
return function_code > 0x80
## Exception PDU's. An enumeration of the valid modbus exceptions
class ModbusExceptions:
const IllegalFunction = 0x01
const IllegalAddress = 0x02
const IllegalValue = 0x03
const SlaveFailure = 0x04
const Acknowledge = 0x05
const SlaveBusy = 0x06
const MemoryParityError = 0x08
const GatewayPathUnavailable = 0x0A
const GatewayNoResponse = 0x0B
var _decoded: = {}
func _init():
for prop in get_property_list():
_decoded[get(prop.name)] = prop.name
## Given an error code, translate it to a string error name.[br]
## [param code] The code number to translate
func decode(code: int) -> String: return _decoded.get(code)
## Base class for a modbus exception PDU
class ExceptionResponse extends ModbusResponse:
var ExceptionOffset = 0x80
var _rtu_frame_size = 5
var original_code = function_code
## Initializes the modbus exception response
## [param function_code] The function to build an exception response for
## [param exception_code] The specific modbus exception to return
func _init(func_code, kwargs: Dictionary, except_code: int = 0):
super(kwargs)
function_code = func_code | ExceptionOffset
exception_code = except_code
original_code = function_code
## Encodes a modbus exception response
func encode(): return exception_code
## Decodes a modbus exception response[br]
## [param data] The packet data to decode
func decode(data: PackedByteArray):
exception_code = data.decode_u8(0)
## Builds a representation of an exception response[/br]
## [b]returns[/b] The string representation of an exception response
func _to_string() -> String:
var message = ModbusExceptions.new().decode(self.exception_code)
return 'Exception Response(%d, %d, %s)' % [function_code, original_code, message]
## Defines the Modbus slave exception type 'Illegal Function'
## This exception code is returned if the slave::
## - does not implement the function code **or**
## - is not in a state that allows it to process the function
class IllegalFunctionRequest extends ModbusRequest:
var ErrorCode = 1
## Initializes a IllegalFunctionRequest[br]
## [param function_code] The function we are erroring on[br]
func _init(func_code, kwargs):
super(kwargs)
self.function_code = func_code
## This is here so this failure will run correctly[br]
## [param data] Not used[br]
func decode(_data: PackedByteArray): pass
## Builds an illegal function request error response
## [param context] The current context for the message
## [b]returns[/b] The error response packet
func execute(context):
return ExceptionResponse.new(function_code, ErrorCode)