Query VM-3P75CT with Prometheus

Hello,
i have a local VM-3P75CT three phase energy meter connected via Ethernet.
For the Victron App this works fine but i want to monitor the values locally in Prometheus/Grafana for evaluation (not VRM)
In the documentation i could not find information/protocoll details.
Can someone help me out ?
I see that “curl --http0.9 IP” results in a continuous data stream.
Documentation tells me it connects via ModbusUDP but i havent found suitable registers in the whitepaper.

Thanks for any help.

Maybe for other DIY Users interesting:
You can use ModbusTCP to connect to the meter and query registers if you intent to use the meter without or in parallel with Cerbo/VenusGX or VenusOS.
For me meanwhile it works fine in parallel and i query every 5sec into my own prometheus database.

here a simple example for a python script i meanwhile use with prometheus.

###################################################
#!/usr/bin/python3

uses virtualenv → .venv

from pymodbus.client import ModbusUdpClient
import time

from prometheus_client import start_http_server, Gauge

def main():

scale = 0.01

client = ModbusUdpClient(host='<<emeter-address>>', port=502, timeout=3)
status = client.connect()
   

freq = Gauge('Frequenz', 'Leitungsnetz Frequenz')
pen = Gauge('PEN_U', 'Schutzleiter Spannung')
L1U = Gauge('L1_U','Spannung L1')
L1I = Gauge('L1_I','Strom L1')
L2U = Gauge('L2_U','Spannung L2')
L2I = Gauge('L2_I','Strom L2')
L3U = Gauge('L3_U','Spannung L3')
L3I = Gauge('L3_I','Strom L3')
Pges = Gauge('P_ges','Vector added Power consumption')
kWh_b = Gauge('Bezug_kWh','Energie in Bezugsrichtung 1.8.0')
kWh_e = Gauge('Einspeisung_kWh','Energie in Einspeiserichtung 2.8.0')

start_http_server(9790)
print('... initial starting web server for prometheus')

while status:

    try:
        freq_tmp = round( client.read_holding_registers(address=0x3032, count=1).registers[0] * scale, 2)
        pen_tmp = round( client.read_holding_registers(address=0x3033, count=1).registers[0] * scale, 2 )
        kWh_b_tmp = client.read_holding_registers(address=0x3034, count=2).registers[1] * scale
        kWh_e_tmp = client.read_holding_registers(address=0x3036, count=2).registers[1] * scale

        L1U_tmp = round( client.read_holding_registers(address=0x3040, count=1).registers[0] * scale, 2)
        L1I_tmp = round( client.read_holding_registers(address=0x3041, count=1).registers[0] * scale, 2)
    
        L2U_tmp = round( client.read_holding_registers(address=0x3048, count=1).registers[0] * scale, 2)
        L2I_tmp = round( client.read_holding_registers(address=0x3049, count=1).registers[0] * scale, 2)
        
        L3U_tmp = round( client.read_holding_registers(address=0x3050, count=1).registers[0] * scale, 2)
        L3I_tmp = round( client.read_holding_registers(address=0x3051, count=1).registers[0] * scale, 2)
        
        Pges_tmp = client.read_holding_registers(address=0x3080, count=2).registers[1]

        if (L1I_tmp or L2I_tmp or L3I_tmp) >= 70. :
            print('Current Readout Value higher than 70A')
            continue

    except Exception as e:
        print('Exception getting data: ',e)
    
    try:
        freq.set( freq_tmp )
        pen.set( pen_tmp )
        kWh_b.set( kWh_b_tmp )
        kWh_e.set( kWh_e_tmp )
        L1U.set( L1U_tmp )
        L1I.set( L1I_tmp )
        L2U.set( L2U_tmp )
        L2I.set( L2I_tmp )
        L3U.set( L3U_tmp )
        L3I.set( L3I_tmp )
        Pges.set( Pges_tmp )
    
        time.sleep(1)
    except Exception as e:
        print('Exception to set data: ', e)
        print('...restarting inner loop')

if name == “main”:
main()

1 Like