Code Monkey home page Code Monkey logo

dbus-shelly-3em-smartmeter's Introduction

dbus-shelly-3em-smartmeter

Integrate Shelly 3EM smart meter into Victron Energies Venus OS

Purpose

With the scripts in this repo it should be easy possible to install, uninstall, restart a service that connects the Shelly 3EM to the VenusOS and GX devices from Victron. Idea is pasend on @RalfZim project linked below.

Inspiration

This project is my first on GitHub and with the Victron Venus OS, so I took some ideas and approaches from the following projects - many thanks for sharing the knowledge:

How it works

My setup

  • Shelly 3EM with latest firmware (20220209-094824/v1.11.8-g8c7bb8d)
    • 3-Phase installation (normal for Germany)
    • Connected to Wifi network "A"
    • IP 192.168.2.13/24
  • Victron Energy Cerbo GX with Venus OS - Firmware v2.93
    • No other devices from Victron connected (still waiting for shipment of Multiplus-2)
    • Connected to Wifi network "A"
    • IP 192.168.2.20/24

Details / Process

As mentioned above the script is inspired by @RalfZim fronius smartmeter implementation. So what is the script doing:

  • Running as a service
  • connecting to DBus of the Venus OS com.victronenergy.grid.http_40 or com.victronenergy.pvinverter.http_40
  • After successful DBus connection Shelly 3EM is accessed via REST-API - simply the /status is called and a JSON is returned with all details A sample JSON file from Shelly 3EM can be found here
  • Serial/MAC is taken from the response as device serial
  • Paths are added to the DBus with default value 0 - including some settings like name, etc
  • After that a "loop" is started which pulls Shelly 3EM data every 750ms from the REST-API and updates the values in the DBus

Thats it 😄

Pictures

Tile Overview Remote Console - Overview SmartMeter - Values SmartMeter - Device Details

Install & Configuration

Get the code

Just grap a copy of the main branche and copy them to /data/dbus-shelly-3em-smartmeter. After that call the install.sh script.

The following script should do everything for you:

wget https://github.com/fabian-lauer/dbus-shelly-3em-smartmeter/archive/refs/heads/main.zip
unzip main.zip "dbus-shelly-3em-smartmeter-main/*" -d /data
mv /data/dbus-shelly-3em-smartmeter-main /data/dbus-shelly-3em-smartmeter
chmod a+x /data/dbus-shelly-3em-smartmeter/install.sh
/data/dbus-shelly-3em-smartmeter/install.sh
rm main.zip

⚠️ Check configuration after that - because service is already installed an running and with wrong connection data (host, username, pwd) you will spam the log-file

Change config.ini

Within the project there is a file /data/dbus-shelly-3em-smartmeter/config.ini - just change the values - most important is the host, username and password in section "ONPREMISE". More details below:

Section Config vlaue Explanation
DEFAULT AccessType Fixed value 'OnPremise'
DEFAULT SignOfLifeLog Time in minutes how often a status is added to the log-file current.log with log-level INFO
DEFAULT CustomName Name of your device - usefull if you want to run multiple versions of the script
DEFAULT DeviceInstance DeviceInstanceNumber e.g. 40
DEFAULT Role use 'GRID' or 'PVINVERTER' to set the type of the shelly 3EM
DEFAULT Position Available Postions: 0 = AC, 1 = AC-Out 1, AC-Out 2
DEFAULT LogLevel Define the level of logging - lookup: https://docs.python.org/3/library/logging.html#levels
ONPREMISE Host IP or hostname of on-premise Shelly 3EM web-interface
ONPREMISE Username Username for htaccess login - leave blank if no username/password required
ONPREMISE Password Password for htaccess login - leave blank if no username/password required
ONPREMISE L1Position Which input on the Shelly in 3-phase grid is supplying a single Multi

Remapping L1

In a 3-phase grid with a single Multi, Venus OS expects L1 to be supplying the only Multi. This is not always the case. If for example your Multi is supplied by L3 (Input C on the Shelly) your GX device will show AC Loads as consuming from both L1 and L3. Setting L1Position to the appropriate Shelly input allows for remapping the phases and showing correct data on the GX device.

