Zitat von Shai
Beitrag anzeigen
Ankündigung
Einklappen
Keine Ankündigung bisher.
eHZ Visu Beispiel mit neuem Widget Stacked Column Bar Chart
Einklappen
X
-
Ja, genau. Hab dem Udo auch gesagt, dass ich 4m USB Kabel bräuchte und hat das auch so umgesetzt. Super Service von ihm.
-
Die Idee mit dem Volkszähler hatte ich gar nicht auf dem Schirm. Ich hab bei mir im Zählerschrank sowieso nen kleinen Atom PC mit Ubuntu laufen der mein Smarthome hostet - und für ein paar Euro könnte man den Versuch ja durchaus wagen.Zitat von hhhc Beitrag anzeigenIch habe 2 Landis + Gyr E350 vom Energieversorger gestellt bekommen.
Daran habe ich je einen IR Schreib-Lese-Kopf (volkszaehler.org - wiki - IR-Schreib-Lesekopf, habe den Lötservice von Udo in Anspruch genommen) per USB an einen Rasperry-PI mit Standard-OS angebracht. Das Auslesen mache ich dann, indem ich per Cronjob jede Minute ein PHP Script ausführe (siehe anhang read.php.zip)
Die entsprechenden Items in smarthome.py müssen über das Network plugin schreibbar sein.
Da ich den Pi eh noch rumliegen hatte, war das für mich die kostengünstigste Lösung und es tut einwandfrei.
Code:type = num cache = on sqlite = yes [B]nw = yes[/B]
Ich vermute mal Du verwendest die USB-Version?
Danke & Grüße,
Lars
Einen Kommentar schreiben:
-
Ja hatte ich heute morgen gleich versucht, ändert aber nichts am Fehlerbild.
Frage ich einen anderen Plot an so erhalte ich keine Meldung im Log, lediglich 192.168.2.29:49267 sent '{"cmd":"series","item":"eg.wohnzimmer.std_tv.curr ent","series":"avg","start":"12h"}'.
Sag mal sind Deine Verbräuche und Kosten von "gestern" stabil? Bei mir hatten sich die auch ständig geändert, hab das jetzt gefixed.
- Likes 1
Einen Kommentar schreiben:
-
Meiner Meinung nach hat er das durch den Unterstrich getan, oder?Zitat von hhhc Beitrag anzeigenHast Du mal probiert, die items nicht mit einer Zahl anfangen zu lassen?
Habe das Widget auch mal versucht einzubauen. Jedoch als separates Widget abgespeichert und mit Temp-Werten, was ja egal sein sollte.
Bekomme auch die "gleiche" Fehlermeldung wie JuMi2006 (s.Screen).
Also tippe ich auch auf einen "Fehler" der anderswo zu suchen ist.
Code:{% import "widget_plot_stacked.html" as showme %} {{ showme.stacked('p20', ['KesselHZ', 'VorlaufHZ', 'RuecklaufHZ'], 'max', '48h', '', '', '', ['Kesseltemp.', 'Vorlauftemp.', 'Rücklauftemp'], 'false', '', ['column', 'column']) }}Code:[VorlaufHZ] type = num visu_acl = rw sqlite = yes knx_dpt = 9 knx_cache = 4/0/5 [RuecklaufHZ] type = num visu_acl = rw sqlite = yes knx_dpt = 9 knx_cache = 4/0/6 [KesselHZ] type = num visu_acl = rw sqlite = yes knx_dpt = 9 knx_cache = 4/0/8Angehängte Dateien
Einen Kommentar schreiben:
-
Das Widget wandelt Deine GAD automatisch um in zaehler.haushalt.verbrauch.60min.max.48h.now.100. Das sieht für mich erstmal auch korrekt aus. Bei mir ist das bspw ehz.haus.verbrauch.gestern.avg.2w.now.100.Zitat von JuMi2006 Beitrag anzeigenIch hab jedoch ein Problem mit dem Plot:
Code:2015-01-10 14:52:25,277 WARNING Main Client 192.168.2.29:61270 requested invalid item: zaehler.haushalt.verbrauch.60min.max.48h.now.100 -- __init__.py:json_parse:298 2015-01-10 14:52:25,280 WARNING Main Client 192.168.2.29:61270 requested invalid item: zaehler.wp.verbrauch.60min.max.48h.now.100 -- __init__.py:json_parse:298
Hast Du mal probiert, die items nicht mit einer Zahl anfangen zu lassen? Siehe https://knx-user-forum.de/smarthome-...item-name.html
Einen Kommentar schreiben:
-
Ich habe 2 Landis + Gyr E350 vom Energieversorger gestellt bekommen.Zitat von chrisi Beitrag anzeigenWelche eHZ verwendet ihr und wie greift ihr die ab?Ich schätze mal das funktioniert nicht mit den Zählern vom Energieversorger?
Verwendet ihr zum Abgriff das S0 Interface? Gibt es da schon was fertiges? Was benötige ich dafür?
Daran habe ich je einen IR Schreib-Lese-Kopf (volkszaehler.org - wiki - IR-Schreib-Lesekopf, habe den Lötservice von Udo in Anspruch genommen) per USB an einen Rasperry-PI mit Standard-OS angebracht. Das Auslesen mache ich dann, indem ich per Cronjob jede Minute ein PHP Script ausführe (siehe anhang read.php.zip)
Die entsprechenden Items in smarthome.py müssen über das Network plugin schreibbar sein.
Da ich den Pi eh noch rumliegen hatte, war das für mich die kostengünstigste Lösung und es tut einwandfrei.
Code:type = num cache = on sqlite = yes [B]nw = yes[/B]Angehängte Dateien
Einen Kommentar schreiben:
-
Welche eHZ verwendet ihr und wie greift ihr die ab?
Ich schätze mal das funktioniert nicht mit den Zählern vom Energieversorger?
Verwendet ihr zum Abgriff das S0 Interface? Gibt es da schon was fertiges? Was benötige ich dafür?
Einen Kommentar schreiben:
-
Ich hatte noch ein Fehler im Namespace von sh.py vermutet, ist es aber leider auch nicht.
Die zaehler.conf wird jetzt langPHP-Code:<div class="block full-width">
<div class="set-2" data-role="collapsible-set" data-theme="c" data-content-theme="a" data-mini="true">
<div data-role="collapsible" data-collapsed="false">
<h3>Stromverbrauch pro Stunde 2(kwh)</h3>
{{ plot.stacked('p22', ['zaehler.haushalt.verbrauch._60min', 'zaehler.wp.verbrauch._60min'], 'max', '48h', '', '', '', ['Haushalt', 'Wärmepumpe'], 'false', '', ['column', 'column']) }}
</div>
</div>
</div>

