我有一个小测试程序,最终将使用 pymodbus 与我们的控制器进行通信。我使用 BinaryPayloadDecoder 将每对寄存器转换为 int 和 float,因为有些寄存器对是 float,有些是 int。但是第二次尝试从同一个 BinaryPayloadDecoder 对象进行解码时解码失败。
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.constants import Endian
registers = [0x41b7, 0x7873]
decoder = BinaryPayloadDecoder.fromRegisters(registers, byteorder=Endian.BIG, wordorder=Endian.BIG)
myfloat = decoder.decode_32bit_float()
print("reg = ", myfloat)
myint = decoder.decode_32bit_int()
print("reg = ", myint)
产品
reg = 22.933813095092773
Traceback (most recent call last):
File "c:\Users\jwoods7\source\hello\test.py", line 8, in <module>
myint = decoder.decode_32bit_int()
File "c:\Users\jwoods7\source\hello\.venv\lib\site-packages\pymodbus\payload.py", line 412, in decode_32bit_int
handle = self._unpack_words(fstring, handle)
File "c:\Users\jwoods7\source\hello\.venv\lib\site-packages\pymodbus\payload.py", line 342, in _unpack_words
handle = unpack(f"!{wc_value}H", handle)
struct.error: unpack requires a buffer of 4 bytes
但是,如果我在尝试转换为 int32 之前再次创建解码器对象。
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.constants import Endian
registers = [0x41b7, 0x7873]
decoder = BinaryPayloadDecoder.fromRegisters(registers, byteorder=Endian.BIG, wordorder=Endian.BIG)
myfloat = decoder.decode_32bit_float()
print("reg = ", myfloat)
decoder = BinaryPayloadDecoder.fromRegisters(registers, byteorder=Endian.BIG, wordorder=Endian.BIG)
myint = decoder.decode_32bit_int()
print("reg = ", myint)
它有效。那么 BinaryPayloadDecoder 对象不能多次转换?
reg = 22.933813095092773
reg = 1102542963
以下将提供您正在寻找的结果:
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.constants import Endian
registers = [0x41b7, 0x7873]
decoder = BinaryPayloadDecoder.fromRegisters(registers, byteorder=Endian.BIG, wordorder=Endian.BIG)
myfloat = decoder.decode_32bit_float()
print("reg = ", myfloat)
decoder.reset()
myint = decoder.decode_32bit_int()
print("reg = ", myint)
输出:
reg = 22.933813095092773
reg = 1102542963
decode_32bit_float
)都会推进一个内部指针,以便下一次调用解码函数将在已解码的数据之后开始读取(允许您提取,对于例如,来自二进制数据的多个 32 位浮点数)。
这意味着以下内容也将获得所需的结果(假设您提取了 4 个寄存器):
registers = [0x41b7, 0x7873, 0x41b7, 0x7873]
decoder = BinaryPayloadDecoder.fromRegisters(registers, byteorder=Endian.BIG, wordorder=Endian.BIG)
myfloat = decoder.decode_32bit_float()
print("reg = ", myfloat)
myint = decoder.decode_32bit_int()
print("reg = ", myint)
reset()
会重置该指针(下一个 decode_*
调用将从缓冲区的开头读取)。