Shelly 3EM

Die Shelly-Produktreihe gefällt mir sehr gut. Man findet eigentlich für jeden Einsatzzweck der Hausautomation passende Geräte. Ich habe zum Beispiel einen Shelly1PM verwendet, um die Werte meines Balkonkraftwerkes zu messen und für die Weiterverarbeitung bereit zu stellen. Dazu habe ich den 1PM mit Tasmota geflasht und sende die Werte an meinen MQTT-Broker. Hier auf dem Bild seht ihr aber einen Shelly-3EM. Shelly schreibt dazu auf seiner Homepage:

"...Überwachen Sie den Verbrauch beliebiger Haushaltsgeräte, Stromkreise und Büroeinrichtungen (Beleuchtung, Stromleitungen, Sicherheitssysteme, Heizung und Kühlung usw.) einzeln drei unabhängige Messkanäle bis zu je 120 Ampere

  • eine Schützsteuerung (oder Last bis zu 10 Ampere)
  • 365 Tage interner Speicher für den Fall, dass WLAN nicht verfügbar  ist
  • Spannungsmessung und konfigurierbare Alarmmeldungen                  
  • Inklusive 3x Stromwandler 120 Ampere..."

Und genau das war auch mein Ziel, wobei die Messwerte (Energieverbrauch, Spannung, Strom) unbedingt auch noch in meine Datenbank aufgenommen werden sollen. Und genau da wird es ein bisschen kniffelig. Man muss sich bei den Shelly-Geräten nämlich entscheiden, ob diese in die Shelly-Cloud aufgenommen werden sollen oder mit MQTT arbeiten und dann einen ganz beliebigen Broker ihre Werte senden. Näheres hierzu könnt ihr hier nachlesen. Gerade für das 3EM wollte ich aber nicht auf die Originalsoftware und Einbindung in die Shelly-Cloud verzichten, weil diese sehr schöne Auswertungen und Grafiken zum Stromverbrauch (und zur Stromeinspeisung) liefert.

Und nun? Auf die Werte in der Datenbank verzichten kommt für mich eigentlich nicht in Frage.

Gut, dass es im Haus noch Raspi's gibt und über einen dieser Raspis habe ich nun folgendes gemacht:

  1. Ein kleines Python-Programm liest zyklisch (bei mir im Minutentakt) die Messwerte vom 3EM aus, die dieser auch per http:// Schnittstelle liefert. Näheres zur http:// Schnittstelle findet ihr hier.
  2. Diese Werte werden dann an den MQTT-Broker gesendet. 
  3. Alles was auf dem MQTT-Broker ankommt und den in der Datenbank vorkonfigurierten Geräten (devices) entspricht, wird automatisch gespeichert. Wie das genau passiert, könnt ihr in folgendem Beitrag nachlesen - MQTT Werte in der Datenbank speichern.

So und hier mal was da genau passiert:

Fangen wir mal mit dem Python-Programm an.

#!/usr/bin/env python3
import paho.mqtt.client as mqtt
import time
import urllib.request
import urllib.error
import json

message = 'ON'

Connected = False   #global variable for the state of the connection
broker_address= "XXXSERVERXXX.de"
port = 1883
user = "XXX_USERNAMEXXX"
password = "XXXPASSWORDXXX"

def send_topic(url,topic):
    conn = urllib.request.urlopen(url)
    payload=json.load(conn)
    payload=json.dumps(payload)
    mqttc.connect(broker_address, port=port)
    mqttc.username_pw_set(user, password=password)
    mqttc.publish(topic,payload)
    mqttc.disconnect

mqttc = mqtt.Client()

value=True
while(value):
    f = open('shelly_to_mqtt.json')
    data = json.load(f)

    for element in data['shelly_to_mqtt']:
        url0=element["url"]
        topic0=element["topic"]
        send_topic(url0,topic0)

    time.sleep(60)

    f.close()

Hier noch das json-File ('shelly_to_mqtt.json'), in dem ich die Adressen speichere, die ausgelesen werden sollen:

{
    "shelly_to_mqtt": [
            {
               "url" : "http://192.168.21.65/emeter/0",
               "topic" : "oxolon/DE_RO_AK3/15/emeter0"
            },
            {
               "url" : "http://192.168.21.65/emeter/1",
               "topic" : "oxolon/DE_RO_AK3/15/emeter1"
            },
	    {
               "url" : "http://192.168.21.65/emeter/2",
               "topic" : "oxolon/DE_RO_AK3/15/emeter2"
            }
     ]
}

Unter der jeweiligen url finden sich dann die kompletten json-formatierten Messwerte jeder einzelnen Phase, die vom 3EM gemessen werden. So sieht das zum Beispiel für emeter/1 aus:

{
  "power": 3.56,
  "pf": 0.04,
  "current": 0.36,
  "voltage": 233.83,
  "is_valid": true,
  "total": 377365.3,
  "total_returned": 39983.5
}

Fehlt nur noch ein kleiner Eintrag, um das ganze als Service auf dem Raspi mit systemctl auch zum Laufen zu bringen:

[Unit]
Description=SHELLY MQTT Client/Daemon
Documentation=https://github.com/ironsheep/RPi-Reporter-MQTT2HA-Daemon
After=network-online.target
Wants=network-online.target systemd-networkd-wait-online.service

[Service]
Type=idle
Restart=on-failure
RestartSec=10s
WorkingDirectory=/opt/shelly_to_mqtt/
ExecStart=/usr/bin/python3 -u /opt/shelly_to_mqtt/shelly_to_mqtt_v1.py

[Install]
WantedBy=multi-user.target

Das ganze könnte man sicher noch viel eleganter lösen. Die Angaben zum MQTT-Broker und die dazugehörigen login-Daten könnten genauso in das json-Config-File wie auch die Angabe zur Wartezeit zwischen den einzelnen Messungen. Aber so wie es ist funktioniert es bei mir seit einigen Wochen recht stabil. Ich werde noch einen kleinen Cron-Job einrichten, um das Python-Script immer wieder mal neu zu starten, wobei es in den letzten 3 Monaten auch nur ein einziges Mal "hängengeblieben" ist - warum auch immer.