question

ralfz avatar image
ralfz asked

Venus OS driver for Fronius Smart Meter

Updated with latest results on 17-Apr-2020

Situation

At home, I have three roofs (east, south and west) with 9.9 kWp PV feeding into a Fronius Symo 8.2-3-M. The setup has Fronius Smart Meter 63A-3.
In a few days I am adding a Multiplus-II 48/5000/70-50 and 2x Pylontech US2000 (4.4 kWh net) LiFePO battery.

Problem

I am running Venus OS on a Raspberry 3B+. It nicely shows the power fed in by the Symo, with all details.

Venus is not showing any data from the Fronius Smart Meter.

Vision

I would like to have the data from the Fronius Smart Meter available on the Venus.

My idea is that I need a driver for Venus OS, which gets the data from the Smart Meter via the http API that Fronius provides and passes that information onto dbus - where hopefully Venus treats the data as if it came from a meter that it knows.

Steps Forward

I searched for a solution to my problem on the internet.I thought that I can not be the first to have this issue. But I found no direct solution.

There are several projects that might be a good start for getting to a solution:

  • dbusdummyservice.py from velib_python
    A simple service on the dbus.
  • dbus-cgwacs
    Reads energy measuremens from Carlo Gavazzi Wired AC Sensors (hence cgwacs), and puts it on the D-Bus.

Both projects look like a good start for programming my own solution.

Python script emulating the Victron Grid meter

Using dbusdummyservice.py from velib_python as a basis, I wrote this script:

#!/usr/bin/env python

"""
Used https://github.com/victronenergy/velib_python/blob/master/dbusdummyservice.py as basis for this service.
Reading information from the Fronius Smart Meter via http REST API and puts the info on dbus.
"""
import gobject
import platform
#import argparse
import logging
import sys
import os
import requests # for http GET

# our own packages
sys.path.insert(1, os.path.join(os.path.dirname(__file__), '../ext/velib_python'))
from vedbus import VeDbusService

class DbusDummyService:
  def __init__(self, servicename, deviceinstance, paths, productname='Fronius Smart Meter', connection='Fronius SM service'):
    self._dbusservice = VeDbusService(servicename)
    self._paths = paths

    logging.debug("%s /DeviceInstance = %d" % (servicename, deviceinstance))

    # Create the management objects, as specified in the ccgx dbus-api document
    self._dbusservice.add_path('/Mgmt/ProcessName', __file__)
    self._dbusservice.add_path('/Mgmt/ProcessVersion', 'Unkown version, and running on Python ' + platform.python_version())
    self._dbusservice.add_path('/Mgmt/Connection', connection)

    # Create the mandatory objects
    self._dbusservice.add_path('/DeviceInstance', deviceinstance)
    self._dbusservice.add_path('/ProductId', 16) # value used in ac_sensor_bridge.cpp of dbus-cgwacs
    self._dbusservice.add_path('/ProductName', productname)
    self._dbusservice.add_path('/FirmwareVersion', 0.1)
    self._dbusservice.add_path('/HardwareVersion', 0)
    self._dbusservice.add_path('/Connected', 1)

    for path, settings in self._paths.iteritems():
      self._dbusservice.add_path(
        path, settings['initial'], writeable=True, onchangecallback=self._handlechangedvalue)

    gobject.timeout_add(200, self._update) # pause 200ms before the next request

  def _update(self):
    URL = "http://10.194.65.143/solar_api/v1/GetMeterRealtimeData.cgi?Scope=Device&DeviceId=0&DataCollection=MeterRealtimeData"
    meter_r = requests.get(url = URL)
    meter_data = meter_r.json() 
    MeterConsumption = meter_data['Body']['Data']['PowerReal_P_Sum']
    self._dbusservice['/Ac/Power'] = MeterConsumption # positive: consumption, negative: feed into grid
    self._dbusservice['/Ac/L1/Voltage'] = meter_data['Body']['Data']['Voltage_AC_Phase_1']
    self._dbusservice['/Ac/L2/Voltage'] = meter_data['Body']['Data']['Voltage_AC_Phase_2']
    self._dbusservice['/Ac/L3/Voltage'] = meter_data['Body']['Data']['Voltage_AC_Phase_3']
    self._dbusservice['/Ac/L1/Current'] = meter_data['Body']['Data']['Current_AC_Phase_1']
    self._dbusservice['/Ac/L2/Current'] = meter_data['Body']['Data']['Current_AC_Phase_2']
    self._dbusservice['/Ac/L3/Current'] = meter_data['Body']['Data']['Current_AC_Phase_3']
    self._dbusservice['/Ac/L1/Power'] = meter_data['Body']['Data']['PowerReal_P_Phase_1']
    self._dbusservice['/Ac/L2/Power'] = meter_data['Body']['Data']['PowerReal_P_Phase_2']
    self._dbusservice['/Ac/L3/Power'] = meter_data['Body']['Data']['PowerReal_P_Phase_3']
    self._dbusservice['/Ac/Energy/Forward'] = meter_data['Body']['Data']['EnergyReal_WAC_Sum_Consumed']
    self._dbusservice['/Ac/Energy/Reverse'] = meter_data['Body']['Data']['EnergyReal_WAC_Sum_Produced']
    logging.info("House Consumption: %s" % (MeterConsumption))
    return True

  def _handlechangedvalue(self, path, value):
    logging.debug("someone else updated %s to %s" % (path, value))
    return True # accept the change

