question

theo9999 avatar image
theo9999 asked

python modbus, Exception Response(132, 4, GatewayPathUnavailable)

Hello everyone,
I am trying to access information about my VenusGX, battery and Multiplus with modbusTCP and python, using the python library pymodbus, and get the error Exception Response(132, 4, GatewayPathUnavailable.

I can successfully access information about my VenusGX. For instance, with this bit of code, which accesses information about the GridSetpoint, using the VEsystemID :

ip            = "172.24.24.1"
VEsystemID        = 10
client = ModbusClient(ip, port='502')

def modbus_register(address, unit):
    msg = client.read_input_registers(address, unit=unit)
    print('message : , ', msg)
    decoder = BinaryPayloadDecoder.fromRegisters(msg.registers, byteorder=Endian.Big)
    msg = decoder.decode_16bit_int()
    return msg



GridSetPoint = modbus_register(2700, VEsystemID)
print(f"Grid Set Point: {GridSetPoint}W")

DVCC_maximum_system_charge_current = modbus_register(2705, VEsystemID)
print(f"DVCC_maximum_system_charge_current: {DVCC_maximum_system_charge_current}")

I get the following result, successfully getting the data :

message : ,  ReadInputRegistersResponse (1)
Grid Set Point: 50W
message : ,  ReadInputRegistersResponse (1)
DVCC_maximum_system_charge_current: -1W


However, when I try to access my batterySOC for instance :

from pymodbus.constants import Endian
from pymodbus.client import ModbusTcpClient as ModbusClient
from pymodbus.payload import BinaryPayloadDecoder


ip = "172.24.24.1"
RefreshRate = 1

MultiPlusID       = 242 
BmvID             = 225 
VEsystemID        = 100 



client = ModbusClient(ip, port='502')

def modbus_register(address, unit):
    msg = client.read_input_registers(address, unit=unit)
    print('message : , ', msg)
    decoder = BinaryPayloadDecoder.fromRegisters(msg.registers, byteorder=Endian.BIG)
    msg = decoder.decode_16bit_int()
    return msg


BatterySOC = modbus_register(266, BmvID) / 10
print(f"Battery State of Charge: {BatterySOC}%")

GridSetPoint = modbus_register(2700, VEsystemID)
print(f"Grid Set Point: {GridSetPoint}W")

DVCC_maximum_system_charge_current = modbus_register(2705, VEsystemID)
print(f"DVCC_maximum_system_charge_current: {DVCC_maximum_system_charge_current}W")

I get an error, because variable "msg" receives "Exception Response(132, 4, GatewayPathUnavailable)" instead of the value of the battery State of Charge.

However, I know the unitID of my BMV is 225 (in the Modbus TCP services of the victron remote console, it shows that the unit ID of my battery is 225, and that the unit id of my multiplus is 242), and the Modbus-TCP-register list indicates that register 266 corresponds to the battery state of charge. I also tried other registers, I got the same error.

I had the same error when trying to access my Multiplus data (for instance, the Output current of phase 1 with MultiPlusID = 242 and Modbus register 18)

The Victron remote console prints an error ,

ERROR "Error processing function code 3, unit id 242,

start address 304, quantity1, src129.104.9.21: Error

finding service with device type battery at device instance

261"

Does someone have an idea of what happens ?
Thank you very much,
Theophile

Venus GX - VGXModbus TCP
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

5 Answers
Mike Dorsett avatar image
Mike Dorsett answered ·

looking at CCGX-dbus_Modbus-TCP-register-list-2.90, mlti's are accessed in address range 4500 - 4602, and battery in range 1282-1318. This looks to be part of the GX register map, so you don't need to use the GX as a modbus gateway to a different UID to access the data.

2 comments
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

theo9999 avatar image theo9999 commented ·

Thank you Mike for your response. I think these registers ( address range 4500 - 4602, and battery in range 1282-1318 ) provide less options than the ones I used. For instance, using address range 4500 - 4602, I can't control the AcPowerSetpoint, whereas I can with address range 3 - 104. (using address 96, 98, 100)
Do you know what is the difference between address range 4500 - 4602 and address range 3 - 104 for the multi ?
And what is the difference between address range 1282-1318 and 258 - 327 for the battery ?

Maybe I should access one type of address range using the Venus Unit-Id and the other type using another Unit-Id ?

Thank you very much,

Théophile

0 Likes 0 ·
Mike Dorsett avatar image Mike Dorsett theo9999 commented ·

It may be easier to access the data you need using the d-bus service of the Venus os. I'm not currently set up with an operating venus device, so can't help further with the modbus. However, I did use the dbus service whilst interfacing a battery management program with venus, providing venus with all of the battery data.

0 Likes 0 ·
elvis avatar image
elvis answered ·

Not sure if it will make a difference but I see 2 things different from the way I do it.

1. you are missing the first line

from pymodbus.constants import Defaults
from pymodbus.constants import Endian
from pymodbus.client.sync import ModbusTcpClient as ModbusClient
from pymodbus.payload import BinaryPayloadDecoder

2. you use byteorder=Endian.BIG <--- caps

I use decoder = BinaryPayloadDecoder.fromRegisters(msg.registers, byteorder=Endian.Big) <-- only B is in caps

2 comments
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

theo9999 avatar image theo9999 commented ·
Yes it depends on the pymodbus version you are using, they use BIG in the older version I think. But I tried with both, and there is no pymodbus error so I guess it comes from somewhere else..
0 Likes 0 ·
elvis avatar image elvis theo9999 commented ·

I uninstalled pymodbus and installed the latest with pip.
I get the same errors you do.
The version of pymodbus i have installed is from my distro package manager (ubuntu apt) python3-pymodbus 2.1.0
if you are using ubuntu you can install with

sudo apt install python3-pymodbus

or

pip install pymodbus==2.1.0


the code provided works locally on the venus OS


Edit: got it figured out

unit is not a valid parameter replace with slave

I will post a working version below

0 Likes 0 ·
elvis avatar image
elvis answered ·

Verified to work on a Cerbo GX directly

soc.py

Edit:

See below for a correct working version.

FYI the soc.py in this post is still correct for running on the cerbo localhost.

The new corrected version will not run on the cerbo localhost.

Victron may someday update pymodbus. It may work then.


Cerbo Firmware v3.20~37

Here is what is installed on the Cerbo from Victron

Package: python3-pymodbus
Version: 2.3.0-r0
Depends: python3-pyserial, python3-six
Status: install ok installed
Architecture: cortexa7hf-neon-vfpv4
Installed-Size: 1062680
Installed-Time: 1703155129

2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

elvis avatar image
elvis answered ·

@theo9999

Verified working with pymodbus 3.6.3 installed with pip

unit is no longer a valid parameter replace with slave

#!/usr/bin/env python3

from pymodbus.constants import Endian
from pymodbus.client import ModbusTcpClient as ModbusClient
from pymodbus.payload import BinaryPayloadDecoder

BmvID = 223

ip = "192.168.20.156"

client = ModbusClient(ip, port='502')

def modbus_register(address, unit):
    msg     = client.read_holding_registers(address, slave=unit)
    decoder = BinaryPayloadDecoder.fromRegisters(msg.registers, byteorder=Endian.BIG)
    msg     = decoder.decode_16bit_int()
    return msg

BatterySOC  = modbus_register(266, BmvID) / 10

print(f"BatterySOC {BatterySOC}")
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

akabza avatar image
akabza answered ·

I had nearly the same issues caused by the version update of Python module pymodbus. Python code that was running since years stopped with errors since the update to the latest pymodus version 3.6.3. And it took me an evening to fix everything. Obviously the syntax of pymodbus changed here and there, e.g. "Big" changed to "BIG" as reported above already. Very frustrating!!!

See also https://pymodbus.readthedocs.io/en/latest/source/api_changes.html

2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.