Eine etwas einfachere Variante mit Hilfe des HomeMatic Strom-/Gassensors HM-ES-TX-WM ist in einem neueren Tutorial beschrieben.
Bitte beachten:
Aufgrund eines Fehlers im Skript (vor 10.10.2015) stimmten nach einem Batteriewechsel bei dem HM-ES-TX-WM die Zählerstände nicht mehr. Der Fehler wurde im Tutorial auf meinem Blog korrigiert. Nutzer, die das Skript vor diesem Datum eigesetzt haben, sollten vor einem Batteriewechsel das Tutorial nochmal durchlesen. Dort wurde ein Workaround eingefügt, mit dem sich die Bestandsdaten der Zeitraumzähler bei einem Batteriewecksel übernehmen lassen.
Mit Stand 31.01.2016 wurde das HM-ES-TX-WM-Tutorial so angepasst, dass der Überlauf des Datenpunktes ENERGY_COUNTER berücksichtigt wird. Bei einem Überlauf und dem Zurücksetzen des Datenpunktes auf NULL laufen die Zeitraumzähler nun problemlos weiter. "Bestandsnutzer" fnden hier ein Workaround zur Anpassung.
Im Folgenden geht es mit der "alten" Anleitung weiter...
Bei Verwendung eines FS20 Zähler-Sensors kann man mit einem an der CCU angeschlossenen CUL über CuxD recht einfach diesbezügliche Daten abgreifen, das wurde an anderer Stelle schon einige Male beschreiben.
Da ich aber keine FS20 Geräte nutze, den CUL also nur für diesen Zweck benötigen würde und aufgrund des Standortes der CCU (für den HM-Funk verwende ich LAN-Adapter) wohl auch eine recht schlechte Funkverbindung zwischen CUL und Zählerkasten hätte, habe ich eine Lösung gewählt, wie ich sie in ähnlicher Art und Weise auch zur Auswertung des Heizölverbrauchs http://homematic-forum.de/forum/viewtop ... 31&t=11974 einsetze.
Der folgende Beitrag beschreibt die Funktionen:
1. Abgriff des Stromzählerstandes und Übertragung in die HomeMatic
2. Zählerauswertung
- Aktueller Zählerstand
- Stromverbrauch seit letzter Ablesung
- Tages-, Wochen-, Monats- und Jahreszähler
- Aktuelle Leistungsaufnahme
- Stromverbrauch der letzten Stunde, 24 Stunden, 7 Tage
3. Statusinformation
1. Abgriff des Stromzählerstandes und Übertragung in die HomeMatic
Da hier im Haus noch ein klassischer Stromzähler verbaut ist, benötigte ich einen Sensor zum Abgriff der roten Markierung auf der Zählerscheibe. Hierzu gibt es von ELV verschiedene Typen von Funksensoren. Ich habe mich für den Funk-Sensor für Wechselstromzähler "EM 1000 WZ" entschieden, da dieser einen +5 V Impulsausgang besitzt, dessen Signale man unmittelbar weiter verarbeiten kann. Ich habe keine wired-Geräte und mich daher für ein "HomeMatic Schließerkontakt-Interface für Öffner und Schließerkontakte" (HM-SCI-3-FM) entschieden, um die Impulse in die CCU zu bekommen. Natürlich kann man z.B. auch eine HM-PBI-4-FM "Funk-Tasterschnittstelle" nehmen.
Meine Zählerscheibe benötigt für 1 kWh 96 Umdrehungen. Bei einer hohen Last (z.B. wenn der Saunaofen an ist) kommen die Impulse so schnell hintereinander, dass die Verarbeitung für die CCU zum Problem wird. Ein Frequenzteiler schafft hier Abhilfe. Ich nutze einen Teiler im Verhältnis 16:1, sodass an der CCU pro kWh statt 96 nur 6 Impulse ankommen. Im Schnitt muss die CCU das Auswertescript so nur alle 8 bis 14 Minuten einmal ausrechnen. Für andere Zähler sind möglicherweise andere Teiler-Verhältnisse sinnvoller.
Zur Realisierung eines solchen Teilers, gibt es unterschiedliche Methoden. Man kann ihn aus integrierten Logikschaltungen oder fertigen Zähler-ICs aufbauen oder einen Microcontroller entsprechend programmieren. Meine Lösung ist die Verwendung eines fertigen, programmierbaren Vorwahlzählers aus der Industrie. Konkret nutze ich einen Omron H7CX-AWD1-N, den ich in der Bucht aus einer Lagerauflösung sehr günstig erstanden habe. Dieser Zähler läuft mit 12 V und kann daher aus dem gleichen Netzteil versorgt werden, wie der EM 1000 WZ. Außerdem kann man die Eingänge auf "PNP-Voltage" einstellen, wodurch der Zähler die +5 V Impulse aus dem EM 1000 WZ direkt (ohne vorgeschalteten Optokoppler/Relais) verarbeiten kann. Natürlich kann man auch andere Vorwahlzähler nehmen.
In ein professionelles Gehäuse eingebaut, sieht das Ganze so aus...
Der Taster ganz links dient dem Reset nach dem Ablesen des Stromzählers (s.u.) und auf der Lochrasterplatine befindet sich ein 3 V Spannungsregler zur Versorgung des HM-SCI-3-FM.
Den Zähler habe ich so eingestellt, dass er nach dem 16. Impuls das HM-SCI-3-FM (heißt bei mir "UE Flur Stromzähler Taktung") für 10 Sekunden einschaltet und sich wieder auf 0 zurücksetzt.
2. Zählerauswertung
Die Auswertung habe ich in Anlehnung an diesen Beitrag (danke!) realisiert: http://homematic-forum.de/forum/viewtop ... zen#p85333.
Zunächst sind folgende Systemvariablen anzulegen...
- "Strom Zaehlerstand", Zahl
"Strom Verbrauch seit letzter Ablesung", Zahl
"Strom Verbrauch laufendes Kalenderjahr", Zahl
"Strom Verbrauch laufender Monat", Zahl
"Strom Verbrauch laufende Woche", Zahl
"Strom Verbrauch heute", Zahl
"Strom Leistungsaufnahme aktuell", Zahl
Hierbei ist "Teiler" das Teilerverhältnis des Vorwahlzählers (in meinem Fall 16) und "Zähler" die Anzahl der Scheibenrotationen pro kWh (in meinem Fall 96):"neuer Wert" = "alter Wert" + ("Teiler"/"Zähler")
und gekürzt..."neuer Wert" = "alter Wert" + (16.0/96)
Im Script sieht das wie folgt aus..."neuer Wert" = "alter Wert" + (1.0/6)
Code: Alles auswählen
var zA = dom.GetObject('Strom Zaehlerstand');
var aA = dom.GetObject('Strom Leistungsaufnahme aktuell');
var vLg = dom.GetObject('Strom Verbrauch seit letzter Ablesung');
var vTg = dom.GetObject('Strom Verbrauch heute');
var vWg = dom.GetObject('Strom Verbrauch laufende Woche');
var vMg = dom.GetObject('Strom Verbrauch laufender Monat');
var vJg = dom.GetObject('Strom Verbrauch laufendes Kalenderjahr');
zA.State(zA.State()+(1.0/6));
vLg.State(vLg.State()+(1.0/6));
vTg.State(vTg.State()+(1.0/6));
vWg.State(vWg.State()+(1.0/6));
vMg.State(vMg.State()+(1.0/6));
vJg.State(vJg.State()+(1.0/6));
var ts1 = zA.Timestamp();
var ts2 = aA.Timestamp();
var tz = aA.State(600000/(ts1.ToInteger()-ts2.ToInteger()));
bei meinen Werten ergibt sich also...1 Impuls = 1kWh * "Teiler" / "Zähler" = 1000 *3600 Ws * "Teiler" / "Zähler"
Die aktuelle Leistungsaufnahme in Watt im Zeitraum zwischen den Ausgangsimpulsen des Vorwahlzählers wird dann wie folgt errechnet...1 Impuls = 1000 * 3600 * 16 / 96 = 600000 Ws
Aufgerufen wird das Script mit folgendem Programm... Da ich mit dem HM-SCI-3-FM sowohl Ein- als auch Ausschaltimpulse auswerten kann, nutze ich den um 10 Sekunden verzögerten (s.o.) Ausschaltimpuls des Vorwahlzählers als Korrekturmöglichkeit, falls mal ein Einschaltimpuls verloren geht. Hierzu dient die zusätzliche Systemvariable "Strom Zaehler Trigger" als Prüfmedium. Die "oder-Verknüpfung" in der "wenn-Bedingung" und die letzten beiden Zeilen in der "dann-Bedingung" können aber auch weggelassen werden, z.B. bei Verwendung eines HM-PBI-4-FM an Stelle des HM-SCI-3-FM oder wenn der genutzte Teiler / Vorwahlzähler den Ausgang nur kurz schalten kann.600000 Ws / "Zeitraum zwischen den Impulsen in Sekunden"
Die Anfangswerte für die jeweiligen CCU-Zähler setzt man manuell, am Besten über WebMatic.
Wer möchte, kann ergänzend den Verbrauch der letzten Stunde, der letzten 24 Stunden und der letzten 7 Tage über das "Universal Wrapper Device" von CuxD auswerten. Wie das grundsätzlich funktioniert, habe ich schon hier beschrieben: http://homematic-forum.de/forum/viewtop ... t=8#p90246.
Hierzu werden zusätzlich folgende Systemvariablen benötigt...
- "Strom Verbrauch letzte 7 Tage", Zahl
"Strom Verbrauch letzte 24 Std", Zahl
"Strom Verbrauch letzte Stunde", Zahl
Code: Alles auswählen
object oZSCux1 = dom.GetObject("Energiemonitor:1");
object o001ZSwT = oZSCux1.DPByHssDP("SWITCH_1H").Value();
object oZSCux2 = dom.GetObject("Energiemonitor:2");
object o024ZSwT = oZSCux2.DPByHssDP("SWITCH_24H").Value();
object o168ZSwT = oZSCux2.DPByHssDP("SWITCH_168H").Value();
var SV001h = dom.GetObject("Strom Verbrauch letzte Stunde");
var SV024h = dom.GetObject("Strom Verbrauch letzte 24 Std");
var SV168h = dom.GetObject("Strom Verbrauch letzte 7 Tage");
real x = SV001h.State(o001ZSwT/6);
x = SV024h.State(o024ZSwT/6);
x = SV168h.State(o168ZSwT/6);
So sieht das Ergebnis aus...
Nach einem Reboot der CCU kann man die fehlenden Impulse einfach durch manuelles Ausführen des Auswerteprogramms nachholen (allerdings stimmt für diesen Zeitbereich dann die Leitungsaufnahmeberechnung natürlich nicht).
Zum Reset der Jahres-, Monats-, Wochen und Tageszähler auf "0" verwende ich Programme, die über das Zeitmodul der CCU kurz nach Mitternacht ausgeführt werden. Hier ein Beispiel für den Tageszähler...
Über die erste Zeile des Programms wird eine Pushnachricht verschickt, mit der die Werte vor dem Reset übermittelt werden. Hierzu verwende ich Pushover, das ich hier (http://homematic-forum.de/forum/viewtop ... 31&t=11579) schon im Detail beschrieben habe. Bei Bedarf kann man die Daten aber natürlich auch per Mail oder über einen anderen Dienst verschicken. Die folgenden Scripte müssen dann entsprechend angepasst werden.
Code: Alles auswählen
string zA = dom.GetObject("Strom Zaehlerstand").Value();
string vJg = dom.GetObject("Strom Verbrauch laufendes Kalenderjahr").Value();
var zeitraum;
! Zeitwert um 1 subtrahieren
time t = system.Date("%Y").ToInteger();
var zeitraum = t - 1;
! Push-Text zusammensetzen
string MailText;
string sDate = zeitraum.ToString();
MailText = "Achtung, der Stromverbrauch-Jahreszaehler wird zurueckgesetzt. Verbrauchswerte am Tag " # sDate # " vor dem Reset: ";
MailText = MailText # "Zaehlerstand: " # zA # "kWh, Strom Verbrauch laufendes Kalenderjahr: " # vJg # "kWh. ";
string teilstr;
string sendmail = "";
! Mailtext erstellen (Wörter am Leerzeichen trennen)
foreach(teilstr, MailText.Split(" "))
{
sendmail = sendmail # "+" # teilstr;
}
! Eigentliche Mail absenden
dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State("curl -s -d token=TOKEN -d user=USER -d message='"#sendmail#"' -d sound=pushover http://api.pushover.net/1/messages.json");
}
Code: Alles auswählen
string zA = dom.GetObject("Strom Zaehlerstand").Value();
string vMg = dom.GetObject("Strom Verbrauch laufender Monat").Value();
var zeitraum;
! Zeitwert um 1 subtrahieren
time t = system.Date("%m").ToInteger();
if (t == 1) {zeitraum = 12;}
else {zeitraum = t - 1;}
! Push-Text zusammensetzen
string MailText;
string sDate = zeitraum.ToString();
MailText = "Achtung, der Stromverbrauch-Monatszaehler wird zurueckgesetzt. Verbrauchswerte am Tag " # sDate # " vor dem Reset: ";
MailText = MailText # "Zaehlerstand: " # zA # "kWh, Verbrauch laufender Monat: " # vMg # "kWh. ";
string teilstr;
string sendmail = "";
! Mailtext erstellen (Wörter am Leerzeichen trennen)
foreach(teilstr, MailText.Split(" "))
{
sendmail = sendmail # "+" # teilstr;
}
! Eigentliche Mail absenden
dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State("curl -s -d token=TOKEN -d user=USER -d message='"#sendmail#"' -d sound=pushover http://api.pushover.net/1/messages.json");
}
Code: Alles auswählen
string zA = dom.GetObject("Strom Zaehlerstand").Value();
string vWg = dom.GetObject("Strom Verbrauch laufende Woche").Value();
var zeitraum;
! Zeitwert um 1 subtrahieren
time t = system.Date("%V").ToInteger();
if (t == 1) {zeitraum = "Letzte KW im Vorjahr";}
else {zeitraum = t - 1;}
! Push-Text zusammensetzen
string MailText;
string sDate = zeitraum.ToString();
MailText = "Achtung, der Stromverbrauch-Wochenzaehler wird zurueckgesetzt. Verbrauchswerte am Tag " # sDate # " vor dem Reset: ";
MailText = MailText # "Zaehlerstand: " # zA # "kWh, Verbrauch laufende Woche: " # vWg # "kWh. ";
string teilstr;
string sendmail = "";
! Mailtext erstellen (Wörter am Leerzeichen trennen)
foreach(teilstr, MailText.Split(" "))
{
sendmail = sendmail # "+" # teilstr;
}
! Eigentliche Mail absenden
dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State("curl -s -d token=TOKEN -d user=USER -d message='"#sendmail#"' -d sound=pushover http://api.pushover.net/1/messages.json");
}
Code: Alles auswählen
string zA = dom.GetObject("Strom Zaehlerstand").Value();
string vTg = dom.GetObject("Strom Verbrauch heute").Value();
var zeitraum;
! Zeitwert um 1 subtrahieren
time t = system.Date("%j").ToInteger();
if (t == 1) {zeitraum = "Letzter Tag im Vorjahr";}
else {zeitraum = t - 1;}
! Push-Text zusammensetzen
string MailText;
string sDate = zeitraum.ToString();
MailText = "Achtung, der Stromverbrauch-Tageszaehler wird zurueckgesetzt. Verbrauchswerte am Tag " # sDate # " vor dem Reset: ";
MailText = MailText # "Zaehlerstand: " # zA # "kWh, Verbrauch heute: " # vTg # "kWh. ";
string teilstr;
string sendmail = "";
! Mailtext erstellen (Wörter am Leerzeichen trennen)
foreach(teilstr, MailText.Split(" "))
{
sendmail = sendmail # "+" # teilstr;
}
! Eigentliche Mail absenden
dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State("curl -s -d token=TOKEN -d user=USER -d message='"#sendmail#"' -d sound=pushover http://api.pushover.net/1/messages.json");
}
Auch hier lasse ich mir die Daten vor dem Reset schicken...
Code: Alles auswählen
string zA = dom.GetObject("Strom Zaehlerstand").Value();
string vLg = dom.GetObject("Strom Verbrauch seit letzter Ablesung").Value();
! Push-Text zusammensetzen
string MailText;
string sDate = system.Date("Tag %j/%Y, %A, %d.%m.%Y, %T Uhr");
MailText = "Achtung, der Stromverbrauch-Ablesezaehler wird zurueckgesetzt. Verbrauchswerte am Tag " # sDate # " vor dem Reset: ";
MailText = MailText # "Zaehlerstand: " # zA # "kWh, Verbrauch seit letzter Ablesung: " # vLg # "kWh. ";
string teilstr;
string sendmail = "";
! Mailtext erstellen (Wörter am Leerzeichen trennen)
foreach(teilstr, MailText.Split(" "))
{
sendmail = sendmail # "+" # teilstr;
}
! Eigentliche Mail absenden
dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State("curl -s -d token=TOKEN -d user=USER -d message='"#sendmail#"' -d sound=pushover http://api.pushover.net/1/messages.json");
}
Über ein mittels Zeitmodul getriggertes Programm können in regelmäßigen Abständen Informationen zum Zählerstand verschickt werden.
Code: Alles auswählen
string zA = dom.GetObject("Strom Zaehlerstand").Value();
string aA = dom.GetObject("Strom Leistungsaufnahme aktuell").Value();
string vLg = dom.GetObject("Strom Verbrauch seit letzter Ablesung").Value();
string vTg = dom.GetObject("Strom Verbrauch heute").Value();
string vWg = dom.GetObject("Strom Verbrauch laufende Woche").Value();
string vMg = dom.GetObject("Strom Verbrauch laufender Monat").Value();
string vJg = dom.GetObject("Strom Verbrauch laufendes Kalenderjahr").Value();
string MailText;
string sDate = system.Date("%d.%m.%Y, %T");
MailText = "Stromzahlerstatus vom " # sDate # ", ZaeStdAkt: " # zA # "kWh ";
MailText = MailText # "LstAfnAkt: " # aA # "W, VbrAbl: " # vLg # "kWh, VbrT: " # vTg # "kWh, VbrW: " # vWg # "kWh, VbrM: " # vMg # "kWh, VbrJ: " # vJg # "kWh. ";
string teilstr;
string sendmail = "";
foreach(teilstr, MailText.Split(" "))
{
sendmail = sendmail # "+" # teilstr;
}
dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State("curl -s -d token=TOKEN -d user=USER -d message='"#sendmail#"' -d sound=bike http://api.pushover.net/1/messages.json");
}