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

  • mumpf
    antwortet
    Hi,

    Zitat von Morg Beitrag anzeigen
    Ja - aber das Item ist ja nicht gesetzt worden, sondern hat die Berechnung über eval_trigger angestoßen... ?


    Doch. Ein
    • knx_listen (Trigger vom KNX-Plugin),
    • eval_trigger (Trigger vom anderen Item),
    • cycle (Trigger vom Laufzeitsystem vom shNG),
    • nw_udp_listen (Trigger vom Network-Plugin)
    • ...
    alles sind attribute, die ein Item triggern. Der Trigger bringt einen neuen Wert mit (im value) und setzt diesen Wert. Wenn da noch ein eval steht, dann wird eben dieser eval mit dem neuen Wert ausgeführt, damit man noch vor dem setzen was machen kann. Einzige mir bekannte Ausnahme: der eval_trigger setzt den value nicht ohne einen eval.

    Im Prinzip ist das shNG mit seinen Items und Triggern genau so Eventbasiert wie der KNX-Bus mit seinen KO und GA.

    Gruß, Waldemar


    Einen Kommentar schreiben:


  • Morg
    antwortet
    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... ?

    Einen Kommentar schreiben:


  • mumpf
    antwortet

    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

    Einen Kommentar schreiben:


  • Sisamiwe
    antwortet
    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?

    Einen Kommentar schreiben:


  • Morg
    antwortet
    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

    Einen Kommentar schreiben:


  • mumpf
    antwortet
    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

    Einen Kommentar schreiben:


  • Morg
    antwortet
    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?

    Einen Kommentar schreiben:


  • Sisamiwe
    antwortet
    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

    Einen Kommentar schreiben:


  • Morg
    antwortet
    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

    Einen Kommentar schreiben:


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

    Einen Kommentar schreiben:


  • mumpf
    antwortet
    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

    Einen Kommentar schreiben:


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

    Einen Kommentar schreiben:


  • Morg
    antwortet
    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

    Einen Kommentar schreiben:


  • Sisamiwe
    antwortet
    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

    Einen Kommentar schreiben:


  • stoepf
    antwortet
    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'

    Einen Kommentar schreiben:

Lädt...
X