Featured image of post Visualisierung für Smappee und myStrom mit InfluxDB/Grafana

Visualisierung für Smappee und myStrom mit InfluxDB/Grafana

Einleitung

Wie bereits in meinem Beitrag „Jeder mag fancy Dashboards“ angetönt, hat es mir die Kombination aus InfluxDB und Grafana extremst angetan. Seit Januar erfolgte die Fütterung der InfluxDB mit den Strommessdaten von meinem Smappee in Form eines Bash-Scripts zwar äusserst zuverlässig, dies jedoch leider im Scriptstil à la „quick and dirty“. Gute 11 Monate später konnte ich mich nun aber endlich dazu motivieren, das Script nach Python(3) zu migrieren. Da zwischenzeitlich auch mehrere myStrom-Smartplugs in unseren Haushalt Einzug hielten, wurde der Abruf der Strommessung desjenigen, welcher in die Stromzuleitung des Racks eingeschlauft ist, auch gleich mit in das neue Script integriert.

Voraussetzungen

  • Lauffähige InfluxDB-Installation
    Am schnellsten erreicht man dies in Form eines Docker-Containers:
1
root@docker:~# docker run -p 8083:8083 -p 8086:8086 --restart=always --name=influxdb -v influxdb:/var/lib/influxdb influxdb:latest
  • Erstellen einer Datenbank
1
2
3
root@docker:~# docker exec -ti influxdb bash
root@420bb9285990:/# influx
> create database power
  • Lauffähige Grafana-Installation
    Auch hier sei der Einsatz eines Docker Containers angeraten:
1
root@docker:~# docker run -d -p 3000:3000 --restart=always --name=grafana -v grafana-data:/var/lib/grafana -v grafana-log:/var/log/grafana -v grafana-etc:/etc/grafana grafana/grafana:latest
  • Alle benötigten Python3-Module installiert
1
root@docker:~# pip3 install python-mystrom influxdb pycurl

Funktionsweise Script

  • Anmeldung an Smappee mittels HTTP POST Request
  • Abruf der Strommessdaten
  • Formatierung des Outputs
  • Erstellen eines leeren Dictionarys (rd)
  • Durchsuchen des Strommessdaten-Outputs mit Regex nach Name/Wert-Paaren
  • Vermeintlich doppelte Paare (da 3 Phasen) werden mit einem Index versehen
  • Speicherung der gefundenen Name/Wert-Paare in das Dictionary
  • Berechnung und Speicherung der Gesamtleistung
  • Abruf und Speicherung des myStrom-Messwerts und Speicherung im Dictionary
  • Schreiben des Dictionarys in die InfluxDB-Datenbank
  • Konfigurierte Zeit schlafen
  • Zurück zu Punkt 2

Script

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/usr/bin/python3
# Python Modules
import re, time, urllib.request, pycurl, pymystrom
from influxdb import InfluxDBClient
# Configuration Smappee
ip_smappee = '10.11.3.43'
pollcycle = 30
c = pycurl.Curl()
c.setopt(c.URL, 'http://'+ip_smappee+'/gateway/apipublic/logon')
c.setopt(c.HTTPHEADER, ['Content-Type: application/json'])
c.setopt(c.POSTFIELDS, 'admin')
c.setopt(c.VERBOSE, False)
# Configuration Influx_DB
db = InfluxDBClient(host='10.11.1.104', port=8086, database='power')
measurement = 'Messungen'
# Configuration MyStrom
rack = pymystrom.MyStromPlug('10.11.3.40')
# Log in to Smappee
c.perform()
# Main Loop
while True:
    try:
        poll = urllib.request.urlopen('http://'+ip_smappee+'/gateway/apipublic/reportInstantaneousValues')
        data = poll.read().decode('utf-8').replace('<BR>','\n').replace('\t','')
        rd = {}
        for match in re.findall("([^=,\r\n]+)=([^' ',\r\n]+)",data):
            if match[0].strip() in rd:
                if match[0].strip()+'2' in rd:
                    rd[str(match[0].strip()+'3')] = float(match[1].strip())
                else:
                    rd[str(match[0].strip()+'2')] = float(match[1].strip())
            else:
                rd[str(match[0].strip())] = float(match[1].strip())
            try:
                rd['activePowertotal'] = rd.get('activePower') + rd.get('activePower2') + rd.get('activePower3')
            except:
                pass
            try:
                rd['rackPower'] = float(rack.get_consumption())
            except:
                pass

        # Write Dictionary to InfluxDB
        json_body = [
            {
            'measurement': measurement,
            'fields': rd
            }
        ]
        db.write_points(json_body)
    except:
        c.perform()
#   print(rd)
    time.sleep(pollcycle)

Grafana Dashboard

Ist der erste Scriptdurchlauf erfolgt, können die einzelnen Werte in einem Grafana-Dashboard verknüpft, bzw. visualisiert werden – alternativ importiert man sich direkt mein fixfertiges Dashboard:

Smappee Dashboard Download Dashboard

formerly known as struband.net
Built with Hugo
Theme Stack designed by Jimmy