问题描述
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.constants import Endian
from pymodbus.client.sync import ModbusTcpClient
def convertINT32(data):
decoder = BinaryPayloadDecoder.fromregisters(data,Endian.Big,wordorder=Endian.Little)
return decoder.decode_32bit_int()
client = ModbusTcpClient(host="176.219.182.106",port="502")
client.connect()
data = client.read_holding_registers(address=230,count=10,unit=1)
eaPlus = convertINT32(data.registers[0:2]) # kWh Del
eaNeg = convertINT32(data.registers[2:4]) # kWh Rec
erPlus = convertINT32(data.registers[4:6]) #VARh Del
erNeg = convertINT32(data.registers[6:8]) #kVAR Rec
client.close()
print("Active Energy Plus: %s \nActive Energy Negative: %s \nReactive Energy Plus: %s \nReactive Energy Negative: %s" %(eaPlus,eaNeg,erPlus,erNeg))
print("----------------------------")
print("Register List: %s" % data.registers)
print("----------------------------")
print("Actual values are APPROXİMATE:\nActive Energy Plus: 989 \nActive Energy Negative: 3879077 \nReactive Energy Plus: 268384 \nReactive Energy Negative: 361")
我正在尝试从 Schneider ION7650 读取仪表值(如果您不知道也没关系),这是一个 modbus 寄存器列表:
我知道确切的值,并将结果与它们进行比较,我的代码看起来是错误的。 IP 地址和端口是可访问的,因此您可以访问仪表。这里有什么问题?
和输出:
Active Energy Plus: 3867613
Active Energy Negative: 275048
Reactive Energy Plus: 6270
Reactive Energy Negative: 3866985
----------------------------
Register List: [989,59,12904,4,6270,361,23532,65535]
----------------------------
Actual values are APPROXİMATE:
Active Energy Plus: 989
Active Energy Negative: 3879077
Reactive Energy Plus: 268384
Reactive Energy Negative: 361
您也可以查看here的实时值,然后点击消费
解决方法
我找到了解决办法。当我从 BinaryDecoder.fromregisters 中删除 wordorder 时,它的工作原理。我还在 Modbus Poll 中看到了订单列表。有很多选择,比如
- A B C D(字节顺序:大端)
- D C B A
- C D A B
- B A D C(字节顺序:Little Endian)
如果我错了,请纠正我。怎么能读到其他的选项。还有词序是什么?是否有任何组合读作“C D A B 组合,如 wordorder=Endian.Big byteorder= Endian.Little
,来自 Modbus Protocol and Register Map for ION Devices documentation(第 12 页):
根据 Modbus 协议,为了响应对特定从设备的寄存器 4xxxx 的请求,Modbus 主设备从从设备读取寄存器 xxxx-1。例如,寄存器 40011 对应于保持寄存器 10。
因此将 address
设置为 229 而不是 230 以读取从地址 230 开始的 10 个寄存器。此外,字节顺序和字顺序都是大端顺序。
我试过了,得到了预期值。