我可以使用相同的 pymodbus BinaryPayloadDecoder 对象解码两次吗?

问题描述 投票:0回答:1

我有一个小测试程序,最终将使用 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

python modbus pymodbus
1个回答
0
投票

以下将提供您正在寻找的结果:

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_*
调用将从缓冲区的开头读取)。

© www.soinside.com 2019 - 2024. All rights reserved.