Ankündigung

Einklappen
Keine Ankündigung bisher.

eHZ Visu Beispiel mit neuem Widget Stacked Column Bar Chart

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • hhhc
    antwortet
    Zitat von Shai Beitrag anzeigen
    Ich vermute mal Du verwendest die USB-Version?
    Ja, genau. Hab dem Udo auch gesagt, dass ich 4m USB Kabel bräuchte und hat das auch so umgesetzt. Super Service von ihm.

    Einen Kommentar schreiben:


  • Shai
    antwortet
    Zitat von hhhc Beitrag anzeigen
    Ich 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]
    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.

    Ich vermute mal Du verwendest die USB-Version?

    Danke & Grüße,

    Lars

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    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.

    Einen Kommentar schreiben:


  • macflei
    antwortet
    Zitat von hhhc Beitrag anzeigen
    Hast Du mal probiert, die items nicht mit einer Zahl anfangen zu lassen?
    Meiner Meinung nach hat er das durch den Unterstrich getan, oder?
    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/8
    Angehängte Dateien

    Einen Kommentar schreiben:


  • hhhc
    antwortet
    Zitat von JuMi2006 Beitrag anzeigen
    Ich 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
    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.

    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:


  • hhhc
    antwortet
    Zitat von chrisi Beitrag anzeigen
    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?
    Ich 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]
    Angehängte Dateien

    Einen Kommentar schreiben:


  • chrisi
    antwortet
    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:


  • JuMi2006
    antwortet
    Ich hatte noch ein Fehler im Namespace von sh.py vermutet, ist es aber leider auch nicht.

    PHP-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
    Die zaehler.conf wird jetzt lang
    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
    Danke für Deine Hilfe!

    Einen Kommentar schreiben:


  • hhhc
    antwortet
    Zitat von Shai Beitrag anzeigen

    wirklich schick geworden.
    Danke!

    Zitat von Shai Beitrag anzeigen

    Welche Schnittstelle nutzt Ihr dafür und vor allem wie habt Ihr die Parametriert?
    ich hatte noch einen ungenutzten Pi hier rumliegen, den ich mittels 2 Leseköpfen von Volkszähler.org angebunden habe.
    ein kurzes Script fragt den Zähler jede Minute ab und pusht die Werte an sh.py mittels network plugin.

    Einen Kommentar schreiben:


  • hhhc
    antwortet
    Zitat von JuMi2006 Beitrag anzeigen
    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

    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.
    das max.48h wird ja automatisch angehängt. Teilst Du bitte mal Deine conf?

    Einen Kommentar schreiben:


  • Shai
    antwortet
    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:


  • JuMi2006
    antwortet
    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:
    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>
    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.

    Dank und Gruß

    Einen Kommentar schreiben:


  • Mike01
    antwortet
    Zitat von hhhc Beitrag anzeigen
    In der config ist noch ein Fehler bei der monatlichen Berechnung. Ich erhalte
    Error parsing crontab: 0 0 0 *

    Wo steckt der Fehler?
    Ich glaube der Tag sollte nicht 0 sein, sondern 1.
    Also jeden 1. Tag im Monat sollte so aussehen: 0 0 1 *

    Einen Kommentar schreiben:


  • hhhc
    antwortet
    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:


  • hhhc
    antwortet
    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
    Code:
    [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
    3) ehz.html
    HTML-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 %}
    4) Neues Widget "stacked", folgendes habe ich in smartvisu/widgets/widget.js hinzugefügt

    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();
    			}
    		}
    	}
    });
    Die Werte, die ich von smarthome.py erhalte, werden am Ende einer Period ermittelt (Stunde, Tag). Im JS korrigiere ich nun 3 "Probleme"
    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
    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 %}
    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.

    Einen Kommentar schreiben:

Lädt...
X