Ankündigung

Einklappen
Keine Ankündigung bisher.

Logik zur Pufferung einer KNX S0-Zählerstandes

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

    Logik zur Pufferung einer KNX S0-Zählerstandes

    Hallo,

    ich zähle über einen Reed-Kontakt an einem MDT-Tasterinterface meinen Wasserverbrauch. Dazu nutze ich die Zählerfunktion im Tasterinferface, so dass über KNX als 4byte Wert der Zählerstand gesendet wird. Das klappt gut.

    Allerdings scheint das Tasterinterface den Zählerstand bei Bussspannungsabfall bzw -ausfall nicht zwischenzuspeichern. Nach Busspannungswiederkehr ist der Zählerstand 0 und somit auch mein Wasserzählerstand in shNG falsch.

    Nun stelle ich mir eine shNG Logik vor, die einen Puffer bzw so eine Art Rücklaufsperre darstellt, denn der Zählerstand darf ja nur steigen.
    Ist also der neue KNX Wert 0 bzw. 1 (in Folge einen höheren Wertes) so soll der dieser neue Wert auf den letzt bekannten Wert vorher addiert werden.

    Wie kann ich das am besten Umsetzten bzw. hat das Problem schon jemand gelöst?

    Danke Euch.

    #2
    Bei mir kommen die Pulse über das Netzwerkplugin und die Pulse zählt dann SmarthomeNG für mich.

    Code:
    Wasser:
    
        Bezug:
            type: bool
            nw: yes
            on_update: ..Gesamt = sh...Gesamt() + 1 if sh..() else None
        
        Gesamt:
            type: num
            database: 'init'

    Kommentar


      #3
      Ich habe mir nochmal Gedanken gemacht, brauche aber von den Experten Msinn mumpf kurze Rückmeldung bzw. Bestätigung.
      • über das KNX-Plugin kommt der KNX-Zählerstand auf mein Item und wird dort erstmal "value" zugewiesen. Da mit "value" nicht weiter gearbeitet wird, wird der über KNX empfange Wert dem Item zugewiesen.
      • nun möchte ich prüfen, ob der neue, über KNX empfangene Wert, der in "value" zwischengespeichert wurde, größer ist, als der Wert dem aktuell im Item steht.
        Wenn ja, soll der Wert ins Item, wenn nicht soll der neue Wert auf den aktuellen addiert werden.
      Meine Frage ist, wie ich an den aktuellen Wert des Items komme?
      Ist
      Code:
      prev_value()
      die richtige Funktion? Mein Verständnis ist, dass ich damit an den letzen Item Wert komme.

      Danke für eine kurze Rückmeldnung

      Kommentar


        #4
        item() ist aktueller Wert
        item.property.last_value() ist letzter Wert
        item.property.prev_value() ist vorletzter Wert

        Ich bin aber nicht sicher, ob das nicht aufwändiger ist, als die Pulse direkt in shng zu zählen... aber es gibt ja immer mehrere Wege

        Kommentar


          #5
          Nebenbei zur Info, die neue Generation .02 der MDT Tasterinterface hat die Logik komplett an Board. Die Datenbank kommt Anfang der Woche.

          Kommentar


            #6
            Hi,

            Zitat von Sisamiwe Beitrag anzeigen
            nun möchte ich prüfen, ob der neue, über KNX empfangene Wert, der in "value" zwischengespeichert wurde, größer ist, als der Wert dem aktuell im Item steht.
            Wenn ja, soll der Wert ins Item, wenn nicht soll der neue Wert auf den aktuellen addiert werden.
            wenn ich Dich richtig verstehe, ist das genau das, wofür ursprünglich eval gedacht war:

            Code:
            ItemXYZ:
                type: number
                eval: value if sh..() < value else sh..() + value
            Ich bin mir nicht sicher, ob das mit der relativen Adressierung korrekt ist, da müsstest Du nochmal in die Doku schauen, ich hab schon lange nichts mehr mit shNG gemacht. Gemeint ist aber, dass sh..() das ItemXYZ selbst adressiert.

            Wichtig hier: value in einem eval enthält schon den neuen Wert, wogegen ItemXYZ noch den vorherigen Wert enthält.

            Gruß, Waldemar

            OpenKNX www.openknx.de

            Kommentar


              #7
              Zitat von mumpf Beitrag anzeigen
              Code:

              ItemXYZ: type: number eval: value if sh..() < value else sh..() + value
              Ich bin mir nicht sicher, ob das mit der relativen Adressierung korrekt ist, da müsstest Du nochmal in die Doku schauen, ich hab schon lange nichts mehr mit shNG gemacht. Gemeint ist aber, dass sh..() das ItemXYZ selbst adressiert.

              Danke.

              Ich habe gemerkt, dass da noch ein Denkfehler drin ist.
              Wenn der KNX-Zähler resettet wurde (u.a. durch Busspannungsausfall), dann ist dessen Wert (also das value) dauerhaft niedriger, da das ItemXYZ ja den Gesamtcount enthalten soll.
              Man muss also den Wert des Gesamtcounts sichern, wenn der neue Wert 0 oder besser 1 ist (0 kommt auch erstmal beim Restart von shNG) bis cache oder DBinit den Itemwert wieder hergestellt haben. Das muss dann über ein Hilfsitem passieren.

              Kommentar


                #8
                Michael, genau deshalb finde ich den Weg über Hilfsitem usw eher aufwändig. Wenn gleich das ganze Zählen in shng läuft, ist es einfacher

                ... oder im Interface, dann ist es noch simpler

                Kommentar


                  #9
                  Zitat von Morg Beitrag anzeigen
                  Wenn gleich das ganze Zählen in shng läuft, ist es einfacher
                  Da hast Du schon Recht. Nichtsdestotrotz wolle ich eine Redundanz mit Zählen per KNX und shNG.
                  und dümmer wird man auch nicht.

                  So sieht das Ergebnis aus:

                  Code:
                  %YAML 1.1
                  ---
                  wasserzaehler:
                      zaehlerstand:
                          type: num
                          visu_acl: ro
                          database: init
                          eval: round(sh.wasserzaehler.bezug.zaehlerstand_offset() + sh.wasserzaehler.bezug() * 0.05, 2)
                          eval_trigger:
                            - wasserzaehler.bezug
                            - wasserzaehler.bezug.zaehlerstand_offset
                          struct: wertehistorie_total
                    
                      bezug:
                          name: Impulszählerstand
                          type: num
                          eval: sh.wasserzaehler.bezug.knx_input() + sh.wasserzaehler.bezug.ruecklaufperre()
                          eval_trigger:
                            - wasserzaehler.bezug.knx_input
                          database: init
                            
                          ruecklaufperre:
                              name: Ruecklaufsperre der Impulszaehlerstandes
                              type: num
                              eval: sh..() + sh.wasserzaehler.bezug.knx_input.prev_value() if value == 0 else None  
                              eval_trigger:
                                - wasserzaehler.bezug.knx_input
                              database: init
                  
                          zaehlerstand_offset:
                              name: Zählerstand der Wasseruhr bei Impulszähler = 0
                              type: num
                              initial_value: 695.82
                              cache: yes
                              
                          knx_input:
                              type: num
                              knx_dpt: 13
                              knx_cache: 0/6/4
                              database: yes
                  
                          knx_input_wert_reset:
                              type: bool
                              knx_dpt: 1
                              knx_send: 0/6/6
                              knx_cache: 0/6/6
                              enforce_updates: yes

                  Kommentar


                    #10
                    Die Logik hinter rücklaufsperre verstehe ich noch nicht. Ich kriege es nicht mal hin zu formulieren, welche Frage ich dazu stellen müsste.

                    sh..() ist der eigene (noch nicht veränderte) Wert, 0 der neue Wert (oder auch nicht) - wann oder wo wird sie denn gesetzt / beschrieben?

                    Kommentar


                      #11
                      Hi,

                      Zitat von Morg Beitrag anzeigen
                      wann oder wo wird sie denn gesetzt / beschrieben?
                      auch das steht natürlich im Item:
                      Code:
                      eval_trigger:
                          - wasserzaehler.bezug.knx_input
                      Da dieses Item triggert, steht dessen Wert im "value". Wenn dieser Wert 0 ist, wird der vorherige Wert von knx_input genommen, sonst passiert gar nichts.

                      Ich meine aber, das kann nicht funktionieren:
                      • Neustart shng: es kommen Werte > 0 an, das if läuft immer auf "None"
                      • dann wird der Zähler neu gestartet und liefert eine 0 -> im Item gibt es aber kein prev_value, weil das if immer auf None lief.
                      Gruß, Waldemar
                      OpenKNX www.openknx.de

                      Kommentar


                        #12
                        Danke erstmal für die Erläuterung. Dass value jetzt der Wert von einem anderen Item ist, hätte ich nicht erwartet... aber ok. D.h., dass knx_input schon neu gesetzt ist - und wieso dann nicht last_value sondern prev_value, also der vorletzte Wert?

                        Und zu deiner Vermutung: es ist ja der prev_value von knx_input, nicht von ruecklaufsperre, der sollte ja vorhanden sein.

                        Ich wäre mir nicht sicher, ob das Timing zwischen bezug und ruecklaufsperre deteministisch ist. Ich vermute, dass Michael das getestet hat und es bei ihm funktioniert. Ich halte es trotzdem für ... schwierig. Aber man lernt dabei, und es gibt immer mehrere Wege

                        Kommentar


                          #13
                          Hallo Waldemar,
                          danke für Deinen Input. Es funktioniert, aber trotzdem nehme ich Deine Bedenken ernst.

                          Zitat von mumpf Beitrag anzeigen
                          Ich meine aber, das kann nicht funktionieren:
                          • Neustart shng: es kommen Werte > 0 an, das if läuft immer auf "None"
                          • dann wird der Zähler neu gestartet und liefert eine 0 -> im Item gibt es aber kein prev_value, weil das if immer auf None lief.
                          Hast Du ggf. einen besseren Vorschlag?

                          Kommentar


                            #14

                            Zitat von Morg Beitrag anzeigen
                            Und zu deiner Vermutung: es ist ja der prev_value von knx_input, nicht von ruecklaufsperre, der sollte ja vorhanden sein.
                            Stimmt, das hab ich falsch gesehen - ja, den sollte es geben, außer beim Startup von shNG, da weiß ich nicht, wie sich das verhält.

                            Zitat von Morg Beitrag anzeigen
                            Dass value jetzt der Wert von einem anderen Item ist, hätte ich nicht erwartet...
                            value ist immer der Wert, den das Item von außen gesetzt bekommen soll, egal wer es setzt.

                            ​​​
                            Zitat von Sisamiwe Beitrag anzeigen
                            Hast Du ggf. einen besseren Vorschlag?
                            Leider nein, das ist aber auch ein Fall, den man ausprobieren muss, weil es wirklich auf die Telegrammreihenfolge in den jeweiligen Situationen ankommt. Da es bei Dir um die Beseitigung von Randerscheinungen bei Neustart geht, musst Du aber immer alle Fälle testen:
                            1. Neustart nur vom shNG
                            2. Neustart nur vom Zähl-Interface
                            3. Neustart durch Stromausfall
                            Letzteres ist immer am schwierigsten zu behandeln, denn die Bootzeit von shNG führt häufig dazu, dass man irgendwelche Telegramme auf dem Bus verpasst. Ob dann die entsprechenden Werte nachgelesen werden können, hängt von der jeweiligen Anwendung ab.

                            Und im Fall 1. und 3. weiß ich konkret in dem Fall nicht, wie prev_value gesetzt ist...

                            Gruß, Waldemar
                            OpenKNX www.openknx.de

                            Kommentar


                              #15
                              Zitat von mumpf Beitrag anzeigen
                              value ist immer der Wert, den das Item von außen gesetzt bekommen soll, egal wer es setzt.
                              Ja - aber das Item ist ja nicht gesetzt worden, sondern hat die Berechnung über eval_trigger angestoßen... ?

                              Kommentar

                              Lädt...
                              X