Slimme meter lezen met Zabbix en OpenWRT

Mijn slimme meter stond al jaren te wachten op uitlezen. Nu heb ik het even gefixt – met Zabbix. Gewoon, omdat als je een hamer hebt, alles eruit ziet als een spijker. Ik heb Zabbix en ik lees dus uit met Zabbix.
In English: I’m reading my smart meter with OpenWRT and Zabbix. It’s not perfect, but hey, it works.

Om de slimme meter uit te lezen met OpenWRT en Zabbix, hebben we een aantal dingen nodig:

  • een slimme meter
  • een kabel om de meter uit te lezen, aangesloten op…
  • … een OpenWRT-station met tenminste één USB-poort. Ik gebruik een TP-Link Archer C7, maar en zijn tientallen andere mogelijkheden.
  • Een Zabbix-server

Als eerste richten we de OpenWRT-kant van de zaken in: data van de meter beschikbaar maken en daarna koppelen met de Zabbix-agent. Doe het volgende.

Uitlezen seriële poort

Installeer in elk geval usbutils, zabbix-agentd en coreutils-stty; als je USB-seriële kabel van de soort “FTDI” is (zie hieronder, de output van lsusb), moet je ook kmod-usb-serial-ftdi installeren. Heb je een andere seriële kabel – dan moet je zelf even uitzoeken wat je nodig hebt:

# opkg update
# opkg install usbutils zabbix-agentd coreutils-stty
# lsusb
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
# opkg install kmod-usb-serial-ftdi

Eenmalig moet je de seriële poort op de juiste snelheid instellen. Dat kan met “stty”:

stty 115200 -F /dev/ttyUSB0

Nu kun je, als het goed is, de poort uitlezen. Probeer het eens (en breek af met control-C):

cat /dev/ttyUSB0

De output ziet er als het goed is ongeveer zo uit (met extra regelovergangen, die heb ik hieronder weggelaten):

/ISK5\2M550E-1012
1-3:0.2.8(50)
0-0:1.0.0(200414172105S)
0-0:96.1.1(4530303433303036383630313632333137)
1-0:1.8.1(003437.166kWh) 1-0:1.8.2(003037.153kWh)
1-0:2.8.1(000001.602kWh) 1-0:2.8.2(000000.000kWh)

Werkt dat? Zorg dan dat het stty-commando in /etc/rc.local komt te staan, opdat het na een herstarten automatisch uitgevoerd wordt.

Oh ja: als je slimme meter een andere baudrate op de P1-lijn gebruikt, vervang dan de 115200 door de betreffende baudrate.

Uitvoer beschikbaar maken

Nu moeten we de informatie uit /dev/ttyUSB0 op een zinnige manier ergens beschikbaar maken voor de Zabbix-agent. Dat kan op verschillende manieren. Ik koos een beetje een vunzige manier, vind ik zelf, door gewoon elke minuut de meter eenmaal uit te lezen en de informatie, al dan niet vertaald, in een bestand te zetten, een en ander met standaard aanwezige utilities: cron, grep en sed. Het kan natuurlijk best anders: je kunt best een Python-script schrijven of in C een utility bouwen – enfin, dat deed ik dus allemaal niet. Ik maakte een script aan in /root/ met de naam iskra.sh, met de volgende inhoud:

#!/bin/sh
sed '1,/^\/ISK5/d
/^!/q' /dev/ttyUSB0 |grep -v '^$' | sed -f iskraconvert.sed > /tmp/isk0
mv /tmp/isk0 /tmp/iskra

Het script iskraconvert.sed kun je vooralsnog even leeg laten, we gaan het zo meteen vullen met informatie. Draai iskra.sh eenmalig en kijk of het bestand iskra zich in de /tmp/-directory bevindt. In dit bestand vind je één enkel bericht vanuit de meter.

Nu de conversie. Omdat ik niet zoveel zin heb om op regels als 1-0:2.8.1(000001.602*kWh) te zoeken, converteer ik de voor mij belangrijke gegevens alvast voor Zabbix. Ik vervang de code en het getal tussen haakjes door een enkelvoudig naam:waarde. Zo wordt de regel 1-0:2.8.1…. van twee zinnen terug vervangen door nightpowerused:000001.602. Het bestand /root/iskraconvert.sed voert deze conversies uit, de inhoud is bij mij als volgt:

s/^1-0:1.7.0(\(.*\)\*kW).*$/actualpower:\1/
s/^1-0:32.36.0(\(.*\)).*$/powerswells:\1/
s/^1-0:32.32.0(\(.*\)).*$/powersags:\1/
s/0-1:24.2.1(.*)(\(.*\)\*m3).*/gas:\1/
s/1-0:1.8.1(\(.*\)\*kWh).*$/nightpowerused:\1/
s/1-0:1.8.2(\(.*\)\*kWh).*$/daypowerused:\1/

