.
.
Vorab zur Info: Alle Erweiterungen, Ergänzungen und Änderungen am Projekt werden in diesem ersten Beitrag veröffentlicht. Man muss also nicht den gesamten Faden (falls es mal einer werden sollte) lesen, um alle Infos zu erhalten.
.
.
Ferarris Stromzähler, Gaszähler und Wasseruhr auslesen
Ziel des Projektes ist es, eine grafische Übersicht über den Stromverbrauch zu erhalten, um eine Optimierung des Stromverbrauchs und der Geräte vornehmen zu können. Ebenso kann die Hardware in leicht abgeänderter Form auch zum Auslesen eines Gaszählers oder einer Wasseruhr genutzt werden. (Plan B)
Da ich immer noch nicht programmieren kann, ist auch dieses Projekt eine Gemeinschaftsproduktion mit Dirk Weyand. So konnte die Hardware optimal an die Software angepasst werden, bzw. umgekehrt.
Nach eingehender Recherche im Internet habe ich einige Schaltungsvorschläge nachgebaut, die alle mehr oder weniger zuverlässig waren. Die einen haben gelegentlich den Durchlauf des roten Balkens „übersehen“, die anderen haben einen roten Balken gesehen, wo gar keiner ist. Wieder andere Schaltungen orientieren sich am S0 Bus, was für meinen Einsatzzweck nicht nötig ist. Daher habe ich mich dazu entschlossen, eine etwas andere Schaltung zu bauen.
Die entworfene Schaltung erkennt zuverlässig und sofern der Sensor exakt positioniert ist, fehlerfrei den Durchlauf des roten Balkens. Das so detektierte Signal wird aufbereitet und über eine fest eingestellte Zeit an den GPIO übertragen. So ist es für die Software möglich, das Signal sauber zu identifizieren.
Wie bereits beim Projekt „PiUS – Die Zisterne sendet Daten zum Wasserstand“ ist der Teil der Software, der die Daten in eine Datei schreibt, im Rahmen von Donationware als Open Source nutzbar. Daher werde ich in diesem Beitrag die jeweils aktuelle Version veröffentlichen. Hierzu eine persönliche Anmerkung: Der Autor gibt sich wirklich viel Mühe und steckt viel Zeit in das Projekt, daher sollten diejenigen, die das Script nutzen, zumindest eine kleine Spende für seine Kaffeekasse springen lassen.
Wer Interesse an der fertig in ein Gehäuse gebauten, getesteten und somit einsatzbereiten Hardware hat, kann mir gerne eine PN senden. Ich habe noch einige Teile hier liegen und könnte noch ein paar Schaltungen aufbauen. Das macht den Tisch leerer und erleichtert die Anschaffung neuer Hardware für künftige Projekte.
Die Fotos zeigen sowohl den ersten Entwurf auf dem Breadbord als auch die in ein Gehäuse gebaute Schaltung mit einer zum Größenvergleich daneben liegenden AA Zelle. Den Sensor habe ich provisorisch in ein Loch einer Plexiglasscheibe gesteckt. Da ich keine passendes Stück Plexiglas hatte, habe ich ein altes RasPi Gehäuse genommen. Die Plexiglasscheibe ist 3mm stark und darf nur so weit ausgefeilt werden, dass der Sensor stramm hineinpasst. Ist das Loch größer, sollte der Sensor angeklebt werden, damit er plan auf der Frontscheibe des Zählers aufliegt. Ist der Sensor einmal richtig ausgerichtet, erkennt er zuverlässig den Durchlauf des roten Balkens.
Der Sensor sollte mit der Schrift nach unten montiert werden und möglichst exakt plan auf dem Zähler aufliegen, so dass die Scheibe mittig zum Sensor liegt. Zur Justage der Schaltung muss das Poti (Drehwinkel 270 Grad) vorsichtig ganz nach rechts (Uhrzeigersinn) gedreht werden. Danach wird es so lange langsam nach links gedreht, bis die grüne LED für 2 Sekunden leuchtet. Dann wieder einen Hauch zurück nach rechts. Nun sollte die Einstellung passen und die LED bei jedem Durchlauf des roten Balkens aufleuchten. Nicht aufleuchten sollte die LED, wenn der silberne Bereich der Scheibe durchläuft. Sollte dies doch der Fall sein, muss die Justage nochmals vorgenommen werden.
Ich habe beide Schaltungen innerhalb von 5 Minuten zuverlässig justiert. Es ist also kein großer Aufwand. Einmal so eingestellt läuft die Schaltung zuverlässig.
Die beigefügte Grafik zeigt exemplarisch den Stromverbrauch über etwas mehr als 24 h.
Inzwischen habe ich erfolgreich zwei verschiedene Bauarten von Wasserzählern auslesen können. Dies ist zwar nicht ganz so einfach wie beim Stromzähler, aber es funktioniert mit dieser Schaltung ebenso gut, wenn der Sensor erst einmal richtig positioniert und das Poti passend eingestellt wurde.
Die angehangene Datei wird nach /home/pi/piem/ kopiert, bzw. die r3 nach /home/pi/piem/bin/
Die Datei r3 bitte von hier herunterladen: http://www.tgd-consulting.de/REBOL/r3-RPi.tar
Das Script wir gestartet mit cd /home/pi/piem && nohup sudo ./bin/r3 PiEMZaehler.r &
REBOL [
Title: "Verbrauchszaehler"
Name: PiEMZaehler
Version: 0.4.1
Date: 12-Jun-2014
File: %PiEMZaehler.r
Author: "Dirk Weyand"
Copyright: "TGD-Consulting"
Homepage: http://rebol.tgd-consulting.de
E-Mail: [info AT tgd-consulting DOT de]
History: [ 26-May-2014 0.1.0 "inital release"
27-May-2014 0.1.1 "fixed GPIO-init"
28-May-2014 0.1.2 "enhanced offset/GPIO-init"
28-May-2014 0.1.3 "changed logging"
29-May-2014 0.1.4 "removed timezone-info"
29-May-2014 0.2.0 "added current consumption"
29-May-2014 0.2.1 "fixed current consumption"
30-May-2014 0.3.0 "added configuration file"
30-May-2014 0.3.1 "fixed previous accounting"
03-Jun-2014 0.3.2 "enhanced object-spec"
10-Jun-2014 0.3.3 "fixed trigger"
12-Jun-2014 0.4.0 "added high frequency meter support"
12-Jun-2014 0.4.1 "changed high precision time"
]
License: { Donationware, visit http://download.tgd-consulting.de#Donate to make a donation. }
Purpose: { This script provides a smart meter solution to remote readout your meter on the Raspberry Pi with Rebol3.
Before you can use this script, you need to built the R3-binary from the mainline R3 sources on GitHub (https://github.com/rebol/rebol)
or download a ready-made binary for Raspbian at http://www.tgd-consulting.de/REBOL/r3-RPi.tar .}
Usage: [ sudo ./r3 PiEMZaehler.r [configfile] ]
]
;###############
;### ###
;### Globals ###
;### ###
;###############
Zaehler-spec: make object! [ ; Spezifikation der Zähler Objektklasse
Offset: 56080.3 ; Offset des Verbrauchszählers/aktueller Zählerstand
delta: 1 / 75 ; Verbrauch pro Zählimpuls
rate: 1 ; Abtastrate in Sekunden (jede Sekunde)
state: none ; zuletzt erfasster Zustand
when: 25-May-2014 ; Zeitpunkt der letzten Abfrage
old: 25-May-2014 ; Zeitpunkt des letzten Impuls
GPIO: 25 ; verwendeter GPIO zum Auslesen des Trigger-Impuls des Zählers
file: %Stromverbrauch.txt ; Log-File der Messergebnisse
type: 'Electricity ; Zählertyp (Electricity, Water, Gas)
feeding: 0 ; Nutzungsart (0=Verbrauchszähler, 1=Einpeisungszähler)
Number: #123456789 ; Zählernummer
Comment: "Strom" ; Beschreibung des Zählers
]
Zaehler: [] ; Liste der Zaehlerobjekte
verbose: false ; bei true erfolgt Bildschirmausgabe der Messwerte (Ausgabe nach STDOUT)
Trigger: %/run/shm/.rm_PiEMlog ; Falls Trigger-Datei vorhanden -> wird das Log-File ueberschrieben
Triggered: [] ; bei allen Sensoren wurden Messwerte erfasst -> wird der Trigger geloescht
config-file: none ; Konfigurationsdatei
sleep: 60 ; maximale Abtastrate/Sleeptime
args: val: none
attempt [all [system/script/args not equal? 'dir exists? foo: to file! first args: parse system/script/args " " config-file: foo]] ;checks 4 configfile as optional script argument
either config-file [ ; Konfiguration einlesen und verwenden
foreach spec attempt [read/lines config-file] [
append Zaehler make Zaehler-spec first to block! spec
]
][ ; Default Konfiguration verwenden
insert Zaehler make Zaehler-spec []
]
jetzt: func [ {aktuelle Zeit ohne Angabe für Zeitzone.}
/precise "sehr präzise Zeitangabe"
/local t
][
t: either precise [now/precise][now]
t/zone: none
t
]
verbrauch: func [ {Berechnet die aktuell abgenommene Leistung in Watt.}
o [object!] "Zählerobjekt"
/local dx dy
][
dx: divide to integer! difference o/when o/old 3600 ; vergangene Zeit in Stunden
dy: o/delta * 1000 ; Verbrauch in Wattstunden
to integer! dy / dx ; aktuelle Leistung in Watt
]
; Init GPIOs
foreach obj zaehler [
print ajoin [t: jetzt " [ PiEM-It! Zaehler: Initializing GPIO" obj/GPIO "... ]"]
call/wait ajoin [{echo "} obj/GPIO {" > /sys/class/gpio/export}] ; GPIO aktivieren
write to file! ajoin ["/sys/class/gpio/gpio" obj/GPIO "/direction"] #{696E0A} ; GPIO ist Eingang #{696E0A} = "in^/"
sleep: min obj/rate sleep ; Sleep = minimale Abtastrate
all [exists? obj/file ; Logfile existiert?
foo: last read/lines obj/file ; Messwert vorhanden
val: to decimal! second foo: parse foo " "
greater? val obj/offset ; Wert groesser als obiger Offset
obj/offset: val ; letzten Zaehlerstand aus Logfile ¸bernehmen
obj/when: to date! foo/1 ] ; letzten Zeitpunkt aus Logfile ¸bernehemen
all [obj/state: equal? read to file! ajoin ["/sys/class/gpio/gpio" obj/GPIO "/value"] #{310A} ; aktueller Pegel am GPIO
obj/offset: obj/offset + obj/delta ; bei High Zählerstand
obj/when: t ] ; und Datum aktualisieren
obj/old: obj/when ; Zeitpunkt des letzten gemessen Impulses
print ajoin [t " [ PiEM-It! Zaehler: " obj/comment "@GPIO" obj/GPIO ", aktueller/letzter Zaehlerstand: " obj/offset " vom: " obj/when " ]"]
]
print [jetzt "[ PiEM-It! Zaehler: Starting metering... ( sleep:" sleep ") ]"]
forever [
t: jetzt/precise ; aktueller Zeitpunkt ohne Zeitzone
foreach obj zaehler [ ; Abfrage aller vorhandenen Zaehler
t1: stats/timer ; zur Berechnung der Latenzzeit erforderlich
if any [lesser? obj/rate 1 greater-or-equal? t obj/when + to time! obj/rate] [ ; Zähler muss abgefragt werden?
val: equal? read to file! ajoin ["/sys/class/gpio/gpio" obj/GPIO "/value"] #{310A} ; High am GPIO?
obj/when: t ; Zeitpunkt der Abfrage
if all [not equal? val obj/state ; Impulswechsel
not obj/state ; von Low -> High
obj/offset: obj/offset + obj/delta ; Zählerstand aktualisieren
][
; Logging-Format (REBOL kompatibel)
if greater-or-equal? difference obj/when obj/old 0:00:01 [ ; Zählerstand loggen (sekündlich bei High Frequency Metern)
foo: ajoin [t/date "/" round/down t/time " " obj/offset " " v: verbrauch obj newline]
obj/old: obj/when ; Zeitpunkt der vorherigen Abfrage
either all [exists? Trigger none? find Triggered obj/GPIO] [
write obj/file foo ; Log-Eintrag fuer Zähler in neue Datei schreiben
insert Triggered obj/GPIO ; Sensor wurde getriggert
][
write/append obj/file foo ; Log-Eintrag fuer Zähler ans Ende der Datei schreiben
]
all [verbose ; Ausgabe nach STDOUT
t2: stats/timer ; zur Berechnung der Latenzzeit erforderlich
print ajoin [obj/when " [ PiEM-It! Zaehler: " obj/comment "@GPIO" obj/GPIO ", Zaehlerstand[kWh]: " round/to obj/offset 0.001 ", Verbrauch[W]: " v ", Latenzzeit[s]: " t2 - t1 " ]"]
]
]
]
obj/state: val ; aktueller Zustand des GPIO
]
]
wait sleep ; Sleep-Time
all [equal? length? Triggered length? zaehler ; alle Sensoren wurden getriggert wurden
delete Trigger clear Triggered] ; -> Trigger loeschen
]
; Reset GPIOs
foreach obj zaehler [
call/wait ajoin [{echo "} obj/GPIO {" > /sys/class/gpio/unexport}] ; GPIO deaktivieren
]
halt
;#EOF
Display More
FAQ:
Ist der Sensor empfindlich gegen Fremdlich?
Der Sensor scheint empfindlich auf Fremdlicht zu reagieren. Beim Einschalten der Neonröhre, die sich über dem Sensor befindet, gibt es Ausschläge in der Grafik. Beim direkten Einfall von Tageslicht ist eine Kalibrierung sehr schlecht möglich. Diese nimmt man am besten bei indirekter Beleuchtung oder in der Dämmerung vor.
Welche Daten werden benötigt, wenn ich die Schaltung kaufen möchte?
Benötigt wird die Angabe der Kabellänge vom Sensor zum Gehäuse und die Kabellänge vom Gehäuse zum Raspberry Pi. Auch muss im Vorfeld geklärt werden, ob mindestens 15 mm Platz zwischen Zählerfront und Schranktür sind, damit der Sensor montiert werden kann. Wichtig ist auch die Angabe der U/kWh, die auf dem Zähler aufgedruckt ist. Sofern dort 96 U/kWh oder mehr steht, muss durch Inbetriebnahme von Großverbrauchern (Mikrowelle, Fön, Herd, etc.) einmalig getestet werden, wie lange in etwa eine Umdrehung der Zählerscheibe dauert.
Was wird das Gerät kosten?
Dazu kann ich erst am Ende der Woche etwas sagen, wenn ich einen Gesamtüberblick habe. Ich schätze es werden rund 39 Euro sein.
Was bekomme ich für mein Geld?
Erstellt wird die Schaltung mit den gewünschten Kabellängen. Sie ist getestet und sauber in ein Gehäuse verbaut. Der Sensor ist bereits in eine ca. 60 x 80 mm große Plexiglasscheibe eingesetzt, die nur noch auf dem Zähler montiert werden muss. Das Kabel zum Raspberry ist mit einem Stecker versehen, der auf die GPIO Pins 4,6,8 (5V, GND, GPIO 14) gesteckt wird. Es fallen also keine Lötarbeiten an. Sollte GPIO 14 belegt sein, muss dies im Vorfeld geklärt werden.
Was ist, wenn ich einen anderen GPIO nutzen möchte?
Wenn ich das vorher weiß, installiere ich einen Doppelstecker für die Stromversorgung und einen einfachen Stecker für den abgesetzten GPIO.
Wie sind die Kabelfarben zugeordnet?
Das Kabel besteht aus drei Leitungen:
grün - Pluspol
braun - Minuspol
weiss - Signal
Wie wird die Schaltung justiert?
Dazu schrieb ich etwas weiter oben im Text:
Der Sensor sollte mit der Schrift nach unten montiert werden und möglichst exakt plan auf dem Zähler aufliegen, so dass die Scheibe mittig zum Sensor liegt. Zur Justage der Schaltung muss das Poti (Drehwinkel 270 Grad) vorsichtig ganz nach rechts (Uhrzeigersinn) gedreht werden. Danach wird es so lange langsam nach links gedreht, bis die grüne LED für 2 Sekunden leuchtet. Dann wieder einen Hauch zurück nach rechts. Nun sollte die Einstellung passen und die LED bei jedem Durchlauf des roten Balkens aufleuchten. Nicht aufleuchten sollte die LED, wenn der silberne Bereich der Scheibe durchläuft. Sollte dies doch der Fall sein, muss die Justage nochmals vorgenommen werden.
edit 03.06.2014: Der zweite Zähler wurde provisorisch mit der Schaltung bestückt und Fotos hinzugefügt.
edit 09.06.2014: Aktuelle Version der Software 0.3.2 veröffentlicht, FAQ erweitert, aktuelle Grafik angehangen.
edit 11.06.2014: Aktuelle Version 0.3.3 der Software veröffentlicht, erstmalig Wasserzähler ausgelesen
edit 12.06.2014: Aktuelle Version 0.4.1 der Software veröffentlicht