Ankündigung

Einklappen
Keine Ankündigung bisher.

Beispiele für Summenbildung für "heute", "gestern" etc. (z.B. Stromverbrauch)

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

    [Codebeispiel] Beispiele für Summenbildung für "heute", "gestern" etc. (z.B. Stromverbrauch)

    Hi Leute,

    so wie einige von euch stand ich auch vor der Aufgabe, die Impulse eines S0-Stromzählers auszuwerten und Statistiken und Diagramme heraus zu bekommen.

    Nachdem ich hier im Forum zwar einige Ansätze aber keine wirklichen Lösungen für die Berechnung von z.B. "Wieviel kWh wurden heute schon verbraucht?" gefunden hab, dachte ich mir, ich poste mal hier meine Lösung, vielleicht hilft sie dem einen oder anderen.

    Als erstes hab ich mir Items definiert, die mir die Minuten seit Mitternacht berechnen und bereit stellen (das zweite ist zum Komfort schon ein fertig formatierter String für .db() Abfragen, z.B. '30i' = 30 Minuten):

    Code:
    [zeit]
    	[[minutenseitmitternacht]]
    		type = num
    		enforce_updates = yes
    		crontab = init | * * * * = 1
    		eval = int(((sh.now() - sh.now().replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds()) // 60)
    		[[[dbstr]]]
    			type = str
    			cache = on
    			eval_trigger = zeit.minutenseitmitternacht
    			eval = str(sh.zeit.minutenseitmitternacht()) + 'i'
    Für meine Wärmepumpe, die an dem Stromzähler dran hängt, hab ich dann zwei weitere Items, wobei in das "Impuls" Item direkt die Impulse des S0-Zählers reinkommen und das "Gesamt" Item den Gesamt-kWh-Stand aufnimmt. Ein Watch auf das Impuls-Item ruft eine externe Logik auf, welche den kWh Stand erhöht:

    Code:
    sh.waermepumpe.verbrauch.gesamt(sh.waermepumpe.verbrauch.gesamt() + 0.01)
    Die aktuelle Leistung berechne ich näherungsweise (wie auch andere hier im Forum) über die Zeitabstände zwischen den Impulsen. Durch den autotimer Eintrag wird die Leistung auf 0 zurückgesetzt, wenn länger als 1 Minute kein Impuls mehr kommt:

    Code:
    		[[[aktuell]]]
    			knx_dpt = 14
    			type = num
    			sqlite = yes
    			eval = 0 if int(value) == 0 else max(36 / sh.waermepumpe.verbrauch.gesamt.prev_age(), 0)
    			eval_trigger = waermepumpe.verbrauch.gesamt
    			autotimer = 1m = 0 # Reset to zero if no impulse comes within a minute (< 0.6kW)
    			enforce_updates=yes
    			cache = on
    So, und hier jetzt noch die eigentlich interessanten Berechnungen der verbrauchten kWh heute, gestern und vorgestern. Mit ein paar Änderungen kann man sicher schnell auch "diese Woche", "letztes Monat" etc. machen.

    Code:
    		[[[heute]]]
    			knx_dpt = 14
    			type = num
    			sqlite = yes
    			cache = on
    			crontab = * * * * = 1
    			eval = sh.waermepumpe.verbrauch.gesamt() - sh.waermepumpe.verbrauch.gesamt.db('max', sh.zeit.minutenseitmitternacht.dbstr(), sh.zeit.minutenseitmitternacht.dbstr())
    			eval_trigger = waermepumpe.verbrauch.gesamt
    		[[[gestern]]]
    			knx_dpt = 14
    			type = num
    			sqlite = yes
    			cache = on
    			crontab = 0 0 * * = 1
    			eval = sh.waermepumpe.verbrauch.gesamt() - sh.waermepumpe.verbrauch.gesamt.db('max', '1d','1d')
    		[[[vorgestern]]]
    			knx_dpt = 14
    			type = num
    			sqlite = yes
    			cache = on
    			crontab = 0 0 * * = 1
    			eval = sh.waermepumpe.verbrauch.gesamt.db('max', '1d', '1d') - sh.waermepumpe.verbrauch.gesamt.db('max', '2d','2d')
    Hoffe, es hilft jemandem.

    LG Stefan

    #2
    Wenn ich die Doku korrekt verstanden habe, kann da noch was nicht stimmen. Zum Beispiel der Wert für vorgestern wird bei dir so berechnet:

    Code:
    eval = sh.waermepumpe.verbrauch.gesamt.db('max', '1d', '1d') - sh.waermepumpe.verbrauch.gesamt.db('max', '2d','2d')
    Laut Doku ist der erste Wert einen Tag in der Vergangenheit mit dem Intervall ein Tag. Also alle Werte von gestern. Davon ziehst du nun den Wert von vorgestern UND gestern ab. Eigentlich sollte da ja nun ein negativer Verbrauch raus kommen.

    Mal eine generelle Frage, da ich mit der db Abfrage noch nicht gearbeitet habe. Nimmt man das Beispiel aus der Doku:

    Code:
    sh.outside.temperature.db('avg', '2w', '1w')  # returns the average temperature of the week before last week
    liefert das nun den Wert von der vorletzten Woche von Montag bis Sonntag oder variiert das Ergebnis der Abfrage, je nach Wochentag an dem ich sie mache? Würde ich jetzt statt 'w' mittels 'd' nur einen Tag abfragen, bekomme ich dann den Wert von vorgestern von 0:00 Uhr bis 23:59 Uhr oder bekomme ich den Wert von 12:00 Uhr vor zwei Tagen bis 11:59 Uhr von gestern wenn ich die Abfrage heute um 12:00 Uhr mache?
    Mit freundlichen Grüßen
    Niko Will

    Logiken und Schnittstelle zu anderen Systemen: smarthome.py - Visualisierung: smartVISU
    - Gira TS3 - iPhone & iPad - Mobotix T24 - ekey - Denon 2313 - Russound C5 (RIO over TCP Plugin) -

    Kommentar


      #3
      Zitat von 2ndsky Beitrag anzeigen
      Zum Beispiel der Wert für vorgestern wird bei dir so berechnet:

      Code:
      eval = sh.waermepumpe.verbrauch.gesamt.db('max', '1d', '1d') - sh.waermepumpe.verbrauch.gesamt.db('max', '2d','2d')
      Laut Doku ist der erste Wert einen Tag in der Vergangenheit mit dem Intervall ein Tag. Also alle Werte von gestern. Davon ziehst du nun den Wert von vorgestern UND gestern ab. Eigentlich sollte da ja nun ein negativer Verbrauch raus kommen.
      Punkt 1: Nein, es handelt sich nicht um einen Intervall von 1 Tag sondern man gibt ein von und ein bis an. Der erste Term berechnet also den Maximalwert genau vor 24h (Intervall quasi 0), der zweite Term den Maximalwert vor 48h. Und nachdem ich das Item mittels Crontab genau immer jeden Tag 1x um 00:00 evaluiere, passt das dann.

      Zitat von 2ndsky
      liefert das nun den Wert von der vorletzten Woche von Montag bis Sonntag oder variiert das Ergebnis der Abfrage, je nach Wochentag an dem ich sie mache? Würde ich jetzt statt 'w' mittels 'd' nur einen Tag abfragen, bekomme ich dann den Wert von vorgestern von 0:00 Uhr bis 23:59 Uhr oder bekomme ich den Wert von 12:00 Uhr vor zwei Tagen bis 11:59 Uhr von gestern wenn ich die Abfrage heute um 12:00 Uhr mache?
      Genau das ist eben das Problem, dass man mit z.B. "1d" genau 24h zurück kommt und mit "1w" 1 Woche zurück kommt, aber nicht an die Datumsgrenze. Das hab ich nun mit den "minuten seit mitternacht" erledigt. Für Abfragen wie "kWh in der letzten Kalenderwoche" müsste man diese Idee weiter ausbauen.

      LG Stefan

      Kommentar


        #4
        Ah okay, dann habe ich das jetzt auch kapiert. Danke für die Erklärung!
        Mit freundlichen Grüßen
        Niko Will

        Logiken und Schnittstelle zu anderen Systemen: smarthome.py - Visualisierung: smartVISU
        - Gira TS3 - iPhone & iPad - Mobotix T24 - ekey - Denon 2313 - Russound C5 (RIO over TCP Plugin) -

        Kommentar


          #5
          Zitat von SvStefan Beitrag anzeigen
          Für Abfragen wie "kWh in der letzten Kalenderwoche" müsste man diese Idee weiter ausbauen.
          Aber bitte in einer kleinen Logik. Das kann man so viel schöner lesen/nachvollziehen und eleganter machen.

          Bis bald

          Marcus

          Kommentar


            #6
            Hallo,

            bei mir funktioniert das leider nicht wie gewollt. Habe die Vorgehensweise zwar kapiert, aber ich denke es scheitert an der Syntax.

            Habe mir die Items, wie angegeben, konfiguriert.

            Code:
            [Zeit]
            	[[minutenseitmitternacht]]
            		type = num
            		enforce_updates = yes
            		crontab = init | * * * * = 1
            		eval = int(((sh.now() - sh.now().replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds()) // 60)
            		[[[dbstr]]]
            			type = str
            			cache = on
            			eval_trigger = zeit.minutenseitmitternacht
            			eval = str(sh.zeit.minutenseitmitternacht()) + 'i'
                        
            [Verbrauch]   
                    [[heute]]
            			knx_dpt = 14
            			type = num
            			sqlite = yes
            			cache = on
            			crontab = * * * * = 1
            			eval = sh.Iskra.stand() - sh.Iskra.stand.db('max', sh.Zeit.minutenseitmitternacht.dbstr(), sh.Zeit.minutenseitmitternacht.dbstr())
            			eval_trigger = Iskra.stand
            Iskra.stand sieht so aus und funktioniert.

            Code:
            [Iskra]
                [[stand]]
                    iskra_code = 1-0:1.8.0*255
                    device = /dev/ttyUSB0
                    type = num
                    sqlite = yes
            Leider funktioniert die Berechnung nicht.

            Code:
            > ls Zeit
            Items:
            ======
            Zeit
            Zeit.minutenseitmitternacht = 107
            Zeit.minutenseitmitternacht.dbstr = 
            > ls Verbrauch
            Items:
            ======
            Verbrauch
            Verbrauch.heute = 0
            Irgendwie wird der String nicht angezeigt oder erzeugt. Aber ich kann den Fehler nicht erkennen. Wäre super wenn jemand eine Idee hat oder den Fehler sieht.

            Danke und Grüße

            Sven

            Kommentar


              #7
              Problem gelöst!!
              Wer genau hinsieht erkennt, dass ich das Zeit-Item groß geschrieben habe, aber im [[[dbstr]]] klein.

              Nun funktionierts!!
              Danke

              Kommentar


                #8
                Ich fange gerade an die ersten Zeilen zu tippen und frage mich ob das nicht vielleicht schon jemand gemacht hat?

                Eine Logik die mir folgende items füllt:

                Code:
                [month]
                    [[since]]
                        [[[year]]]
                    [[until]]
                        [[[year]]]
                [week]
                    [[since]]
                        [[[month]]]
                        [[[year]]]
                    [[until]]
                        [[[month]]]
                        [[[year]]]
                [day]
                    [[since]]
                        [[[week]]]
                        [[[month]]]
                        [[[year]]]
                    [[until]]
                        [[[week]]]
                        [[[month]]]
                        [[[year]]]
                [hour]
                    [[since]]
                        [[[midnight]]]
                        [[[week]]]
                        [[[month]]]
                        [[[year]]]
                    [[until]]
                        [[[midnight]]]
                        [[[week]]]
                        [[[month]]]
                        [[[year]]]
                [minute]
                    [[since]]
                        [[[hour]]]
                        [[[midnight]]]
                        [[[week]]]
                        [[[month]]]
                        [[[year]]]
                    [[until]]
                        [[[hour]]]
                        [[[midnight]]]
                        [[[week]]]
                        [[[month]]]
                        [[[year]]]
                Damit könnte man dann recht hübsch arbeiten ... oder ist das etwas oversized? Ich wollte mir mal meine Arbeitszahl pro Tag und Wochen ausrechnen und visualisieren und hätte dann gleich alle items die man vielleicht noch benötigt gleich mit angelegt. Starten würde ich die Woche dann jeweils mit Montag, ob das über den Jahres- oder Monatswechsel dann Probleme macht bekommt man schnell raus .
                Umgezogen? Ja! ... Fertig? Nein!
                Baustelle 2.0 !

                Kommentar


                  #9
                  Falls es jemanden interessiert gibt es das Ergebnis hier: https://knx-user-forum.de/smarthome-...tml#post446021
                  Umgezogen? Ja! ... Fertig? Nein!
                  Baustelle 2.0 !

                  Kommentar


                    #10
                    Hallo zusammen,

                    inspiriert von diesem Thread habe ich mir ein Plugin gebaut, da ich nicht so der Freund von unzähligen Zwischen- und Hilfsitems bin. Das Plugin zählt die Impulse eines Zählers und kann die momentane Leistung wie hier im Thread beschrieben ermitteln. Außerdem ist es möglich, die Verbrauchswerte für Zeiträume in der Vergangenheit über ein einfaches eval zu ermitteln.

                    Coding und Doku liegen auf GitHub unter https://github.com/i-am-offline/smarthome.plugin.meter

                    Grüße
                    offline

                    Kommentar


                      #11
                      Zitat von SvStefan Beitrag anzeigen
                      Für meine Wärmepumpe, die an dem Stromzähler dran hängt, hab ich dann zwei weitere Items, wobei in das "Impuls" Item direkt die Impulse des S0-Zählers reinkommen und das "Gesamt" Item den Gesamt-kWh-Stand aufnimmt. Ein Watch auf das Impuls-Item ruft eine externe Logik auf, welche den kWh Stand erhöht:
                      Code:
                      sh.waermepumpe.verbrauch.gesamt(sh.waermepumpe.verbrauch.gesamt() + 0.01)

                      Hallo Stefan,

                      wenn ich das richtig verstehe, könnte das die Lösung für "mein Problem" hier sein. (oder vielleicht auch nicht... da Dir der Zählerstand "egal" ist, nur der Impuls ist wichtig)

                      Könntes Du dein gesamtes Item hier oder dort einstellen?

                      Danke

                      Kommentar


                        #12
                        Hallo zusammen,

                        ich bekomme beim "Jahr" eine Fehlermeldung - liegt es daran, dass die Items noch nicht seit > 1 Jahr aktiv sind?

                        Code:
                        2022-02-05 00:06:51 WARNING lib.item.item Item verbrauch_gas.gaszaehler.jahr: problem evaluating 'sh.verbrauch_gas.gaszaehler.zaehlerstand() - sh.verbrauch_gas.gaszaehler.zaehlerstand.db('max', sh.date.day.since.year.dbstr(), sh.date.day.since.year.dbstr())': unsupported operand type(s) for -: 'float' and 'NoneType'
                        2022-02-05 00:06:59 WARNING lib.item.item Item verbrauch_gas.gaszaehler.jahr: problem evaluating 'sh.verbrauch_gas.gaszaehler.zaehlerstand() - sh.verbrauch_gas.gaszaehler.zaehlerstand.db('max', sh.date.day.since.year.dbstr(), sh.date.day.since.year.dbstr())': unsupported operand type(s) for -: 'float' and 'NoneType'
                        2022-02-05 00:07:56 WARNING lib.item.item Item verbrauch_strom.verbrauch.jahr: problem evaluating 'sh.verbrauch_strom.verbrauch.zaehler() - sh.verbrauch_strom.verbrauch.zaehler.db('max', sh.date.day.since.year.dbstr(), sh.date.day.since.year.dbstr())': unsupported operand type(s) for -: 'float' and 'NoneType'
                        2022-02-05 00:08:21 WARNING lib.item.item Item verbrauch_gas.gaszaehler.jahr: problem evaluating 'sh.verbrauch_gas.gaszaehler.zaehlerstand() - sh.verbrauch_gas.gaszaehler.zaehlerstand.db('max', sh.date.day.since.year.dbstr(), sh.date.day.since.year.dbstr())': unsupported operand type(s) for -: 'float' and 'NoneType'
                        2022-02-05 00:09:02 WARNING lib.item.item Item verbrauch_gas.gaszaehler.jahr: problem evaluating 'sh.verbrauch_gas.gaszaehler.zaehlerstand() - sh.verbrauch_gas.gaszaehler.zaehlerstand.db('max', sh.date.day.since.year.dbstr(), sh.date.day.since.year.dbstr())': unsupported operand type(s) for -: 'float' and 'NoneType'
                        2022-02-05 00:09:04 WARNING lib.item.item Item verbrauch_strom.verbrauch.jahr: problem evaluating 'sh.verbrauch_strom.verbrauch.zaehler() - sh.verbrauch_strom.verbrauch.zaehler.db('max', sh.date.day.since.year.dbstr(), sh.date.day.since.year.dbstr())': unsupported operand type(s) for -: 'float' and 'NoneType'
                        2022-02-05 00:10:09 WARNING lib.item.item Item verbrauch_gas.gaszaehler.jahr: problem evaluating 'sh.verbrauch_gas.gaszaehler.zaehlerstand() - sh.verbrauch_gas.gaszaehler.zaehlerstand.db('max', sh.date.day.since.year.dbstr(), sh.date.day.since.year.dbstr())': unsupported operand type(s) for -: 'float' and 'NoneType'
                        2022-02-05 00:11:31 WARNING lib.item.item Item verbrauch_gas.gaszaehler.jahr: problem evaluating 'sh.verbrauch_gas.gaszaehler.zaehlerstand() - sh.verbrauch_gas.gaszaehler.zaehlerstand.db('max', sh.date.day.since.year.dbstr(), sh.date.day.since.year.dbstr())': unsupported operand type(s) for -: 'float' and 'NoneType'
                        2022-02-05 00:11:39 WA


                        Code:
                        # verbrauch_gas.yaml
                        
                        verbrauch_gas:
                            gaszaehler:
                                zaehlerstand: # das ist der Wert vom Gaszähler 
                                    type: num
                                    visu_acl: ro
                                    database: init
                                    eval: round(sh.verbrauch_gas.gaszaehler.zaehlerstand.zaehlerstand_offset() + sh.verbrauch_gas.gaszaehler.zaehlerstand.zaehlerstand_knx(), 3)
                         #ok#     eval: sh.verbrauch_gas.gaszaehler.zaehlerstand.zaehlerstand_offset() + sh.verbrauch_gas.gaszaehler.zaehlerstand.zaehlerstand_knx()
                                    eval_trigger:
                                      - verbrauch_gas.gaszaehler.zaehlerstand.zaehlerstand_knx
                                      - verbrauch_gas.gaszaehler.zaehlerstand.zaehlerstand_offset
                                      
                                      
                                    stunde: # zu festgelegten Zeiten wird der aktuelle Zaehlerstand in der DB abgelegt
                                        type: num
                                        database: init
                                        eval: round(sh.verbrauch_gas.gaszaehler.zaehlerstand.zaehlerstand_offset() + sh.verbrauch_gas.gaszaehler.zaehlerstand.zaehlerstand_knx(), 3)
                                        crontab: '0 */6 * * = 1' # alle 6 Stunden
                                    
                                    erster:
                                        type: num
                                        database: init
                                        eval: round(sh.verbrauch_gas.gaszaehler.zaehlerstand.zaehlerstand_offset() + sh.verbrauch_gas.gaszaehler.zaehlerstand.zaehlerstand_knx(), 3)
                                        crontab: '0 0 1 * = 1' # Monatserster um 00:00 Uhr
                                        
                                       
                                # enforce_change: yes
                                # crontab: 59 23 * * = 1
                                #    struct: my.wertehistorie.total
                            
                                    zaehlerstand_knx:
                                        type: num
                                        knx_dpt: 12
                                        knx_cache: 6/0/1 # Kanal A für Wasser
                                       ## eval: round(value/1000, 1)
                                        eval: value/100
                                        cache: yes
                                    
                                        zaehlerstand_knx_reset:
                                            type: bool
                                            knx_dpt: 1
                                            knx_send: 6/0/2
                                            knx_cache: 6/0/2
                                            enforce_updates: yes
                                
                                    zaehlerstand_offset:
                                        name: Zählerstand Gaszähler bei KNX-Zähler = 0
                                        type: num
                                        initial_value: 725.724
                                        cache: yes
                               
                                heute:
                                        type: num
                                        # database: true
                                        eval: sh.verbrauch_gas.gaszaehler.zaehlerstand() - sh.verbrauch_gas.gaszaehler.zaehlerstand.db('max', '1d', str(shtime.time_since(shtime.today(), 'im')) + 'i')
                                        eval_trigger: verbrauch_gas.gaszaehler.zaehlerstand
                                
                               
                               
                                gestern:
                                       # name: Gasverbrauch_gestern
                                        type: num
                                    #    # database: init
                                        eval: sh.verbrauch_gas.gaszaehler.zaehlerstand.db('max', '1d','1d') - sh.verbrauch_gas.gaszaehler.zaehlerstand.db('max', '2d','2d')
                                        eval_trigger: verbrauch_gas.gaszaehler.zaehlerstand    
                         
                         
                                vorgestern:
                                       # name: Stromverbrauch_vorgestern
                                        type: num
                                    #    # database: init
                                        eval: sh.verbrauch_gas.gaszaehler.zaehlerstand() - sh.verbrauch_gas.gaszaehler.zaehlerstand.db('max', '1d', '1d')
                                        eval_trigger: verbrauch_gas.gaszaehler.zaehlerstand    
                         
                                
                                woche:
                                      #  name: Stromverbrauch_letzteWoche
                                        type: num
                                    #    # database: init
                                        eval: sh.verbrauch_gas.gaszaehler.zaehlerstand() - sh.verbrauch_gas.gaszaehler.zaehlerstand.db('max', sh.date.day.since.week.dbstr(), sh.date.day.since.week.dbstr())
                                        eval_trigger: verbrauch_gas.gaszaehler.zaehlerstand
                                        
                                        
                                        
                                monat:
                                     #   name: Stromverbrauch_Monat
                                        type: num
                                    #    # database: init
                                        eval: sh.verbrauch_gas.gaszaehler.zaehlerstand() - sh.verbrauch_gas.gaszaehler.zaehlerstand.db('max', sh.date.day.since.month.dbstr(), sh.date.day.since.month.dbstr())
                                        eval_trigger: verbrauch_gas.gaszaehler.zaehlerstand
                        
                        
                                jahr:
                                    #    name: Stromverbrauch_Jahr
                                        type: num
                                    #    # database: init
                                        eval: sh.verbrauch_gas.gaszaehler.zaehlerstand() - sh.verbrauch_gas.gaszaehler.zaehlerstand.db('max', sh.date.day.since.year.dbstr(), sh.date.day.since.year.dbstr())
                                        eval_trigger: verbrauch_gas.gaszaehler.zaehlerstand

                        Kommentar


                          #13
                          Wie def Log Eintrag sagt, versuchst Du eine Summe aus Float Werten und None Werten zu bilden und das geht nicht.
                          Mindestens einer der Werte, die Du in der Summenbildung hast, ist also None.
                          Viele Grüße
                          Martin

                          There is no cloud. It's only someone else's computer.

                          Kommentar


                            #14
                            Danke Martin,

                            für die Rückmeldung. Wie geschrieben, kann es daran liegen, dass in der DB noch keine "ein Jahr alte" Werte stehen, oder ist der Fehler woanders zu suchen?

                            Kommentar


                              #15
                              Zitat von Maexle Beitrag anzeigen
                              kann es daran liegen, dass in der DB noch keine "ein Jahr alte" Werte stehen
                              Darauf würde ich tippen.
                              Viele Grüße
                              Martin

                              There is no cloud. It's only someone else's computer.

                              Kommentar

                              Lädt...
                              X