question

Jimmy Bergetun avatar image
Jimmy Bergetun asked

Anyone have python example how to read MQTT values from Venus

I want to display battery information from my victron setup on a web page though python scripting, but I am strugling to understand how Victron has implemented mqtt on its devices.

Anyone have an example how to connect and display a value (For example Battery voltage) from Venus MQTT over internet with python and mqtt?

cerbo gxMQTT
2 |3000

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

3 Answers
Ole Saether avatar image
Ole Saether answered ·

Below is a python script that prints the battery voltage and exits. You need to change the mqtt_broker for your installation. See at the bottom of this page on how to find the correct one:
https://github.com/victronenergy/dbus-mqtt



from time import sleep
import ssl
import json
import os
from paho.mqtt.client import Client 

username = "your VRM email"
password = "your VRM pasword"
portal_id = "your VRM portal ID"
mqtt_broker = "mqtt67.victronenergy.com"

def on_message(client, userdata, message):
    val = json.loads(message.payload)
    print(val["value"])
    client.loop_stop()
    client.disconnect()
    os._exit(0)


def on_connect(client, userdata, rc, *args): 
    client.subscribe("N/%s/system/0/Dc/Battery/Voltage" % portal_id)

client = Client("P1")
client.tls_set(cert_reqs=ssl.CERT_NONE)
client.tls_insecure_set(True)
client.username_pw_set(username, password=password)
client.connect(mqtt_broker, port=8883)
client.on_connect = on_connect
client.on_message = on_message

client.loop_start()

while True:
    sleep(1)


1 comment
2 |3000

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

Jimmy Bergetun avatar image Jimmy Bergetun commented ·

Thank you :)

0 Likes 0 ·
drdiesel avatar image
drdiesel answered ·

Can this be modified to talk to a local GX device and not VRM?

9 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.

Ole Saether avatar image Ole Saether commented ·

If you want to read the Venus locally I would recommend Modbus. Below is an example that read the system battery voltage and print it to the console.


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

Defaults.Timeout = 25
Defaults.Retries = 5
client = ModbusClient('ipaddress.of.venus', port='502')
result = client.read_input_registers(840, 2)
decoder = BinaryPayloadDecoder.fromRegisters(result.registers, byteorder=Endian.Big)
voltage=decoder.decode_16bit_uint()
print("Battery voltage: {0:.2f}V".format(voltage/10.0))


0 Likes 0 ·
joel-cherian avatar image joel-cherian Ole Saether commented ·

Thank you for this answer. Is there any way i can get the solar panel data as well? Thanks a lot


0 Likes 0 ·
Ole Saether avatar image Ole Saether joel-cherian commented ·

Yes there is. All Modbus registers can be found in the document "Modbus-TCP register list" found on this page:
https://www.victronenergy.com/support-and-downloads/technical-information

0 Likes 0 ·
joel-cherian avatar image joel-cherian Ole Saether commented ·

thanks !!

0 Likes 0 ·
joel-cherian avatar image joel-cherian Ole Saether commented ·

Hey for some reason i am getting an error when i try to get the PV voltage. Is there any thing that i need to add in the code for it to work? I see that its under com.victronenergy.solarcharger d bus . Please help me . Thanks a lot.

0 Likes 0 ·
Ole Saether avatar image Ole Saether joel-cherian commented ·

Hei again,

You need to include the unit ID found under the "Unit ID mapping" tab of the excel sheet. For example my Multiplus have ID 242 and to turn it on I use this code:

result = client.write_register(33, 3, unit=242)

0 Likes 0 ·
joel-cherian avatar image joel-cherian Ole Saether commented ·

Thanks a lot !! Really appreciate it. For Reading solar i used

client.read_input_registers(776,3,unit=226) and it worked!!!

0 Likes 0 ·
drdiesel avatar image drdiesel Ole Saether commented ·

@osaether


You are my hero, thanks! I somehow missed that you replied, thank you very much.

0 Likes 0 ·
dcsonka avatar image dcsonka Ole Saether commented ·

Hi,


Thanks for the example. Based upon your example i am able to poll some data from my installed base, however, not all that I want to.

For example I have connected 3 temperature sensors to my CerbGX and I want to read their temperature value. Unfortunately, there is no mention for the external devices in the excell sheet.

Besides, the terminology is kind of confusing. The web GUI refers to "VRM instance". The excel sheet talks about unit-id or /DeviceInstance. So it is not clear which one is equivalent with which one.


I also tried to use their example found on the following link (reading the input voltage of the MP) :

https://www.victronenergy.com/live/ccgx:modbustcp_faq


from pymodbus.constants import Defaults
from pymodbus.constants import Endian
from pymodbus.client import ModbusTcpClient as ModbusClient
from pymodbus.payload import BinaryPayloadDecoder
 
Defaults.Timeout = 25
Defaults.Retries = 5
client = ModbusClient('192.168.25.220', port='502')


result = client.read_input_registers(3, 1, 246)
decoder = BinaryPayloadDecoder.fromRegisters(result.registers, byteorder=Endian.Big)
output=decoder.decode_16bit_uint()
print(output)

When I run this script, i get the following result:

plotter@plotter:~$ python3 test_iv.py 
Traceback (most recent call last):
  File "test_iv.py", line 12, in <module>
    decoder = BinaryPayloadDecoder.fromRegisters(result.registers, byteorder=Endian.Big)
AttributeError: 'ExceptionResponse' object has no attribute 'registers'

So I suppose, that register address or the so called unit-id is not correct (it is coded according to the excel's content).

So most of the registers mentioned in the excel are not possible to read. I was able to read registers with addresses only from 771 to 866. Nothing below and above that range.

What is it that I miss here?

1683935832500.png

1683935864064.png1683935894271.png

Thanks




0 Likes 0 ·
1683935832500.png (1.9 KiB)
1683935864064.png (2.6 KiB)
1683935894271.png (2.7 KiB)
laurenceh avatar image
laurenceh answered ·

Jimmy

I did some work on this some time ago as I wanted to do something similar when writing my own HTML GUI, my article is here:

https://community.victronenergy.com/articles/48977/simple-jsonrestajax-interface-to-venus-d-bus-writt.html

1) I did not use MQTTI I went straight into the d-bus data - this was after a prompt from Matthijs about using d-bus.

2) the d-bus code in that article is intended to run on the Venus OS device but I have linked it to run as a CGI service to return data in response to queries from network clients. The server side is in Python so you could extract my code example as a means of running python to read the d-bus data. Almost everything you would ever want is available on the d-bus once you have the code working.

3) the content is returned encoded as json because there are libraries to neatly unpick json responses and get them back into your html page. Not that the call to the function to render the response is embedded deep within the javascript to issue the request (easy to miss if you dont know what you are looking at).

4) You need to modify the hiawatha.conf file to enable cgi, there is a little more on making that change here: https://community.victronenergy.com/questions/47919/install-utilities-such-as-jq.html

The services and paths to the data are mostly by Victron, but some of the information may be out of date and there is now much more available via the d-bus than is documented by Victron here.

https://github.com/victronenergy/venus/wiki/dbus

Laurence


2 |3000

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