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!
Hallo Christian,
super Arbeit! Klasse!
Ich habe evrsucht umzusetzen aber ohne Erfolg. Die Variable wurde gesetzt aber die Berechnung STR_D0 erfolg nicht bzw. belibt beim 0.0 Kwh.
Kannst du mir bitte helfen?
Danke dir!
Beste Grüße,
Pampulea
Hi,
das liegt bestimmt daran dass die Variable „STR_help_d“ noch nicht initialisiert ist. Entweder die Regel „Strom_taegl“ einmal ausführen oder bis morgen warten weil um Mitternacht die Regel sowieso ausgeführt wird. Könnte man noch in die Regel „Strom_aktualisiert“ einbauen dass die die Variable bei bedarf initialisiert aber das kommt ja nur wirklich einmal beim initialen Aufsetzen vor.
Grüße
Christian
Hallo Christian,
doch die Variable „STR_help_d“ ist mit dem richtigen Wert initialisiert. Ich habe seit 2 Tage installiert. Die letzten 2 Tage sind mit 0 ausgefüllt. Es gib soweit ich als Anfänger beurteilen kann ein Formatierung Problem. Habe selber eine Rule geschrieben und die Variante „STR_help_d“ und „STR_sum“ ausgegeben. Die funktioniert aber geben verschiedene Formate (visuell) aus. Deren Berechnung gibt falsche Ergebnis aus.
z.B:
„STR_help_d“ = 795884,20
„STR_sum“ = 799028,80 Wh
„STR_sum“ – „STR_help_d“ = 11320480,00
Ah ja, und habe noch eine Java Fehler in der Logdatei:
Rule ‚Strom_aktualisiert‘: Could not cast NULL to java.lang.Number; line 48, column 21, length 26
Bezieht sich auf die Zeile:
helper_m = (STR_help_m.state as Number)
Wahrscheinlich, weil immer noch nicht initialisiert ist, oder?
Vielen Dank und Grüße,
Pampulea
Hm ja, der Monatswert muss auch initialisert werden. Entweder manuell machen oder die Regel „Strom_monatl“ einmal triggern. Sorry hab gerade wenig Zeit…