Danke für Deine Hilfe!Code:[zaehler] [[haushalt]] [[[stand]]] cache = yes type = num knx_dpt = 14 knx_listen = 6/1/0 visu = yes rrd = 1 rrd_type = 'COUNTER' rrd_step = 84600 [[[[sql]]]] cache = yes type = num knx_dpt = 14 knx_listen = 6/1/0 sqlite = yes [[[[_60min]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.haushalt.stand eval = sh.zaehler.haushalt.stand.sql.db('min','60i') [[[[_24h]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.haushalt.stand eval = sh.zaehler.haushalt.stand.sql.db('min','24h') [[[[_7d]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.haushalt.stand eval = sh.zaehler.haushalt.stand.sql.db('min','7d') [[[[stunde]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.haushalt.stand eval = sh.zaehler.haushalt.stand.sql.db('min',sh.minute.since.hour.dbstr()) [[[[tag]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.haushalt.stand eval = sh.zaehler.haushalt.stand.sql.db('min',sh.minute.since.midnight.dbstr()) [[[[woche]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.haushalt.stand eval = sh.zaehler.haushalt.stand.sql.db('min',sh.hour.since.week.dbstr()) [[[verbrauch]]] [[[[_60min]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.haushalt.stand eval = sh.zaehler.haushalt.stand.sql() - sh.zaehler.haushalt.stand.sql.db('min','60i') [[[[_24h]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.haushalt.stand eval = sh.zaehler.haushalt.stand.sql() - sh.zaehler.haushalt.stand.sql.db('min','24h') [[[[_7d]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.haushalt.stand eval = sh.zaehler.haushalt.stand.sql() - sh.zaehler.haushalt.stand.sql.db('min','7d') [[[[stunde]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.haushalt.stand eval = sh.zaehler.haushalt.stand.sql() - sh.zaehler.haushalt.stand.sql.db('min',sh.minute.since.hour.dbstr()) [[[[tag]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.haushalt.stand eval = sh.zaehler.haushalt.stand.sql() - sh.zaehler.haushalt.stand.sql.db('min',sh.minute.since.midnight.dbstr()) [[[[gestern]]]] type = num cache = on sqlite = yes eval_trigger = zaehler.haushalt.stand eval = sh.zaehler.haushalt.stand.sql() - sh.zaehler.haushalt.stand.sql.db('max', '1d', '1d') [[[[[weekly_avg]]]]] type = num cache = on sqlite = yes eval = round(sh.zaehler.haushalt.verbrauch.gestern.db('avg', '1w'), 2) eval_trigger = zaehler.kosten.gestern [[[[woche]]]] type = num sqlite = yes eval_trigger = zaehler.haushalt.stand eval = sh.zaehler.haushalt.stand.sql() - sh.zaehler.haushalt.stand.sql.db('min',sh.hour.since.week.dbstr()) [[[[monat]]]] type = num cache = on sqlite = yes eval_trigger = zaehler.wp.stand eval = sh.zaehler.haushalt.stand() - sh.zaehler.haushalt.stand.sql.db('max', '1m', '1m') [[[kosten]]] [[[[heute]]]] type = num cache = on sqlite = yes eval = round((sh.zaehler.haushalt.verbrauch.tag())*0.2649 + (78.54/365),2) eval_trigger = zaehler.haushalt.verbrauch.tag [[[[gestern]]]] type = num cache = on sqlite = yes eval = round((sh.zaehler.haushalt.verbrauch.gestern())*0.2649 + (78.54/365),2) eval_trigger = zaehler.haushalt.verbrauch.gestern [[[[[weekly_avg]]]]] type = num cache = on sqlite = yes eval = round(sh.zaehler.haushalt.kosten.gestern.db('avg', '1w'), 2) eval_trigger = zaehler.haushalt.kosten.gestern [[[[monat]]]] type = num cache = on sqlite = yes eval = round((sh.zaehler.haushalt.verbrauch.monat())*0.2649 + (78.54/365),2) eval_trigger = zaehler.haushalt.verbrauch.monat [[[leistung]]] cache = yes type = num knx_dpt = 9 knx_listen = 6/1/1 visu = yes rrd = 1 rrd_type = GAUGE [[[strom_l1]]] type = num knx_dpt = 9 knx_listen = 6/1/10 visu = yes rrd = 1 [[[strom_l2]]] type = num knx_dpt = 9 knx_listen = 6/1/20 visu = yes [[[strom_l3]]] type = num knx_dpt = 9 knx_listen = 6/1/30 visu = yes [[[spannung_l1]]] type = num knx_dpt = 9 knx_listen = 6/1/11 visu = yes [[[spannung_l2]]] type = num knx_dpt = 9 knx_listen = 6/1/21 visu = yes [[[spannung_l3]]] type = num knx_dpt = 9 knx_listen = 6/1/31 visu = yes #NV [[wp]] [[[stand]]] cache = yes type = num knx_dpt = 14 knx_listen = 6/2/0 visu = yes rrd = 1 rrd_type = 'COUNTER' rrd_step = 84600 [[[[sql]]]] cache = yes type = num knx_dpt = 14 knx_listen = 6/2/0 sqlite = yes [[[[stunde]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.wp.stand eval = sh.zaehler.wp.stand.sql.db('min',sh.minute.since.hour.dbstr()) [[[[tag]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.wp.stand eval = sh.zaehler.wp.stand.sql.db('min',sh.minute.since.midnight.dbstr()) [[[[woche]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.wp.stand eval = sh.zaehler.wp.stand.sql.db('min',sh.hour.since.week.dbstr()) [[[verbrauch]]] [[[[_60min]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.wp.stand eval = sh.zaehler.wp.stand.sql() - sh.zaehler.wp.stand.sql.db('min','60i') [[[[_24h]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.wp.stand eval = sh.zaehler.wp.stand.sql() - sh.zaehler.wp.stand.sql.db('min','24h') [[[[_7d]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.wp.stand eval = sh.zaehler.wp.stand.sql() - sh.zaehler.wp.stand.sql.db('min','7d') [[[[stunde]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.wp.stand eval = sh.zaehler.wp.stand.sql() - sh.zaehler.wp.stand.sql.db('min',sh.minute.since.hour.dbstr()) [[[[tag]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.wp.stand eval = sh.zaehler.wp.stand.sql() - sh.zaehler.wp.stand.sql.db('min',sh.minute.since.midnight.dbstr()) [[[[gestern]]]] type = num cache = on sqlite = yes eval_trigger = zaehler.wp.stand eval = sh.zaehler.wp.stand.sql() - sh.zaehler.wp.stand.sql.db('max', '1d', '1d') [[[[[weekly_avg]]]]] type = num cache = on sqlite = yes eval = round(sh.zaehler.wp.verbrauch.gestern.db('avg', '1w'), 2) eval_trigger = zaehler.kosten.gestern [[[[woche]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.wp.stand eval = sh.zaehler.wp.stand.sql() - sh.zaehler.wp.stand.sql.db('min',sh.hour.since.week.dbstr()) [[[[monat]]]] type = num cache = on sqlite = yes eval_trigger = zaehler.wp.stand eval = sh.zaehler.wp.stand() - sh.zaehler.wp.stand.sql.db('max', '1m', '1m') [[[kosten]]] [[[[heute]]]] type = num cache = on sqlite = yes eval = round((sh.zaehler.wp.verbrauch.tag())*0.2242 + (51.12/365),2) eval_trigger = zaehler.wp.verbrauch.tag [[[[gestern]]]] type = num cache = on sqlite = yes eval = round((sh.zaehler.wp.verbrauch.gestern())*0.2242 + (51.12/365),2) eval_trigger = zaehler.wp.verbrauch.gestern [[[[[weekly_avg]]]]] type = num cache = on sqlite = yes eval = round(sh.zaehler.wp.kosten.gestern.db('avg', '1w'), 2) eval_trigger = zaehler.wp.kosten.gestern [[[[monat]]]] type = num cache = on sqlite = yes eval = round((sh.zaehler.wp.verbrauch.monat())*0.2242 + (51.12/365),2) eval_trigger = zaehler.wp.verbrauch.monat [[[leistung]]] type = num cache = on sqlite = yes eval = round((sh.zaehler.wp.stand() - sh.zaehler.wp.stand.sql.db('min', '4i')) * 15 , 2) eval_trigger = zaehler.wp.stand [[[cop]]] [[[[_24h]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.wp.stand eval = (sh.ebus.energie_summe.ertrag._24h() / sh.zaehler.wp.verbrauch._24h()) + 1 [[[[_7d]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.wp.stand eval = (sh.ebus.energie_summe.ertrag._7d() / sh.zaehler.wp.verbrauch._7d()) + 1 [[[[tag]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.wp.stand eval = (sh.ebus.energie_summe.ertrag.tag() / sh.zaehler.wp.verbrauch.tag()) + 1 [[[[woche]]]] type = num cache = yes sqlite = yes eval_trigger = zaehler.wp.stand eval = (sh.ebus.energie_summe.ertrag.woche() / sh.zaehler.wp.verbrauch.woche()) + 1 [[kosten]] [[[gestern]]] type = num cache = on sqlite = yes eval = round(sh.zaehler.haushalt.kosten.gestern() + sh.zaehler.wp.kosten.gestern(), 2) eval_trigger = zaehler.haushalt.kosten.gestern | zaehler.wp.kosten.gestern [[[[weekly_avg]]]] type = num cache = on sqlite = yes eval = round(sh.zaehler.kosten.gestern.db('avg', '1w'), 2) eval_trigger = zaehler.kosten.gestern
Einen Kommentar schreiben:
-
Danke!Zitat von Shai Beitrag anzeigen
wirklich schick geworden.
ich hatte noch einen ungenutzten Pi hier rumliegen, den ich mittels 2 Leseköpfen von Volkszähler.org angebunden habe.Zitat von Shai Beitrag anzeigen
Welche Schnittstelle nutzt Ihr dafür und vor allem wie habt Ihr die Parametriert?
ein kurzes Script fragt den Zähler jede Minute ab und pusht die Werte an sh.py mittels network plugin.
Einen Kommentar schreiben:
-
das max.48h wird ja automatisch angehängt. Teilst Du bitte mal Deine conf?Zitat von JuMi2006 Beitrag anzeigenSchön dass auch was von mir dabei ist
.
Ich hab jedoch ein Problem mit dem Plot:
2015-01-10 14:52:25,277 WARNING Main Client 192.168.2.29:61270 requested invalid item: zaehler.haushalt.verbrauch.60min.max.48h.now.100 -- __init__.py:json_parse:298
2015-01-10 14:52:25,280 WARNING Main Client 192.168.2.29:61270 requested invalid item: zaehler.wp.verbrauch.60min.max.48h.now.100 -- __init__.py:json_parse:298
Die items gibt es nur ohne .max.48h also denke ich läuft irgendwas im Widget schief? Das ist eigentlich Dein Beispiel p2 nur dass die sh.py items geändert sind.
Einen Kommentar schreiben:
-
Hey,
wirklich schick geworden.
Ich bin auch noch in der Planung unseren eHZ einzubinden.
Welche Schnittstelle nutzt Ihr dafür und vor allem wie habt Ihr die Parametriert?
Hab die KNX Schnittstelle von Lingg & Janke gefunden und mir das Applikationsprogramm mal in die ETS geholt, ich muss aber sagen dass ich etwas überfordert war von den 27 möglichen Zählerarten, was mich dann erst mal abgeschreckt hat mir die Schnittstelle auch zu kaufen ;-)
Grüße,
Lars
Einen Kommentar schreiben:
-
Schön dass auch was von mir dabei ist
.
Ich hab jedoch ein Problem mit dem Plot:
2015-01-10 14:52:25,277 WARNING Main Client 192.168.2.29:61270 requested invalid item: zaehler.haushalt.verbrauch.60min.max.48h.now.100 -- __init__.py:json_parse:298
2015-01-10 14:52:25,280 WARNING Main Client 192.168.2.29:61270 requested invalid item: zaehler.wp.verbrauch.60min.max.48h.now.100 -- __init__.py:json_parse:298
Das ganze kommt aus folgendem Code in der Visu:Die items gibt es nur ohne .max.48h also denke ich läuft irgendwas im Widget schief? Das ist eigentlich Dein Beispiel p2 nur dass die sh.py items geändert sind.Code:<div class="block full-width"> <div class="set-2" data-role="collapsible-set" data-theme="c" data-content-theme="a" data-mini="true"> <div data-role="collapsible" data-collapsed="false"> <h3>Stromverbrauch pro Stunde 2(kwh)</h3> {{ plot.stacked('p2', ['zaehler.haushalt.verbrauch.60min', 'zaehler.wp.verbrauch.60min'], 'max', '48h', '', '', '', ['Haushalt', 'Wärmepumpe'], 'false', '', ['column', 'column']) }} </div> </div> </div>
Dank und Gruß
Einen Kommentar schreiben:
-
Ich glaube der Tag sollte nicht 0 sein, sondern 1.Zitat von hhhc Beitrag anzeigenIn der config ist noch ein Fehler bei der monatlichen Berechnung. Ich erhalte
Error parsing crontab: 0 0 0 *
Wo steckt der Fehler?
Also jeden 1. Tag im Monat sollte so aussehen: 0 0 1 *
Einen Kommentar schreiben:
-
In der config ist noch ein Fehler bei der monatlichen Berechnung. Ich erhalte
Error parsing crontab: 0 0 0 *
Wo steckt der Fehler?
Einen Kommentar schreiben:
-
Also,
das ganze ist aus mehreren Ideen hier aus dem Forum zusammenkopiert.
1) Ich habe die Zeit Logik von hier eingebaut
https://knx-user-forum.de/smarthome-...er-sqlite.html
2) ehz.conf
3) ehz.htmlCode:[ehz] [[haus]] type = num cache = on sqlite = yes nw = yes [[[leistung_aktuell]]] type = num cache = on nw = yes [[[verbrauch]]] [[[[aktuell]]]] type = num cache = on eval = sh.ehz.haus() - sh.ehz.haus.db('max', '1d', sh.minute.since.midnight.dbstr()) eval_trigger = ehz.haus [[[[gestern]]]] type = num cache = on sqlite = yes crontab = 0 0 * * = 1 eval = sh.ehz.haus() - sh.ehz.haus.db('max', '1d', '1d') [[[[[weekly_avg]]]]] type = num cache = on sqlite = yes eval = round(sh.ehz.haus.verbrauch.gestern.db('avg', '1w'), 2) eval_trigger = ehz.kosten.gestern [[[[stuendlich]]]] type = num cache = on sqlite = yes crontab = 0 * * * = 1 eval = sh.ehz.haus() - sh.ehz.haus.db('max', '1h','1h') [[[[monat]]]] type = num cache = on sqlite = yes crontab = 0 0 0 * = 1 eval = sh.ehz.haus() - sh.ehz.haus.db('max', '1m', '1m') [[[kosten]]] [[[[heute]]]] type = num cache = on sqlite = yes eval = round((sh.ehz.haus.verbrauch.aktuell())*0.2549 + (54.86/365),2) eval_trigger = ehz.haus.verbrauch.aktuell [[[[gestern]]]] type = num cache = on sqlite = yes eval = round((sh.ehz.haus.verbrauch.gestern())*0.2549 + (54.86/365),2) eval_trigger = ehz.haus.verbrauch.gestern [[[[[weekly_avg]]]]] type = num cache = on sqlite = yes eval = round(sh.ehz.haus.kosten.gestern.db('avg', '1w'), 2) eval_trigger = ehz.haus.kosten.gestern [[[[monat]]]] type = num cache = on sqlite = yes eval = round((sh.ehz.haus.verbrauch.monat())*0.2549 + (54.86/365),2) eval_trigger = ehz.haus.verbrauch.monat [[wp]] [[[tag]]] type = num cache = on sqlite = yes nw = yes [[[[verbrauch]]]] [[[[[aktuell]]]]] type = num cache = on eval = sh.ehz.wp.tag() - sh.ehz.wp.tag.db('max', '1d', sh.minute.since.midnight.dbstr()) eval_trigger = ehz.wp.tag [[[[[gestern]]]]] type = num cache = on sqlite = yes crontab = 0 0 * * = 1 eval = sh.ehz.wp.tag() - sh.ehz.wp.tag.db('max', '1d', '1d') [[[[[monat]]]]] type = num cache = on sqlite = yes crontab = 0 0 0 * = 1 eval = sh.ehz.wp.tag() - sh.ehz.wp.tag.db('max', '1m', '1m') [[[[kosten]]]] [[[[[heute]]]]] type = num cache = on eval = round((sh.ehz.wp.tag.verbrauch.aktuell()*0.2279) + (55.37/2/365),2) eval_trigger = ehz.wp.tag.verbrauch.aktuell [[[[[gestern]]]]] type = num cache = on sqlite = yes eval = round((sh.ehz.wp.tag.verbrauch.gestern()*0.2279) + (55.37/2/365),2) eval_trigger = ehz.wp.tag.verbrauch.gestern [[[[[monat]]]]] type = num cache = on sqlite = yes eval = round((sh.ehz.wp.tag.verbrauch.monat()*0.2279) + (55.37/2/365),2) eval_trigger = ehz.wp.tag.verbrauch.monat [[[nacht]]] type = num cache = on sqlite = yes nw = yes [[[[verbrauch]]]] [[[[[aktuell]]]]] type = num cache = on eval = sh.ehz.wp.nacht() - sh.ehz.wp.nacht.db('max', '1d', sh.minute.since.midnight.dbstr()) eval_trigger = ehz.wp.nacht [[[[[gestern]]]]] type = num cache = on sqlite = yes crontab = 0 0 * * = 1 eval = sh.ehz.wp.nacht() - sh.ehz.wp.nacht.db('max', '1d', '1d') [[[[[monat]]]]] type = num cache = on sqlite = yes crontab = 0 0 0 * = 1 eval = sh.ehz.wp.nacht() - sh.ehz.wp.nacht.db('max', '1m', '1m') [[[[kosten]]]] [[[[[heute]]]]] type = num cache = on eval = round((sh.ehz.wp.nacht.verbrauch.aktuell()*0.1942) + (55.37/2/365),2) eval_trigger = ehz.wp.nacht.verbrauch.aktuell [[[[[gestern]]]]] type = num cache = on sqlite = yes eval = round((sh.ehz.wp.nacht.verbrauch.gestern()*0.1942) + (55.37/2/365),2) eval_trigger = ehz.wp.nacht.verbrauch.gestern [[[[[monat]]]]] type = num cache = on sqlite = yes eval = round((sh.ehz.wp.nacht.verbrauch.monat()*0.2279) + (55.37/2/365),2) eval_trigger = ehz.wp.nacht.verbrauch.monat [[[gesamt]]] type = num cache = on sqlite = yes eval = sh.ehz.wp.tag() + sh.ehz.wp.nacht() eval_trigger = ehz.wp.tag | ehz.wp.nacht [[[[leistung_aktuell]]]] type = num cache = on nw = yes [[[[verbrauch]]]] [[[[[aktuell]]]]] type = num cache = on eval = sh.ehz.wp.gesamt() - sh.ehz.wp.gesamt.db('max', '1d', sh.minute.since.midnight.dbstr()) eval_trigger = ehz.wp.gesamt [[[[[gestern]]]]] type = num cache = on sqlite = yes eval = sh.ehz.wp.tag.verbrauch.gestern() + sh.ehz.wp.nacht.verbrauch.gestern() eval_trigger = ehz.wp.tag.verbrauch.gestern | ehz.wp.nacht.verbrauch.gestern [[[[[stuendlich]]]]] type = num cache = on sqlite = yes crontab = 0 * * * = 1 eval = sh.ehz.wp.gesamt() - sh.ehz.wp.gesamt.db('max', '1h', '1h') [[[[kosten]]]] [[[[[heute]]]]] type = num cache = on eval = sh.ehz.wp.tag.kosten.heute() + sh.ehz.wp.nacht.kosten.heute() eval_trigger = ehz.wp.tag.kosten.heute | ehz.wp.nacht.kosten.heute [[[[[gestern]]]]] type = num cache = on sqlite = yes eval = sh.ehz.wp.tag.kosten.gestern() + sh.ehz.wp.nacht.kosten.gestern() eval_trigger = ehz.wp.tag.kosten.gestern | sh.ehz.wp.nacht.kosten.gestern [[[jahresarbeitszahl]]] type = num cache = on sqlite = yes eval = round(sh.Waermepumpe.WMZ_Total.db('max', '1y') / sh.ehz.wp.gesamt.db('max', '1y'), 1) eval_trigger = ehz.wp.gesamt | Waermepumpe.WMZ_Total [[kosten]] [[[gestern]]] type = num cache = on sqlite = yes eval = round(sh.ehz.haus.kosten.gestern() + sh.ehz.wp.gesamt.kosten.gestern(), 2) eval_trigger = ehz.haus.kosten.gestern | ehz.wp.gesamt.kosten.gestern [[[[weekly_avg]]]] type = num cache = on sqlite = yes eval = round(sh.ehz.kosten.gestern.db('avg', '1w'), 2) eval_trigger = ehz.kosten.gestern
4) Neues Widget "stacked", folgendes habe ich in smartvisu/widgets/widget.js hinzugefügtHTML-Code:{% extends "base.html" %} {% block sidebar %} {% include "/navigation_rooms.html" %} {% endblock %} {% block content %} <h1><img class="icon" src='{{ icon0 }}measure_power_meter.png'/>Energiezähler</h1> <div class="block"> <div class="ui-bar-c ui-li-divider ui-corner-top">Haushalt </div> <div class="ui-fixed ui-body-a ui-corner-bottom" style="min-height: 50px"> <table height="90%" width="80%" align="center"> <tr> <td colspan="2" align="left"> Aktuelle Leistung: <center> <font size="104"> {{ basic.float('akt_leistung_haus', 'ehz.haus.leistung_aktuell', 'kwh') }} </font> </center> </td> </tr> <tr> <td width="55%" align="left"> Heutiger Verbrauch </td> <td width="45%" align="right"> {{ basic.float('verbrauch_heute_haus', 'ehz.haus.verbrauch.aktuell', 'kwh') }} </td> </tr> <tr> <td width="55%" align="left"> Heutige Kosten </td> <td width="45%" align="right"> {{ basic.float('kosten_heute_haus', 'ehz.haus.kosten.heute', '€') }} </td> </tr> </table> </div> </div> <div class="block"> <div class="ui-bar-c ui-li-divider ui-corner-top">Wärmepumpe </div> <div class="ui-fixed ui-body-a ui-corner-bottom" style="min-height: 50px"> <table height="90%" width="80%" align="center"> <tr> <td colspan="2" align="left"> Aktuelle Leistung: <center> <font size="104"> {{ basic.float('akt_leistung_wp', 'ehz.wp.gesamt.leistung_aktuell', 'kwh') }} </font> </center> </td> </tr> <tr> <td width="55%" align="left"> Heutiger Verbrauch </td> <td width="45%" align="right"> {{ basic.float('verbrauch_heute_wp', 'ehz.wp.gesamt.verbrauch.aktuell', 'kwh') }} </td> </tr> <tr> <td width="55%" align="left"> Heutige Kosten </td> <td width="45%" align="right"> {{ basic.float('kosten_heute_wp', 'ehz.wp.gesamt.kosten.heute', '€') }} </td> </tr> </table> </div> </div> <div class="block"> <div class="ui-bar-c ui-li-divider ui-corner-top">Verbräuche (gestern)</div> <div class="ui-fixed ui-body-a ui-corner-bottom" style="min-height: 50px"> <table height="90%" width="80%" align="center"> <tr> <td width="55%" align="left"> Haushalt </td> <td width="45%" align="right"> {{ basic.float('ehz.verbrauch_haus_gestern', 'ehz.haus.verbrauch.gestern', 'kwh') }} / {{ basic.float('ehz.kosten_haus_gestern', 'ehz.haus.kosten.gestern', '€') }} </td> </tr> <tr> <td width="55%" align="left"> WP Tag </td> <td width="45%" align="right"> {{ basic.float('ehz.verbrauch_wp_nacht_gestern', 'ehz.wp.tag.verbrauch.gestern', 'kwh') }} / {{ basic.float('ehz.wp.tag.kosten.gestern', 'ehz.wp.tag.kosten.gestern', '€') }} </td> </tr> <tr> <td width="55%" align="left"> WP Nacht </td> <td width="45%" align="right"> {{ basic.float('ehz.verbrauch_wp_tag_gestern', 'ehz.wp.nacht.verbrauch.gestern', 'kwh') }} / {{ basic.float('ehz.wp.nacht.kosten.gestern', 'ehz.wp.nacht.kosten.gestern', '€') }} </td> </tr> <tr> <td width="55%" align="left"> Wärmepumpe </td> <td width="45%" align="right"> {{ basic.float('ehz.verbrauch_wp_gestern', 'ehz.wp.gesamt.verbrauch.gestern', 'kwh') }} / {{ basic.float('ehz.wp.gesamt.verbrauch.gestern', 'ehz.wp.gesamt.kosten.gestern', '€') }} </td> </tr> </table> </div> </div> <div class="block"> <div class="ui-bar-c ui-li-divider ui-corner-top">Zählerstände</div> <div class="ui-fixed ui-body-a ui-corner-bottom" style="min-height: 50px"> <table height="90%" width="80%" align="center"> <tr> <td width="55%" align="left"> Haushalt </td> <td width="45%" align="right"> {{ basic.float('ehz.haus', 'ehz.haus', 'kwh') }} </td> </tr> <tr> <td width="55%" align="left"> WP Tag </td> <td width="45%" align="right"> {{ basic.float('ehz.wp_tag', 'ehz.wp.tag', 'kwh') }} </td> </tr> <tr> <td width="55%" align="left"> WP Nacht </td> <td width="45%" align="right"> {{ basic.float('ehz.wp_nacht', 'ehz.wp.nacht', 'kwh') }} </td> </tr> <tr> <td width="55%" align="left"> Wärmepumpe </td> <td width="45%" align="right"> {{ basic.float('ehz.wp', 'ehz.wp.gesamt', 'kwh') }} </td> </tr> </table> </div> </div> <div class="block full-width"> <div class="set-2" data-role="collapsible-set" data-theme="c" data-content-theme="a" data-mini="true"> <div data-role="collapsible" data-collapsed="false"> <h3>Stromverbrauch pro Tag (kwh)</h3> {{ plot.stacked('p1verbrauchprotag', ['ehz.haus.verbrauch.gestern', 'ehz.wp.tag.verbrauch.gestern', 'ehz.wp.nacht.verbrauch.gestern'], 'avg', '2w', '', '', '', ['Haushalt', 'Wärmepumpe Tag', 'Wärmepumpe Nacht'], 'true', '', ['column', 'column', 'column'], '', true) }} </div> </div> </div> <div class="block full-width"> <div class="set-2" data-role="collapsible-set" data-theme="c" data-content-theme="a" data-mini="true"> <div data-role="collapsible" data-collapsed="false"> <h3>Stromverbrauch pro Stunde (kwh)</h3> {{ plot.stacked('p2', ['ehz.haus.verbrauch.stuendlich', 'ehz.wp.gesamt.verbrauch.stuendlich'], 'max', '48h', '', '', '', ['Haushalt', 'Wärmepumpe'], 'false', '', ['column', 'column']) }} </div> </div> </div> <div class="block full-width"> <div class="set-2" data-role="collapsible-set" data-theme="c" data-content-theme="a" data-mini="true"> <div data-role="collapsible" data-collapsed="false"> <h3>Kosten pro Tag (EUR)</h3> {{ plot.stacked('p3', ['ehz.haus.kosten.gestern', 'ehz.wp.tag.kosten.gestern', 'ehz.wp.nacht.kosten.gestern', 'ehz.kosten.gestern.weekly_avg'], 'max', '2w', '', '', '', ['Haushalt', 'Wärmepumpe Tag', 'Wärmepumpe Nacht', 'Wochendurchschnitt'], 'true', '', ['column', 'column', 'column', 'line'], '', true) }} </div> </div> </div> {% endblock %}
Die Werte, die ich von smarthome.py erhalte, werden am Ende einer Period ermittelt (Stunde, Tag). Im JS korrigiere ich nun 3 "Probleme"Code:// ----- plot.stacked ---------------------------------------------------------- $(document).delegate('div[data-widget="plot.stacked"]', { 'update': function (event, response) { // response is: [ [ [t1, y1], [t2, y2] ... ], [ [t1, y1], [t2, y2] ... ], ... ] var label = $(this).attr('data-label').explode(); var color = $(this).attr('data-color').explode(); var exposure = $(this).attr('data-exposure').explode(); var axis = $(this).attr('data-axis').explode(); var zoom = $(this).attr('data-zoom'); var showStacklabels = JSON.parse($(this).attr('data-stacklabels')); var correctdate = JSON.parse($(this).attr('data-correctdate')); var series = Array(); for (var i = 0; i < response.length; i++) { // 1) werte werden um Mitternacht für den Vortag generiert, Anzeige von Highcharts auf dem Folgetag, ABzug von 24h in millisekunden // 2) timestamp is in milliseconds, harmonize last 3 figures to 000 // sollte also hiermit auf 10sec "ungenau" werden => notwendig für gruppierung von highcharts // 3) remove last value as it is a during the day value var oneResponse = response[i]; // [[1420526954593,0],[1420554301019,6.21],[1420585202298,6.7],[1420671601499,7.4],[1420671601527,7.12],[1420747423682,7.12]] for (var k = 0; k < oneResponse.length; k++) { var timestamp = oneResponse[k][0]; // 1) if (correctdate) { timestamp = timestamp - 1000 * 60 * 60 * 24; } // 2) var newTimestamp = timestamp.toString().substring(0, 9).concat('0000'); oneResponse[k][0] = parseInt(newTimestamp); } oneResponse.pop(); // 3) response[i] = oneResponse; series[i] = { type: (exposure[i] != 'stair' ? exposure[i] : 'line'), step: (exposure[i] == 'stair' ? 'left' : false), name: label[i], data: response[i], color: (color[i] ? color[i] : null) } } // draw the plot $('#' + this.id).highcharts({ chart: { type: 'column' }, series: series, xAxis: { type: 'datetime', title: { text: axis[0] } }, yAxis: { min: $(this).attr('data-ymin'), max: $(this).attr('data-ymax'), title: { text: axis[1] }, stackLabels: { enabled: showStacklabels, style: { color: '#fff', 'font-size': '13px', 'line-height': '14px' } } }, plotOptions: { column: { stacking: 'normal', dataLabels: { enabled: false } } } }); }, 'point': function (event, response) { var count = $(this).attr('data-count'); if (count < 100) { count = 100; } for (var i = 0; i < response.length; i++) { if (response[i]) { var chart = $('#' + this.id).highcharts(); // more points? for (var j = 0; j < response[i].length; j++) { chart.series[i].addPoint(response[i][j], false, (chart.series[i].data.length >= count)); } chart.redraw(); } } } });
1) Werte werden um Mitternacht für den Vortag generiert, Anzeige von Highcharts auf dem Tag der Berrechnung (Folgetag), Abzug von 24h in millisekunden
2) Damit Highcharts die Werte stapeln kann (stacked) müssen die Timestamps die gleichen sein, da sh.py im millisekunden Bereich arbeitet, hamonisiere ich das einfach auf 10 Sekunden genau
3) Letzten Wert fallen lassen, da das die Vorperiod spiegelt (könnte man das mit tmax umgehen? Irgendwie verstehe ich tmax auch nicht so richtig...
Anschliessend bitte im Hauptverzeichnis "php make.php" ausführen.
5) neues Makro in smartvisu/widgets/plot.html
Natürlich sehr stark von plot.period angelehnt, aber "data-stacklabel" und "data-correctdate" hinzugefügt. Letzteres ist wichtig, da die oben angesprochene Korrektur 1 des Datums für die Stunden nicht benötigt werden.HTML-Code:/** * A simple widget for plotting stacked charts * * @param unique id for this widget * @param series of item/s. More item/s in array form: [ item1 , item2 ] * @param the mode: 'avg', 'sum', 'min', 'max' * @param the minimum time (x-axis): '1h', '2h'... (duration-format) * @param the maximum time (x-axis): '', '1h', '2h'... (duration-format, default: now) * @param the minimum y-axis (optional) * @param the maximum y-axis (optional) * @param label/s for each series (optional) * @param stacklabel if the aggregated values should be shown, true/false (optional, default true) * @param color/s for each series e. g. '#f00' for red (optional, default: sutiable for design) * @param type/s for each series (exposure): 'line', 'stair', 'spline', 'area', 'areaspline', 'column' (optional, default 'line') * @param count number of data points to load, default 100 * @param correctdate whether to delete last data point (if stats from previous * * @see misc/fundamentals#Array-Form * @see misc/fundamentals#Duration-Format */ {% macro stacked(id, gad, mode, tmin, tmax, ymin, ymax, label, stacklabels, color, exposure, count, correctdate) %} <div id="{{ uid(page, id) }}" data-widget="plot.stacked" data-item="{{ implode(gad, [mode|default('avg'), tmin|default('1h'), tmax|default('now'), count|default(100)]) }}" {% if ymin is not empty %} data-ymin="{{ ymin }}" {% endif %} {% if ymax is not empty %} data-ymax="{{ ymax }}" {% endif %} data-label="{{ implode(label) }}" data-stacklabels="{{ stacklabels|default(true) }}" data-correctdate="{{ correctdate|default('false') }}" data-color="{{ implode(color) }}" data-exposure="{{ implode(exposure) }}" data-axis="{{ implode(axes) }}" {% if count is not empty %} data-count="{{ count }}" {% endif %} class="plot"></div> {% endmacro %}
Einen Kommentar schreiben:


Einen Kommentar schreiben: