Pylontech Firmware Update Feature Issue

Hi,

I wanted to look into the new Pylontech firmware update feature with an Ekrano GX, Venus OS v3.71, and Pylontech US3000C batteries, and as the Pylontech battery did not show up in the list of devices having a potential firmware update in the vrm portal I looked a bit deeper into it

Setup

  • Ekrano GX

  • Venus OS v3.71

  • Pylontech US3000C

  • vecan0 = 500000 bit/s

  • vecan1 = 250000 bit/s

Manually executing /opt/victronenergy/mqtt-rpc/thirdparty/pylon/py-tool -l shows the battery on vecan0:

<device serial="Y240311C31090015" version="2.4" description="Pylon Low-V Bat" id="B009" type="pylontech" connection="vecan0" updatable="True"/>

From the logs, when triggering looking for new firmware versions via vrm the generic scan was invoking:

INFO:streamcommand:Command ('vup', '--xml', '--no-local', '--canbus', 'socketcan:vecan1') terminated with status 0
INFO:streamcommand:Command ('xupt', '--xml') terminated with status 89
WARNING:thirdpartyupdater:"/opt/victronenergy/mqtt-rpc/thirdparty/pylon/py-tool -l" returned abnormal exit code 7

Looking at /opt/victronenergy/mqtt-rpc/mqtt-rpc.py, get_canbuses() only checks DBus services matching:

com.victronenergy.vecan.*

But on my system DBus shows:

com.victronenergy.vecan.vecan1
com.victronenergy.battery.socketcan_vecan0

So vecan0 is ignored by the generic scan, even though that is where the Pylontech battery actually is.

After patching get_canbuses() to also include com.victronenergy.battery.socketcan_*, the scan started invoking both CAN buses:

INFO:streamcommand:Command ('vup', '--xml', '--no-local', '--canbus', 'socketcan:vecan0') terminated with status 0
INFO:streamcommand:Command ('vup', '--xml', '--no-local', '--canbus', 'socketcan:vecan1') terminated with status 0

and discovery started working, hence the pylontech battery showed up in the vrm firmware update device list. So it looks like mqtt-rpc.py:get_canbuses() ignores com.victronenergy.battery.socketcan_*, so valid battery CAN interfaces like vecan0 are missed.

Has anyone else seen this with Ekrano GX + US3000C or do you see anyhting obvious that I might have configured/setup wrong?

What I’m trying to report is a likely Victron-side issue in the update mechanism itself.

On my system, the battery is clearly reachable and detected by the Pylon helper:

<device serial="..." version="2.4" description="Pylon Low-V Bat" id="B009" type="pylontech" connection="vecan0" updatable="True"/>

However, the generic discovery path in mqtt-rpc.py only considers com.victronenergy.vecan.*, while my battery is exposed on DBus as:

com.victronenergy.battery.socketcan_vecan0

Because of that, device-list-2 initially scanned only socketcan:vecan1 and missed the actual battery CAN interface. After patching get_canbuses() to also include com.victronenergy.battery.socketcan_*, discovery started working.

Maybe the currently installed FW is too old?

He already stated that he has Venus 3.71 so it’s not old.

And he is right about discovery method because since long the com.victronenergy.battery.* is the D-Bus service interface for battery devices and therefore it’s only logical that you should also look there for can buses used for battery communication.

For example, below on one of my systems, you can clearly see that …vecan.* enumeration will only expose can0, which is used only for Cerbo and Multi RS communication.
The can1, where the battery is, is exposed through …battery.* service. So the script should also look at this path.

Or better, the can buses can be enumerated from com.victronenergy.platform/CanBus/Interfaces, where you, for sure, find all can buses.

2

No, it is a plugin. This code is not involved.

The code here

def get_canbuses():
	dbusSession = dbusConnection()
	services = dbusSession.list_names()
	can_services = [ x for x in services if "com.victronenergy.vecan." in x ]
	return [
		"socketcan:{}".format(x.split(".")[-1]) for x in sorted(can_services)]

will not enumerate can1 where the battery is in my system, as seen below
The list will only contain [socketcan:can0]
In order for the battery to be detected, it should contain [socketcan:can0, socketcan:can1], but the python code above will not populate the socketcan:can1

yes, and it shouldn’t for a a not ve.can interface.

Are you saying that on old Cerbo MK1, that has a “dedicated” BMS CAN module - so not a VE.CAN interface, you can’t update the firmware in Pylontech batteries?

It is Pylontech detecting Pylontech batteries, it has nothing to do with VE.Can.

No, I am just saying that the code you quoted is irrelevant.

Correct me if I am wrong…
The code I have quoted is enumerating CAN ports on a system.
In order for later the script to be able to scan each detected CAN port.

	# CAN-bus interfaces
	interfaces = get_canbuses()
	for idx, can_interface in enumerate(interfaces):
		cmds.append(VupCommand(can_interface))

If we don’t have a complete list of CAN ports, is it possible to miss a/the battery on the system?

I will, vup is for VE.Can, Pylontech is a plugin though, has nothing to do with VE.Can.

For completeness btw, not saying there might not be a bug in there, but just pointing out that this code isn’t the reason…

OK, maybe we are talking about different things…

Nevertheless he said:

After patching get_canbuses() to also include com.victronenergy.battery.socketcan_*, discovery started working.

I know, but that is likely timing luck…

Aaaaa… I finally realized what you are trying to say…
Doh…
Indeed, the pytool is searching for the battery…

I am pretty sure that its not timing luck as I triggered the discovery multiple times with and without the patch applied.

For completeness, these are the changes I had to make locally to get past the initial discovery issue:

1) Patch in mqtt-rpc.py

File:

/opt/victronenergy/mqtt-rpc/mqtt-rpc.py

Function:

def get_canbuses():

Originally, it only included DBus services matching:

com.victronenergy.vecan.*

On my system that only returned:

com.victronenergy.vecan.vecan1

But the actual Pylontech battery was exposed on DBus as:

com.victronenergy.battery.socketcan_vecan0

So vecan0 was ignored by the generic discovery scan.

I patched get_canbuses() so it also includes:

com.victronenergy.battery.socketcan_*

After that, device-list-2 started scanning both:

socketcan:vecan0
socketcan:vecan1

and discovery started working.

2) Patch in thirdparty/pylon.py

File:

/opt/victronenergy/mqtt-rpc/thirdparty/pylon.py

Because the automatic Pylon helper scan was still not behaving correctly, I changed the Pylon plugin so that device_list()explicitly runs:

py-tool -l -c vecan0

instead of relying on the automatic interface scan.

This made the Pylon battery show up correctly.

exactly, and on all interfaces and with a doubtful exit code. Anyway as said, that was not the code you should be looking at…

Still, there is the connection_id that is passed to the UpdaterThread for the specific plugin.
Isn’t it contain the can port id?

I guess you are over complicating things, I doubt this ! should be here py_tool/pylon_tool.c at master · pylontech-sw/py_tool · GitHub.