能否使用同一个pymodbus BinaryPayloadDecoder对象进行两次解码?
为什么同一个BinaryPayloadDecoder对象无法多次解码同一组寄存器?
没错,BinaryPayloadDecoder是流式解码的设计——它内部会维护一个读取偏移量,每次调用decode_32bit_float、decode_32bit_int这类解码方法时,都会消耗对应长度的寄存器数据,偏移量同步向后推进。
你第一次调用decode_32bit_float时,已经把手里的2个寄存器(刚好对应32位浮点数的4字节)全部读取完毕,此时解码器内部已无剩余数据。第二次再调用decode_32bit_int,自然会因为缺少足够的字节数抛出struct.error。
解决办法
最直接的方式就是像你已经尝试的那样,每次解码前重新创建一个BinaryPayloadDecoder对象,让每个解码器都从寄存器数据的起始位置开始读取:
from pymodbus.payload import BinaryPayloadDecoder from pymodbus.constants import Endian registers = [0x41b7, 0x7873] # 解码浮点数 decoder_float = BinaryPayloadDecoder.fromRegisters(registers, byteorder=Endian.BIG, wordorder=Endian.BIG) myfloat = decoder_float.decode_32bit_float() print("reg = ", myfloat) # 重新创建解码器解码整数 decoder_int = BinaryPayloadDecoder.fromRegisters(registers, byteorder=Endian.BIG, wordorder=Endian.BIG) myint = decoder_int.decode_32bit_int() print("reg = ", myint)
如果不想重复写创建解码器的代码,也可以封装一个小函数复用逻辑:
from pymodbus.payload import BinaryPayloadDecoder from pymodbus.constants import Endian def decode_registers(registers, decode_func, byteorder=Endian.BIG, wordorder=Endian.BIG): decoder = BinaryPayloadDecoder.fromRegisters(registers, byteorder=byteorder, wordorder=wordorder) return getattr(decoder, decode_func)() registers = [0x41b7, 0x7873] myfloat = decode_registers(registers, "decode_32bit_float") myint = decode_registers(registers, "decode_32bit_int") print("float: ", myfloat) print("int: ", myint)
补充说明
BinaryPayloadDecoder并没有提供公开方法重置内部的读取偏移量,没法让同一个解码器回到起始位置重新读取数据。这种设计是为了适配流式数据场景(比如从串口/网络持续接收数据并解码),而非针对同一组数据做多次不同格式的解码。
内容的提问来源于stack exchange,提问作者SWood
相关产品推荐
相关产品推荐