Ik converteer lang niet alles. Ik heb geen zonnepanelen, dus de teruggeleverde energie meet ik niet – maar een simpel regeltje dat 1-0:2.8.2 omzet in huppeldepuppowerdelivered is zo toegevoegd.

Iets anders is, dat de punten eigenlijk van een escape \ voorzien zouden moeten worden: 1-0:1\.7\.0(. Ik laat het maar zo – er zijn toch geen regels die matchen op de huidige regexps. Tenslotte moet nog vermeld, dat het P1-protocol ingebouwde foutcorrectie heeft: het getal aan het einde van het bericht (hieronder: 0E58) kun je gebruiken om de geldigheid van het bericht te controleren. Ik doe dat allemaal niet – wil je het wel doen, dan lijkt me Python of C de juiste aanvliegroute.
Als je nu iskra.sh nog een keer draait, krijg je als het goed is uitvoer die er ongeveer zo uit ziet:

1-3:0.2.8(50)
0-0:1.0.0(200415094740S)
0-0:96.1.1(4530303433303042453630313632333137)
nightpowerused:003439.774
daypowerused:003040.419
1-0:2.8.1(000001.602*kWh)
1-0:2.8.2(000000.000*kWh)
0-0:96.14.0(0002)
actualpower:00.298
1-0:2.7.0(00.000*kW)
0-0:96.7.21(00012)
0-0:96.7.9(00005)
1-0:99.97.0(3)(0-0:96.7.19)(170408160804S)(0000000285*s)(170410104401S)(0000153355*s)(191105135919W)(0000006636*s)
powersags:00009
powerswells:00001
0-0:96.13.0()
1-0:32.7.0(233.3*V)
1-0:31.7.0(001*A)
1-0:21.7.0(00.241*kW)
1-0:22.7.0(00.000*kW)
0-1:24.1.0(003)
0-1:96.1.0(4730303339303048543130343334333137)
gas:01732.430
!0E58

Zoals je ziet, zijn niet alle waarden geconverteerd. Dat vind ik niet erg.

We hebben nu een relatief betrouwbare manier om de meter uit te lezen. Let op: het script loopt grandioos de mist in als je het tweemaal, tegelijk, laat draaien; /dev/ttyUSB0 kun je niet “verdelen”, het is geen daemon, het is een enkelvoudige seriële lijn.

Daarom zet ik bovenstaand script in een cron-job: elke minuut wordt /tmp/iskra ververst. Zet in /etc/crontabs/root het volgende:

* * * * * /root/iskra.sh

Herstart de cron-daemon. Er wordt nu elke minuut een bestand /tmp/iskra weggeschreven. Dit gaan we laten uitlezen door de Zabbix-agent. Let dus op: de resolutie is, in plaats van elke seconde een waarde zoals de slimme meter dit kan, gereduceerd tot eenmaal per minuut.

Zabbix agent koppelen

Het configureren van de zabbix-agent en zabbix-server laat ik even aan je eigen fantasie over. Het volstaat om je OpenWRT-station in Zabbix te hebben, waarbij je de Template App Zabbix (al dan niet Active) Agent hebt toegevoegd: je hebt dan in elk geval de agent.ping, agent.hostname en agent.version waarden in de configuratie op de server staan. Je moet deze waarden ook daadwerkelijk kunnen uitlezen.

Voeg nu een bestand met de naam iskra.conf toe aan de directory /etc/zabbix_agentd.conf.d/ in OpenWRT. De inhoud van dit bestand moet zijn:

# power/gas meter
UserParameter=iskra[*],sed -n "/^$1:/s/^$1://p" /tmp/iskra

Ofwel: als Zabbix “iskra[gas]” opvraagt, zal de agent in het bestand /tmp/iskra op zoek gaan naar de regel die begint met “gas:” en de waarde die daar achter staat aan de agent leveren.

[wordt vervolgd]

2 Replies to “Slimme meter lezen met Zabbix en OpenWRT”

  1. Nice, ik las de P1 al uit in Domoticz maar om Zabbix beter te leren kennen vond ik dit ook wel een geinige toepassing. Het heeft me weer iets geleerd, thanks! En ondertussen blijft Domoticz ook dezelfde data verwerken 😬

  2. Hoi, leuk dat het werkt, wel een waarschuwing: ik vermoed dat je sporadisch Zabbix-fouten zult zien, omdat er nu twee processen de /dev/ttyUSB0 proberen uit te lezen. En dat kan wel – maar niet op een goede manier.

Comments are closed.