我是pymodbus的新手。我试图创建一个自定义请求发送到TCP客户端,这个特定的请求需要在消息的开头有3个感叹号。一个示例消息请求将是21 21 21 01 7F 07 40 01 00 88 00 00十六进制,我试图从pymodbus文档示例中遵循自定义消息示例,并更改请求类中的编码函数,但我没有得到任何响应。是否有任何方法可以发送此特定消息,然后从modbus设备读取响应?这个特定函数应该返回设备中的日期和时间。谢谢!
class CustomBSCRACRequest(ModbusRequest):
"""Custom modbus request."""
function_code = 127
_rtu_frame_size = 8
command = 136
flags = 64
dest_task = 0
def __init__(self, address=None, **kwargs):
"""Initialize."""
ModbusRequest.__init__(self, **kwargs)
self.address = address
self.count = 7
def encode(self):
"""Encode."""
return struct.pack(">HHHHHHHHH", 33, 33, 33, self.address, self.count, self.flags, self.address, self.dest_task, self.command)
为了解决这个问题,我创建了一个新的帧器来编辑发送到设备的消息的头部。Pymodbus使用负责创建字节消息的帧,在这种情况下,我创建了一个继承ModbusRtuFramer的帧,并通过添加所需的头来覆盖buildPacket方法。我还需要将参数_hsize改写为新头的正确大小(函数代码之前的所有内容),在我的情况下,这是4。最后,因为这是一个特殊的请求消息,它的单元ID不像普通的RTU响应那样位于相同的位置,因此,populateHeader方法也被修改为指向单元ID的正确字节。这是一个非常特殊的情况,但一般来说,有类似问题的人需要做的是创建一个新的框架类,并首先修改buildPacket方法,然后修改所有其他头依赖的方法。创建框架器之后,更容易遵循自定义消息示例。我为我的特殊情况包含了buildPacket方法
def buildPacket(self, message) -> bytes:
data = message.encode()
packet = struct.pack(
">BBBBB",
33,
33,
33,
message.unit_id,
message.function_code,
)
packet += data
packet += struct.pack(">H", computeCRC(packet))
message.transaction_id = message.unit_id
return packet