def main():
  logging.basicConfig(level=logging.INFO)

  from dbus.mainloop.glib import DBusGMainLoop
  # Have a mainloop, so we can send/receive asynchronous calls to and from dbus
  DBusGMainLoop(set_as_default=True)

  pvac_output = DbusDummyService(
    servicename='com.victronenergy.grid',
    deviceinstance=0,
    paths={
      '/Ac/Power': {'initial': 0},
      '/Ac/L1/Voltage': {'initial': 0},
      '/Ac/L2/Voltage': {'initial': 0},
      '/Ac/L3/Voltage': {'initial': 0},
      '/Ac/L1/Current': {'initial': 0},
      '/Ac/L2/Current': {'initial': 0},
      '/Ac/L3/Current': {'initial': 0},
      '/Ac/L1/Power': {'initial': 0},
      '/Ac/L2/Power': {'initial': 0},
      '/Ac/L3/Power': {'initial': 0},
      '/Ac/Energy/Forward': {'initial': 0}, # energy bought from the grid
      '/Ac/Energy/Reverse': {'initial': 0}, # energy sold to the grid
    })

  logging.info('Connected to dbus, and switching over to gobject.MainLoop() (= event based)')
  mainloop = gobject.MainLoop()
  mainloop.run()

if __name__ == "__main__":
  main()

The script registers itself on dbus as "com.victronenergy.grid" and publishes values as defined on Venus wiki - dbus - Grid meter .

Before I run the script, I have the following situation on the remote console, feeding 3.9 kW to the grid:

When I run the script, I see the following situation on the remote console, as if the AC Loads would consume 3.9 kW:

So, clearly, my script does something. But not what I wanted.

As the next step, I added three paths to the script: "/Ac/L1/Power", "/Ac/L2/Power" and "/Ac/L3/Power" and then it worked. So, the "/Ac/Power" was not enough for Venus to accept the data as valid- it needed power for all three phases separately.

Now the remote console shows:

Final thoughts

So, it is possible to use a Fronius Smart Meter and make Venus see it correctly.

I think this could be useful for other users as well, therefore it now can be found together with some documentation on GitHub: venus.dbus-fronius-smartmeter

Venus OSFronius
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.

mondeoman avatar image mondeoman commented ·
This is a brilliant idea. Thanks for posting this!


If you are still reading this thread, I wanted to ask about error handling.

Is it possible to force the ESS into Passthrough mode (not charging, not inverting) if there is no data from the Fronius JSON Solar API?

I know the ESS manual says it goes into Passhtrough mode if there is no data from a directly attached Carlo Gavazzi grid meter.

0 Likes 0 ·
4 Answers
ralfz avatar image
ralfz answered ·

As written above - the issue is closed - it works as intended.

The code together with some documentation on how to install it on a Raspberry Pi with Venus OS is now on GitHub: venus.dbus-fronius-smartmeter

2 |3000

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

Daniël Boekel (Victron Energy Staff) avatar image
Daniël Boekel (Victron Energy Staff) answered ·

Hi @RalfZ

You'll need to use a supported grid-meter, like

https://www.victronenergy.com/live/energy-meters:em24

For no-feed in systems, The Fronius Smart Meter cannot be used together with our ESS system, as they will both try to regulate the grid setpoint. (but that's not the case with your system)


https://www.victronenergy.com/live/ac_coupling:fronius

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.

ralfz avatar image ralfz commented ·

I will use the MultiPlus-II in Mode 3, there will be no conflict between the control loops:

  • The Fronius Symo uses the Fronius Smart Meter to limit the power produced by the PV to a level where feed into the grid reaches 70% of PV-Power-peak. (German legal regulation)
  • My Mode 3 control loop will control the battery inverter of the MultiPlus-II in a way that I am reducing the consumption from the grid as much as possible.
0 Likes 0 ·
unifiedcommsguy avatar image
unifiedcommsguy answered ·

Added support for single phase meter (eg Smart Meter 63A-1) if anyone is interested.

https://github.com/unifiedcommsguy/victron-dbus-fronius-smartmeter

Also included automatic installation script to make it easier for those without python/BASH experience

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.

nzmikec avatar image nzmikec commented ·

Hi,

I was running this script from your repository /victron-dbus-fronius-smartmeter with great success thanks! Unfortunately I broke it with a Venus update to v2.80. :( Looks like this is due to a Python update.

Due to this ive moved over to the repo which is working however the meter is not showing up on VRM or the dashboard. It is avalible in nodered using the Victron grid meter node so my nodered flow is working - controlling my mode3 ESS.

Just wondering what I may need to change to get the dashboards and VRM showing up correctly as per the prior version?


Many thanks for all you work on this project!


Regards,

Mike

0 Likes 0 ·
recorp avatar image recorp nzmikec commented ·

I also use trixing's script and everything works fine. Maybe you have to adapt the Fronius API request URL (change DeviceId=0 to DeviceId=1).


0 Likes 0 ·
jarek-s avatar image
jarek-s answered ·

Hi,

Does this script work properly with Venus update to v2.91? If not, is there any other solution for reading data from the Fronius Smart Meter in VRM / dashboard with Venus v2.91?


Regards,

Jarek


2 |3000

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