使用pymodbus从Epever uPower充电器/逆变器读取modbus寄存器



我从Epever uPower太阳能充电器/逆变器读取modbus寄存器时遇到问题。我正在使用运行在树莓派上的pymodbus库,通过USB到RS485电缆进行通信。我知道硬件和电缆都在工作,因为我可以在Windows笔记本电脑上获取数据。它似乎也适用于PI,因为当我在下面的代码中选择不同的单元ID时,我会出现连接错误。

有很多从Epever设备读取寄存器的例子,下面的代码似乎适用于大多数设备,但我无法使其适用于较新的uPower设备:

import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)
client = ModbusClient(method = 'rtu', port = '/dev/ttyUSB0', baudrate = 115200, stopbits=1, timeout=1, parity='N' )
client.connect()

result = client.read_input_registers(0x3100,6,unit=10)
print(result.registers)
solarVoltage = float(result.registers[0] / 100.0)
solarCurrent = float(result.registers[1] / 100.0)
batteryVoltage = float(result.registers[4] / 100.0)
chargeCurrent = float(result.registers[5] / 100.0)

# Do something with the data

client.close()

调试日志显示以下内容:

DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:SEND: 0xa 0x4 0x31 0x0 0x0 0x6 0x7f 0x8f
DEBUG:pymodbus.client.sync:New Transaction state 'SENDING'
DEBUG:pymodbus.transaction:Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
DEBUG:pymodbus.transaction:Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
DEBUG:pymodbus.transaction:RECV: 0xa 0x84 0x2 0xb3 0x3
DEBUG:pymodbus.framer.rtu_framer:Getting Frame - 0x84 0x2
DEBUG:pymodbus.factory:Factory Response[132]
DEBUG:pymodbus.framer.rtu_framer:Frame advanced, resetting header!!
DEBUG:pymodbus.transaction:Adding transaction 10
DEBUG:pymodbus.transaction:Getting transaction 10
DEBUG:pymodbus.transaction:Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
Traceback (most recent call last):
File "main.py", line 11, in <module>
print(result.registers)
AttributeError: 'ExceptionResponse' object has no attribute 'registers'

感谢收到的任何帮助或建议。如果我能理解代码得到RECV:0xa 0x84 0x2 0xb3 0x3 的响应,可能会有所帮助

不管怎样,它似乎没有任何寄存器。。。。

您需要将地址从0x3100更改为0x3500。

我反编译了SolarStationSoftware,发现他们把实时地址改成了13568。

查看Modbus规范,您的响应中列出的异常功能代码(0x0A(似乎是GATEWAY PATH UNAVAILABLE。这意味着问题可能与RS485总线有关。您可以通过添加isError((检查获得更多信息:

result = client.read_input_registers(0x3100,6,unit=10)
assert(not result.isError())
print(result.registers)