If your single Multi is connected to the Input A on the Shelly you don't need to change this setting. Setting L1Position to 2 would swap the B CT & Voltage sensors data on the Shelly with the A CT & Voltage sensors data on the Shelly. Respectively, setting L1Position to 3 would swap A and C inputs.

Used documentation

Discussions on the web

This module/repository has been posted on the following threads:

dbus-shelly-3em-smartmeter's People

Contributors

amcssh avatar fabian-lauer avatar kirichkov avatar kotty666 avatar leowinterde avatar matthiasos avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dbus-shelly-3em-smartmeter's Issues

value for total_returned are wrong because 3EM not "saldierend"

Hi,
as in forums discussed the 3EM builds no SUM over L1, L2 and L3.
so values for total returned are wrong if your PV inverter is only on one phase.
please compare the values with your meter from the distributor.
my suggustion:
at midnight set all values to zero and build your own sum over the day.
i made this for an ESP32 that reads my data from the 3EM and sends it to the solax X1 over RS485.
it works and the values in the solax portal looks rigth for me.
here is a bit of my code:

_//saldierung shelly
unsigned long time_now = millis();
unsigned long time_diff = time_now - last_time_Returned_energy_saldo;
last_time_Returned_energy_saldo = time_now;
if (power_gesamt_shelly_EM3 < 0) {
energy_returned_saldiert_Wattmillisekunde = energy_returned_saldiert_Wattmillisekunde + ((power_gesamt_shelly_EM3 * -1) * time_diff);
}

