Endlich konnte ich meine Optokoppler den ich bei Nils von Volkszähler bestellt habe in Betrieb nehmen. Bei mir hat es mit OH 2.4 und dem Einbinden des Optokopplers als Thing über die GUI auf Anhieb funktioniert. Aus unterschiedlichen Quellen habe ich hier aber auch schon von Problemen gehört von denen ich zum Glück verschont geblieben bin.
Nun zur Einrichtung. Ich möchte natürlich den aktuellen Verbrauch sowie den Gesamtverbrauch sehen. Dazu werden folgende Items angelegt und natürlich ins Sitemap eingebunden. Ich verwende hier auch das neue UOM Konzept:
Number:Energy STR_act "Stromverbrauch akt [%.0f %unit%]" <energy> {channel="smartmeter:meter:6fd23207:1-0_16-7-0"} Number:Energy STR_sum "Stromverbrauch ges [%.2f %unit%]" <energy> {channel="smartmeter:meter:6fd23207:1-0_1-8-0"}
Darüber hinaus will ich noch den Verbrauch der letzten 7 Tage (STR_D0 bis STR_D6) sowie pro Monat (STR_1 bis STR_12) sehen. Und ich hab mir noch zwei Hilfsvariablen angelegt. Diese habe ich als Item angelegt damit sie nicht weg sind wenn ich den PI einmal durchstarte. Um die Items muss ich mir nämlich keine Gedanken machen da die MAP DB diese speichert und wiederherstellt.
Number STR_help_d "Stromverbruach helper Tag [%.2f]" Number STR_help_m "Stromverbruach helper Monat [%.2f]" Number STR_D0 "heute [%.2f kWh]" Number STR_D1 "-1 [%.2f kWh]" Number STR_D2 "-2 [%.2f kWh]" Number STR_D3 "-3 [%.2f kWh]" Number STR_D4 "-4 [%.2f kWh]" Number STR_D5 "-5 [%.2f kWh]" Number STR_D6 "-6 [%.2f kWh]" Number STR_1 "Januar [%.2f kWh]" (gStrom) Number STR_2 "Februar [%.2f kWh]" (gStrom) Number STR_3 "März [%.2f kWh]" (gStrom) Number STR_4 "April [%.2f kWh]" (gStrom) Number STR_5 "Mai [%.2f kWh]" (gStrom) Number STR_6 "Juni [%.2f kWh]" (gStrom) Number STR_7 "Juli [%.2f kWh]" (gStrom) Number STR_8 "August [%.2f kWh]" (gStrom) Number STR_9 "September [%.2f kWh]" (gStrom) Number STR_10 "Oktober [%.2f kWh]" (gStrom) Number STR_11 "November [%.2f kWh]" (gStrom) Number STR_12 "Dezember [%.2f kWh]" (gStrom)
Kommen wir nun zu den Regeln und beginnen mit dem was wir für die Werte der letzten 7 Tage brauchen. Immer um Mitternacht reichen wir die Variablen eins weiter. Somit ist in D0 immer der Wert des aktuellen Tags und in den anderen Variablen absteigend die letzten Tage.
rule "Strom_taegl" when Time is midnight then STR_D6.postUpdate(STR_D5.state) STR_D5.postUpdate(STR_D4.state) STR_D4.postUpdate(STR_D3.state) STR_D3.postUpdate(STR_D2.state) STR_D2.postUpdate(STR_D1.state) STR_D1.postUpdate(STR_D0.state) STR_help_d.postUpdate(STR_sum.state) STR_D0.postUpdate(0.0) end
Das ganze ist mit den labels leider etwas unschön weshalb die Regel auch die Tage in die labels setzt. Abhängig vom aktuellen Wochentag werden die labels absteigend entsprechend umbenannt:
switch now.getDayOfWeek{ case 1: { STR_D0.label = "Montag" STR_D1.label = "Sonntag" STR_D2.label = "Samstag" STR_D3.label = "Freitag" STR_D4.label = "Donnerstag" STR_D5.label = "Mittwoch" STR_D6.label = "Dienstag" } case 2: { STR_D0.label = "Dienstag" STR_D1.label = "Montag" STR_D2.label = "Sonntag" STR_D3.label = "Samstag" STR_D4.label = "Freitag" STR_D5.label = "Donnerstag" STR_D6.label = "Mittwoch" } case 3: { STR_D0.label = "Mittwoch" STR_D1.label = "Dienstag" STR_D2.label = "Montag" STR_D3.label = "Sonntag" STR_D4.label = "Samstag" STR_D5.label = "Freitag" STR_D6.label = "Donnerstag" } case 4: { STR_D0.label = "Donnerstag" STR_D1.label = "Mittwoch" STR_D2.label = "Dienstag" STR_D3.label = "Montag" STR_D4.label = "Sonntag" STR_D5.label = "Samstag" STR_D6.label = "Freitag" } case 5: { STR_D0.label = "Freitag" STR_D1.label = "Donnerstag" STR_D2.label = "Mittwoch" STR_D3.label = "Dienstag" STR_D4.label = "Montag" STR_D5.label = "Sonntag" STR_D6.label = "Samstag" } case 6: { STR_D0.label = "Samstag" STR_D1.label = "Freitag" STR_D2.label = "Donnerstag" STR_D3.label = "Mittwoch" STR_D4.label = "Dienstag" STR_D5.label = "Montag" STR_D6.label = "Sonntag" } case 7: { STR_D0.label = "Sonntag" STR_D1.label = "Samstag" STR_D2.label = "Freitag" STR_D3.label = "Donnerstag" STR_D4.label = "Mittwoch" STR_D5.label = "Dienstag" STR_D6.label = "Montag" } }
Und hier die Regel komplett
rule "Strom_taegl" when Time is midnight then STR_D6.postUpdate(STR_D5.state) STR_D5.postUpdate(STR_D4.state) STR_D4.postUpdate(STR_D3.state) STR_D3.postUpdate(STR_D2.state) STR_D2.postUpdate(STR_D1.state) STR_D1.postUpdate(STR_D0.state) STR_help_d.postUpdate(STR_sum.state) STR_D0.postUpdate(0.0) switch now.getDayOfWeek{ case 1: { STR_D0.label = "Montag" STR_D1.label = "Sonntag" STR_D2.label = "Samstag" STR_D3.label = "Freitag" STR_D4.label = "Donnerstag" STR_D5.label = "Mittwoch" STR_D6.label = "Dienstag" } case 2: { STR_D0.label = "Dienstag" STR_D1.label = "Montag" STR_D2.label = "Sonntag" STR_D3.label = "Samstag" STR_D4.label = "Freitag" STR_D5.label = "Donnerstag" STR_D6.label = "Mittwoch" } case 3: { STR_D0.label = "Mittwoch" STR_D1.label = "Dienstag" STR_D2.label = "Montag" STR_D3.label = "Sonntag" STR_D4.label = "Samstag" STR_D5.label = "Freitag" STR_D6.label = "Donnerstag" } case 4: { STR_D0.label = "Donnerstag" STR_D1.label = "Mittwoch" STR_D2.label = "Dienstag" STR_D3.label = "Montag" STR_D4.label = "Sonntag" STR_D5.label = "Samstag" STR_D6.label = "Freitag" } case 5: { STR_D0.label = "Freitag" STR_D1.label = "Donnerstag" STR_D2.label = "Mittwoch" STR_D3.label = "Dienstag" STR_D4.label = "Montag" STR_D5.label = "Sonntag" STR_D6.label = "Samstag" } case 6: { STR_D0.label = "Samstag" STR_D1.label = "Freitag" STR_D2.label = "Donnerstag" STR_D3.label = "Mittwoch" STR_D4.label = "Dienstag" STR_D5.label = "Montag" STR_D6.label = "Sonntag" } case 7: { STR_D0.label = "Sonntag" STR_D1.label = "Samstag" STR_D2.label = "Freitag" STR_D3.label = "Donnerstag" STR_D4.label = "Mittwoch" STR_D5.label = "Dienstag" STR_D6.label = "Montag" } } end
Für die Anzeige der monatlichen Werte habe ich einen etwas anderen Ansatz gewählt. Dazu muss man sich zunächst am Monatsersten den aktuellen Wert speichern und zwar mit folgender Regel:
rule "Strom_monatl" when Time cron "0 0 0 1 * ?" then STR_help_m.postUpdate(STR_sum.state) end
Und damit haben wir dann auch unser Rüstzeug und können die Werte schließlich ermitteln und updaten. Der Teil für die täglichen Werte ist ganz einfach. Mit ein paar kleinen Helferlein wird die Differenz berechnet und dann schließlich in STR_D0 geschrieben.
var float helper_d = 0 var float diff_d = 0 var float sum = 0 rule "Strom_aktualisiert" when Item STR_sum changed then helper_d = (STR_help_d.state as Number).floatValue sum = (STR_sum.state as QuantityType<Number>).floatValue diff_d = ( sum - helper_d ) / 1000 STR_D0.postUpdate(diff_d) end
Der Teil für die Monate ist etwas kniffeliger aber sobald man das System raus hat auch nicht wirklich schwierig. Zunächst ermitteln wir auch hier die Differenz zum Monatsanfang. Dann folgt die Magie indem wir den dynamisch ermittelten Namen in der Gruppe gStrom, welche wir oben den Items zugewiesen haben suchen und somit das aktuelle Monatsitem an der Hand haben um diesem dann den ermittelten Wert zuzuweisen.
var float helper_m = 0 var float diff_d = 0 var float sum = 0 rule "Strom_aktualisiert" when Item STR_sum changed then helper_m = (STR_help_m.state as Number).floatValue sum = (STR_sum.state as QuantityType<Number>).floatValue diff_d = ( sum - helper_d ) / 1000 diff_m = ( sum - helper_m ) / 1000 val monthStrom = gStrom.members.findFirst[name.equals("STR_"+now.getMonthOfYear)] monthStrom.postUpdate(diff_m) end
Die Regel sieht dann fertig so aus:
var float helper_d = 0 var float helper_m = 0 var float diff_d = 0 var float diff_m = 0 var float sum = 0 rule "Strom_aktualisiert" when Item STR_sum changed then helper_d = (STR_help_d.state as Number).floatValue helper_m = (STR_help_m.state as Number).floatValue sum = (STR_sum.state as QuantityType<Number>).floatValue diff_d = ( sum - helper_d ) / 1000 diff_m = ( sum - helper_m ) / 1000 STR_D0.postUpdate(diff_d) val monthStrom = gStrom.members.findFirst[name.equals("STR_"+now.getMonthOfYear)] monthStrom.postUpdate(diff_m) end
Und jetzt mal sehen ob sich das bewährt. Klar kann man hier auch viel mit Graphen etc. machen aber ich bin ein Freund der nackten Zahlen und möchte einfach und schnell eine Übersicht über den Verbrauch haben.
Off Topic: Da ich zu faul war das USB Kabel zu verlegen und noch ein nicht genutztes Netzwerkkabel in der Nähe des Zählerschranks verfügbar war habe ich mir bei Aliexpress für wenige € ein USB RJ45 Extern geschossen. Funktioniert super!