and dont forget:

  day_of_month = timeinfo.tm_mday;
  if (day_of_month != last_day){
  Serial.println("neuer tag: " + String(timeinfo.tm_mday));
  last_day = timeinfo.tm_mday;
 
  energy_returned_saldiert_Wattmillisekunde = 0; //returned energy um mitternacht zuruecksetzen,_

Can this be transformed for Shelly EM - monophase?

Hi!
Hope you have time to change the script for a Shelly EM.
Here is the output for it:
{"power":2724.16,"reactive":-1050.38,"pf":-0.93,"voltage":221.42,"is_valid":true,"total":12716863.2,"total_returned":1742722.0}

Shelly 3EM PV Inverter

Hallo,

habe den Shelly zum messen eines PV Inverters auf AC In eingesetzt. Allerdings ignoriert Venus OS die Werte völlig und nutzt die Leistung nicht zum Laden der Batterie.

Muss ich im ESS Menü externe Zähler auswählen damit das funktioniert? Das Problem ist bloß, dass die Victrons dann auf Durchleiten schalten.

Grüße

support for 1EM

What do you think about adding support for the 1EM shelly?

(I have a micro-inverter on the AC out on my Multiplus 2, connected via an 1EM shelly, and it would be quite cool to integrate it into my Venus stuff. - It looks straight forward to do it in a separate project, but maybe you would be interested in supporting both the 1 and the 3 channel shelly)

performance tweaks

Hi,

I have a CCGX (slow CPU) and using dbus-shelly-3em-smartmeter is noticable. Even more powerful Cerbo-s will benefit from the following optimizations:

Great project!!!

Service stops if shelly is not reachable

Although there is not a persistent problem with the network nor with shelly 3em, the service stops after some minutes with the following message on current.log "CRITICAL Error getting data from Shelly - check network or Shelly status. Setting power values to 0".
After I restart the service manually and it starts working again for more some minutes/hour.

There is a way to make this access more resilient not being necessary o keep restarting it?

Thanks

IP V6

Hi Fabian,

thanks a lot for the script.
On my Raspi with Venus OS it's working fine.

My cousin has a Gerbo connected to a fritzbox.
in this case the Gerbo has an IP V4 and an IP V6 Address!

From a SSH Terminal on the Gerbo the Shelly with the IP v4 address is not reachable by ping (also not with your script)

The shelly seems not to able to deal with a IP v6

Do you know if I can disable IP v6 on the Gerbo?
Or any other idea?

Thx
Michael

energy values are wrong

Hi Fabian,

i was not able to create a branch to fix it on my own. Here the fix:

Changing to value from "power" to "total" for Forward like:
self._dbusservice['/Ac/L1/Energy/Forward'] = meter_data['emeters'][0]['total']/1000 if meter_data['emeters'][0]['total'] > 0 else 0
Changing to value from "power" to "total_returned" for Reverse like:
self._dbusservice['/Ac/L1/Energy/Reverse'] = (meter_data['emeters'][0]['total_returned']/1000) if meter_data['emeters'][0]['total_returned'] < 0 else 0

This change works on my setup like expected.

BR,
Viktor

Shelly pro 3em

Hallo,
wäre es möglich den pro auch zu implementieren?

lg Heinz

Not running as service at v2.93 large after shutdown / reboot

It seems when using the Venus OS Large Image v2.93 there is a problem with the service when the Raspberry was shutted down and then started a few hours later.
Then there are no values from the dbus-shelly-3em-smartmeter at "AC-Eingang" and "AC-Lasten" and dbus-spy shows no 3EM service.

Shelly Em Freezes after a while

Hi,

I have a Shelly Em installed on my house now.

I've recently installed a ESS with a cerbo gx and installed the driver for this.

It runs fine for an hour or so then freezes and the only way to kick it back into.action is to reboot the gx.

The shelly is still connected to network and update fine.

Any idea on what this could be or how I could fault find on it?

Cheers

Gareth

AC Load is not shown correctly

I have connected all load and PV at AC out. My Growatt inverter is measured by the 3EM, so I configured it at the AC OUT.
What happens is that VRM subtracts the PV power from the AC Load. So the AC Load does not shows the real power.

When I connect the PV to the AC IN and the load to AC OUT and I configure the Shelly as connected to AC IN, the grid power is not shown correctly.

The Grid Metering in the ESS menu is set to Inverter/Charger. I don't have a grid meter

What am I doing wrong?

Dbus hangs sometimes and script needs to be restarted

hi, ive adopted your script to read json data from a Tasmota 12.4 with hichi ir read head.

ive no python skills and changed only the parts to get the JSON data.

it works, but I get after 4 hours or sometimes after 2 days no updates, the last value hangs and I had to restart the script to work again.

maybe you can look at it and find a error in my changing?

thank you very much

`#!/usr/bin/env python
import platform
import logging
import sys
import os
if sys.version_info.major == 2:
import gobject
else:
from gi.repository import GLib as gobject
import sys
import time
import requests # for http GET
sys.path.insert(1, os.path.join(os.path.dirname(file), '/opt/victronenergy/dbus-systemcalc-py/ext/velib_python'))
from vedbus import VeDbusService
class DbusMT681Service:
def init(self, servicename, paths, productname='MT681', connection='MT681 JSON service'):
deviceinstance = 42
customname = 'MT681-Netz'
self.dbusservice = VeDbusService("{}.http{:02d}".format(servicename, deviceinstance))
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)
self._dbusservice.add_path('/DeviceInstance', deviceinstance)
self._dbusservice.add_path('/ProductId', 0xFFFF) # id assigned by Victron Support from SDM630v2.py
self._dbusservice.add_path('/ProductName', productname)
self._dbusservice.add_path('/CustomName', customname)
self._dbusservice.add_path('/Connected', 1)
self._dbusservice.add_path('/Role', 'grid')
self._dbusservice.add_path('/Latency', None)
self._dbusservice.add_path('/FirmwareVersion', 0.1)
self._dbusservice.add_path('/HardwareVersion', 0)
self._dbusservice.add_path('/Position', 0) # normaly only needed for pvinverter
self._dbusservice.add_path('/Serial', self._getSerial())
self._dbusservice.add_path('/UpdateIndex', 0)
self._dbusservice.add_path('/StatusCode', 0) # Dummy path so VRM detects us as a PV-inverter.
# add path values to dbus
for path, settings in self._paths.items():
self._dbusservice.add_path(
path, settings['initial'], gettextcallback=settings['textformat'], writeable=True, onchangecallback=self._handlechangedvalue)
# last update
self._lastUpdate = 0
# add _update function 'timer'
gobject.timeout_add(250, self._update) # pause 250ms before the next request
# add _signOfLife 'timer' to get feedback in log every 5minutes
gobject.timeout_add(self._getSignOfLifeInterval()601000, self._signOfLife)
def _getSerial(self):
meter_data = self._getData()
if not meter_data['StatusSNS']['mt681']['Meter_id']:
raise ValueError("Response does not contain 'mac' attribute")
serial = meter_data['StatusSNS']['mt681']['Meter_id']
return serial
def _getSignOfLifeInterval(self):
value = 1
if not value:
value = 0
return int(value)
def _getData(self):
URL = "http://192.168.100.23/cm?cmnd=status%208"
meter_r = requests.get(url = URL)
# check for response
if not meter_r:
raise ConnectionError("No response from mt681 - %s" % (URL))
meter_data = meter_r.json()
# check for Json
if not meter_data:
raise ValueError("Converting response to JSON failed")
return meter_data
def _signOfLife(self):
logging.info("--- Start: sign of life ---")
logging.info("Last _update() call: %s" % (self._lastUpdate))
logging.info("Last '/Ac/Power': %s" % (self._dbusservice['/Ac/Power']))
logging.info("--- End: sign of life ---")
return True
def _update(self):
try:
#get data from Device
meter_data = self._getData()
self._dbusservice['/Ac/Power'] = meter_data['StatusSNS']['mt681']['Power_curr']
self._dbusservice['/Ac/L1/Voltage'] = 230
self._dbusservice['/Ac/L2/Voltage'] = 230
self._dbusservice['/Ac/L3/Voltage'] = 230
self._dbusservice['/Ac/L1/Power'] = meter_data['StatusSNS']['mt681']['Power_p1']
self._dbusservice['/Ac/L2/Power'] = meter_data['StatusSNS']['mt681']['Power_p2']
self._dbusservice['/Ac/L3/Power'] = meter_data['StatusSNS']['mt681']['Power_p3']
self._dbusservice['/Ac/L1/Current'] = meter_data['StatusSNS']['mt682']['Power_p1'] /230
self._dbusservice['/Ac/L2/Current'] = meter_data['StatusSNS']['mt682']['Power_p2'] /230
self._dbusservice['/Ac/L3/Current'] = meter_data['StatusSNS']['mt682']['Power_p3'] /230
self._dbusservice['/Ac/Energy/Forward'] = meter_data['StatusSNS']['mt681']['Total_out']
self._dbusservice['/Ac/Energy/Reverse'] = meter_data['StatusSNS']['mt681']['Total_in']
#logging
logging.debug("House Consumption (/Ac/Power): %s" % (self._dbusservice['/Ac/Power']))
logging.debug("---");
# increment UpdateIndex - to show that new data is available
index = self._dbusservice['/UpdateIndex'] + 1 # increment index
if index > 255: # maximum value of the index
index = 0 # overflow from 255 to 0
self._dbusservice['/UpdateIndex'] = index
#update lastupdate vars
self._lastUpdate = time.time()
except Exception as e:
logging.critical('Error at %s', '_update', exc_info=e)
# return true, otherwise add_timeout will be removed from GObject -
# see docs http://library.isr.ist.utl.pt/docs/pygtk2reference/gobject-functions.html#function-gobject--timeout-add
return True
def _handlechangedvalue(self, path, value):
logging.debug("someone else updated %s to %s" % (path, value))
return True # accept the change
def main():
try:
logging.info("Start");
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
#formatting
_kwh = lambda p, v: (str(round(v, 2)) + 'KWh')
_a = lambda p, v: (str(round(v, 1)) + 'A')
_w = lambda p, v: (str(round(v, 1)) + 'W')
_v = lambda p, v: (str(round(v, 1)) + 'V')
#start our main-service
pvac_output = DbusMT681Service(
servicename='com.victronenergy.grid',
paths={
'/Ac/Energy/Forward': {'initial': 0, 'textformat': _kwh}, # energy bought from the grid
'/Ac/Energy/Reverse': {'initial': 0, 'textformat': _kwh}, # energy sold to the grid
'/Ac/Power': {'initial': 0, 'textformat': _w},
'/Ac/Current': {'initial': 0, 'textformat': _a},
'/Ac/Voltage': {'initial': 0, 'textformat': _v},
'/Ac/L1/Voltage': {'initial': 0, 'textformat': _v},
'/Ac/L2/Voltage': {'initial': 0, 'textformat': _v},
'/Ac/L3/Voltage': {'initial': 0, 'textformat': _v},
'/Ac/L1/Current': {'initial': 0, 'textformat': _a},
'/Ac/L2/Current': {'initial': 0, 'textformat': _a},
'/Ac/L3/Current': {'initial': 0, 'textformat': _a},
'/Ac/L1/Power': {'initial': 0, 'textformat': _w},
'/Ac/L2/Power': {'initial': 0, 'textformat': _w},
'/Ac/L3/Power': {'initial': 0, 'textformat': _w},
})

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

except Exception as e:
logging.critical('Error at %s', 'main', exc_info=e)
if name == "main":
main()
`

Not working with Shelly 3em pro

Hello,

it is not working with a shelly 3em pro, because the status page is not available: Message "Not Found".
Seems to be that a shelly 3em pro don't have a status page.

Thanks
Best Regards

Marco Eberhardt

AC Input missing total in VRM Portal

Hi, I really love the integration, but somehow I am missing the total values for the AC Input in the vrm portal.
In the venusOS dashboard everything shows up, but not in VRM portal dashboard:
image

Is there a way to fix that?

Robustness regarding non reachable meters

Short story: I think the script should set current power meter values to 0, whenever the meter is not reachable.

Long story:
I'm running the latest version with my Multiplus II and Venus on a raspberry pi.

Recently I've discovered my inverter pushing max power into L1, while the actual load only was around 300-500W.
As a root cause I could find a broken Wifi connection to the shelly device, the log did show a long list of exceptions.
Multiplus would still see a usage of 500 W and would push up power for compensating that ..... the meter value would
not get back to Multiplus accordingly, and Multiplus increased even more.
If a missing meter fetch attempt would have set values to 0, this would at least have prevented Multiplus from trying to compensating and emptying the battery.

HTTP API iobroker or another sources

Hi, and great work! that saves a lot of users the em24 enery meter.

it is possible to integrate every data over http api in JSON format? without high costs in my meter housing i cant integrate a em24. a shelly e3m is possible, but i have all energy data on iobroker (generation, grid relation and grid feeding). iobroker can provide with a plugin all data over http GET in JSON format. all values of my energy meters phases shown in total.

#5

Hi, erstmal top Arbeit, das erspart vielen den em24.

Mich würde interessieren ob es möglich ist, auch auf Daten von iobroker (http api) zuzugreifen? Ohne größere Umbauarbeiten am Zählerschrank (ist voll bei mir) bekomme ich kein em24 rein. Jedoch bekomme ich die Werte von Bezug, Einspeisung und Erzeugung von meinem Wechselrichter und smartmeter direkt. Diese könnten per iobroker simpleapi per http JSON zu Verfügung gestellt werden. Abtastraten ab 1 Sekunde sind dort möglich.

https://github.com/ioBroker/ioBroker.simple-api

sieht dann z.b. folgendermaßen aus:

http://192.168.2.8:8090/getPlainValue/javascript.0.Haus_Strom_Verbrauch_gesamt?json 

1158

Es wird der Bezug, Einspeisung und Eigenverbrauch saldierend anzeigt.

Vielleicht kann ich unterstützend mitwirken oder bei der Machbarkeit helfen…

Shelly 3EM not in "energy meter"

eventuell ein Problem mit VenusOS 3.0 ?

image Shelly wird erkannt uns ausgelesen

aber Energy Meters ist leer:
image

und ESS steuert deswegen nicht.

Log goes too big

Hi, the current.log tends to gain all the free space on partition. Deleting from time to time solves that, but if you would clear it on boot, it will be better for all others. I can do it by cron, of course.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.