Ankündigung

Einklappen
Keine Ankündigung bisher.

Problem mit autotimer

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

    Problem mit autotimer

    Moin,

    ich möchte den autotimer dafür einsetzen meine Rollo-Automatik für eine gewisse Zeit auszusetzen. Dies soll immer dann geschehen, wenn das Rollo von Hand bedient wird. Sobald die Gruppenadresse für das Rollo-Fahren am Bus erkannt wird, ob von der SmartHome oder einem KNX-Taster, soll soll die "auto.pause" gesetzt werden und nach einer gewissen Zeit wieder abfallen. Natürlich könnte ich dies für jedes Rollo durch eine Logik erreichen, ich würde es aber lieber direkt im Item erledigen, das finde ich übersichtlicher. Bei folgender Beschaltung habe ich das Problem, dass der Trigger in jedem Durchlauf neu gestartet wird und sich die SH totläuft.
    Code:
    [auto]
    ...
       [[pause]]
            [[[Arbeitszimmer]]]
                type = bool
                visu_acl = rw
                knx_dpt = 1
                knx_listen = 2/2/4  # Gruppenadresse Rollo Arbeitszimmer fahren
                eval = True if sh.knx.groupread('2/2/4') == 1 else None
                autotimer = 30m = False
    
    ...
    Was mache ich falsch?
    Oder kennt jemand eine bessere Methode?

    Gruß Rudi
    Gruß
    ElektroRudi

    ............kann,.muß aber net....

    #2
    Hi,

    Dein Item wird nie false! eval wird IMMER durchlaufen, auch beim autotimer. Ich habe bei mir was ähnliches - ich will feststellen, ob in den letzten 15 Minuten jemand im Raum war:
    Code:
            [[[Praesenz]]]
                #wird vom PM gesetzt
                name = Präsenz aktuell
                type = bool
                knx_dpt = 1
                knx_cache = 6/0/20
                [[[[Fuenf]]]]
                    #wird vom PM gesetzt
                    name = Präsenz in den letzten 5 Minuten
                    type = bool
                    knx_dpt = 1
                    knx_cache = 6/0/21
                [[[[Fuenfzehn]]]]
                   #wird von sh berechnet
                    name = Präsenz in den letzten 15 Minuten
                    type = num
                    value = 2
                    autotimer = 15m = 2
                    eval = sh.EG.Diele.Praesenz() if int(value) > 1 else 1
                    eval_trigger = EG.WC.Praesenz
    Zur Erklärung (das Item Fuenfzehn ist gemeint):
    Beim Start von sh wird value = 2 gesetzt. Der eval macht daraus den gleichen Wert wie Praesenz, je nachdem ob Praesenz da ist oder nicht, sagen wir mal es ist keine Praesenz da, also 0.
    Irgendwann geht Praesenz auf 1, der eval_trigger spricht an und der eval setzt Fuenfzehn auf 1, da value = 1. Der autotimer geht auf 15m.
    Die Praesenz geht irgendwann auf 0 (bei mir nach 15 Sekunden), der eval_trigger spricht wieder an und der eval setzt Fuenfzehn wieder auf 1, da value jetzt 0. Ich habe es nicht getestet, aber der autotimer dürfte wieder auf 15m gesetzt werden.
    Wenn zwischendurch wieder Praesenz kommt, wird der autotimer wieder auf 15m gesetzt.
    Irgendwann läuft der autotimer ab und liefert den Wert 2. Der eval setzt das Item jetzt auf Praesenz (was ziemlich sicher = 0 ist, ausser es geht gerade während der Verarbeitung auf 1 - ist ein eher unwichtiger Grenzfall).
    Bei Dir sollte auch einfach
    Code:
                    eval = 0 if int(value) > 1 else 1
    reichen.

    Gruß, Waldemar
    OpenKNX www.openknx.de

    Kommentar


      #3
      Danke Waldemar für die ausführliche Erklärung.
      Wo finde ich denn eine Beschreibung was z.B. hinter "eval =" alles stehen darf, es ist ja nicht typisch Phython!?

      Zitat von mumpf Beitrag anzeigen

      Code:
      eval = 0 if int(value) > 1 else 1
      Wirft eine Fehlermeldung weil ich einen "bool"-Typ verwende.
      Da ich mit sh.knx.... nicht weitergekommen bin, habe ich den Code folgendermaßen abgeändert:

      [[pause]]
      [[[Arbeitszimmer]]]
      type = bool
      visu_acl = ro
      value = False
      autotimer = 1m = False
      eval = True if value == True else False
      eval_trigger = EG.Arbeitszimmer.Rollo.move
      Nach meinen Überlegungen müsste hier value imme False bleiben, bleibt es aber nicht
      Wird vom eval_trigger das value geändert?
      Denn bei "eval = True if value == True else False" sollte immer False ergeben sobald das value einmal False war !?
      Wenn das Rollo fährt, und nur dann, wird das value True.

      Mit der Position des Rollos funktioniert es, ich müsste dann halt abfragen ob der Wert größer -1 ist.
      Mit 0 als Startwert habe ich ein Problem, weil Rollo oben auch den Pos-Wert 0 hat.

      [[pause]]
      [[[Arbeitszimmer]]]
      type = num
      value = -1
      autotimer = 1m = -1
      eval = int(sh.EG.Arbeitszimmer.Rollo.pos()) if int(value) > -1 else -1
      eval_trigger = EG.Arbeitszimmer.Rollo.pos

      Würde funktionieren, finde ich aber nicht schön.
      Ich möchte lieber mit bool arbeiten.
      Ich denke, ich habe noch ein grundsätzliches Verständnisproblem...

      Gruß Rudi
      Gruß
      ElektroRudi

      ............kann,.muß aber net....

      Kommentar


        #4
        Hi Rudi,

        Zitat von ElektroRudi Beitrag anzeigen
        Wo finde ich denn eine Beschreibung was z.B. hinter "eval =" alles stehen darf, es ist ja nicht typisch Phython!?
        ist doch Python, aber eben nur das, was Du in eine Zeile rein bekommst. Als Erweiterungen gibt es das sh-Objekt, dass Dir Zugriff auf alle Items und smarthome-Funktionen gibt und value, da steht der Wert, den das evaluierte Item bekommen soll.

        Zitat von ElektroRudi Beitrag anzeigen
        Wirft eine Fehlermeldung weil ich einen "bool"-Typ verwende.
        Mein Beispiel geht nur mit einem num-Item, da man hierfür 3 Werte braucht und bool nur 2 bietet. Aber bei Python ist 0=False und alle anderen Werte True, wobei mein Item immer nur 0 oder 1 liefert.

        Zitat von ElektroRudi Beitrag anzeigen
        Ich denke, ich habe noch ein grundsätzliches Verständnisproblem...
        Nach meinen Überlegungen müsste hier value imme False bleiben, bleibt es aber nicht
        Ja! value ist nicht der Wert, den das Item hat, sondern der Wert, den das Item bekommen soll! Also - anders gesagt, wenn da kein eval stehen würde, würde das Item auf den Wert value gesetzt. Oder noch anders gesagt: Wenn ein Item [abc] den Wert 0 hat, das Item durch irgendwas (knx_listen, eval_trigger, autotimer, crontab, logik, ...) einen Wert 2 bekommt, ist beim eval der Wert von sh.abc() noch 0, der Wert von value aber 2!

        Zitat von ElektroRudi Beitrag anzeigen
        Wird vom eval_trigger das value geändert?
        Denn bei "eval = True if value == True else False" sollte immer False ergeben sobald das value einmal False war !?
        Wenn das Rollo fährt, und nur dann, wird das value True.
        Ja! Aber nicht von eval_trigger, sondern von der Routine, die den Wert des Items ändern will, und zwar egal, wodurch die Wertänderung ausgelöst wird - auch von eval_trigger!

        Zitat von ElektroRudi Beitrag anzeigen
        Ich möchte lieber mit bool arbeiten.
        Das tut mein Beispiel (liefert 0 oder 1), muss aber technisch ein num sein, da man intern mehr als 2 Werte braucht.

        Du hast beim move noch ein anderes Problem: Das ist 1 beim runterfahren und 0 beim hochfahren. Deswegen kannst Du nicht auf == True abfragen, deswegen arbeite ich intern mit einem Wert 2.
        Und das -1 in Deiner Lösung ist "schlecht", da es semantisch ein False ist aber technisch ein True ist.

        Gruß, Waldemar

        OpenKNX www.openknx.de

        Kommentar


          #5
          Hi,

          hier nochmal ein Vorschlag, wie es bei Dir laufen könnte/sollte (mit bool-Item):
          Code:
          [auto]
            [[pause]]
              [[[Arbeitszimmer]]]
                type = bool
                eval = value
                eval_trigger = auto.pause.Arbeitszimmer.calc
                [[[[calc]]]]
                  type = num
                  visu_acl = rw
                  value = 2
                  knx_dpt = 1
                  knx_listen = 2/2/4
                  eval = 0 if int(value) > 1 else 1
                  autotimer = 30m = 2
          Hab es aber nicht getestet... sollte aber klappen.

          Gruß, Waldemar
          OpenKNX www.openknx.de

          Kommentar


            #6
            Zitat von mumpf Beitrag anzeigen
            Hi,

            hier nochmal ein Vorschlag, wie es bei Dir laufen könnte/sollte (mit bool-Item):
            Code:
            [auto]
            [[pause]]
            [[[Arbeitszimmer]]]
            type = bool
            eval = value
            eval_trigger = auto.pause.Arbeitszimmer.calc
            [[[[calc]]]]
            type = num
            visu_acl = rw
            value = 2
            knx_dpt = 1
            knx_listen = 2/2/4
            eval = 0 if int(value) > 1 else 1
            autotimer = 30m = 2
            Hab es aber nicht getestet... sollte aber klappen.

            Gruß, Waldemar
            Danke Waldemar
            für Deine Geduld und super Erklärungen, jetzt habe auch ich es verstanden.

            Code:
                [[pause]]
                    [[[Arbeitszimmer]]]
                        type = num
                        visu_acl = ro
                        value = 2
                        autotimer = 1m = 2
                        eval = 1 if int(value) < 2 else 0
                        eval_trigger = EG.Arbeitszimmer.Rollo.move
            Funktioniert auch SUPER!!!
            Deine Variante werde ich auch gleich noch ausprobieren.

            Gruß Rudi
            Gruß
            ElektroRudi

            ............kann,.muß aber net....

            Kommentar


              #7
              Schau dir doch mal das autoblind plugin an. Wär evtl ne alternative

              Kommentar


                #8
                Hallo Zusammen,

                ich habe gerade überlegt, ob es möglich wäre ein "Fenster-Modul" rein mit evals zu implementieren:
                - Ausgewertet wird immer der Fensterkontakt
                - Es gibt ein "Counter" Item, was Anzahl der Betätigungen zählt (wozu auch immer...)
                - Es gibt ein "Warn" Item, welches (wenn Freigabe-Item == 1) nach Ablauf einer Zeit x auf "True" geht und beim Schließen des Fensters wieder gelöscht wird.

                Erster Ansatz:
                ...
                Code:
                [
                              [[[window]]]
                                        [[[[open]]]]
                                                name = Fenster offen
                                                type = bool
                                                visu_yes
                                                visu_acl = r
                                                knx_dpt = 1
                                                knx_listen = 4/1/1
                                                knx_init = 4/1/1
                                                [[[[[counter]]]]]
                                                        name = Zähler Zustandswechsel Fenster
                                                        type = num
                                                        cache = yes
                                                        sqlite = init # init with last db entry
                                                        eval_trigger = EG.office.window.open
                                                        eval = sh.EG.office.window.open.counter() + 1  if (int(value) == 1) else sh.EG.office.window.open.counter()
                                                [[[[[warn]]]]]
                                                        # TODO: (auto)timer der Wert nach 10min offenen Fenster setzt und wieder löscht.
                                                        name = Warnung Fenster länger als x offen
                                                        type = num
                                                        visu_acl = r
                                                        value = 2
                                                        autotimer = 10m = 2
                                                        eval = 1 if int(value) > 1 else 0
                                                        eval_trigger = EG.office.window.open

                Kommentar


                  #9
                  Warn wird doch damit alle 10 Minuten ausgelöst.
                  Du setzt per autotimer eine 2, was im eval wiederum zu einer 1 wird - unabhängig von anderen Bedingungen.
                  Und wenn dann das Fenster bewegt wird, wird warn zu 0, weil du mit dem eval_trigger einen value von 0 oder 1 kriegst, welche im eval beide zu 0 werden.

                  Du musst also alle 10 Minuten das Fenster bewegen, damit du keine Warnung hast

                  Der Counter wird ja gar nirgends benutzt.

                  Kommentar


                    #10
                    Hi,

                    schon nicht schlecht, aber wie smai schon sagt, nicht an alle Fälle gedacht. Die Lösung bei Deinem Ansatz ist:
                    Code:
                    enforce_updates = true
                    eval = sh.EG.office.window.open() if value > 1 else 0
                    Es gibt 3 Fälle:
                    1. Du machst Fenster auf: warn wird auf 0 gesetzt (war schon null, deswegen enforce_updates), eval_trigger führt zum starten vom autotimer. Nach 10 Minuten feuert dieser eine 2, warn geht auf 1, weil Fenster noch offen steht, triggert den autotimer, der feuert nach 10 Minuten, warn geht wiederholt auf 1 usw.
                    2. Wenn nach > 10 Minuten das Fenster zu gemacht wird, geht warn auf 0, triggert den autotimer, der feuert nach 10 Minuten, es bleibt bei 0, er feuert wieder etc.
                    3. Wenn nach < 10 Minuten das Fenster zu gemacht wird, bleibt warn bei 0, sonst wie unter 2.
                    Bei Deiner Lösung ist nicht so gut, dass immer alle 10 Minuten getriggert wird. Das kann man besser lösen:
                    Code:
                    eval = value if value < 2 or sh.EG.office.window.open.warn() == 1 else sh.EG.office.window.open.warn()
                    Geht ohne enforce_updates, eine Warnung hast du, wenn warn = 2.
                    Die 3 Fälle hier:
                    1. Fenster geht auf: warn geht auf 1, autotimer startet, feuert nach 10 Minuten, warn geht auf 2, autotimer startet, feuert nach 10 Minuten, warn bleibt auf 2, kein autotimer mehr.
                    2. Fenster wird geschlossen: warn geht auf 0, autotimer startet, feuert nach 10 Minuten, warn bleibt bei 0, kein autotimer mehr.
                    3. Fenster wird nach < 10 Minuten wieder geöffnet: warn geht auf 1, autotimer macht restart, feuert nach 10 Minuten, dann wie bei 1.
                    Wenn man warn als Bool-Item haben will, macht man noch ein
                    Code:
                    [Warn]
                        type = bool
                        eval_trigger = EG.office.window.open.warn
                        eval = value == 2
                    Gruß, Waldemar
                    OpenKNX www.openknx.de

                    Kommentar


                      #11
                      So gefältts mir auch

                      Kommentar


                        #12
                        Vielen Dank für die ausführliche Beschreibung... aber ich muss mir das noch ein-/zweimal durchlesen bis ich es (hoffentlich) verstanden habe.

                        Vielleicht noch einmal zusammengefasst:
                        - Ein Ereignis (knx_listen, eval_trigger, autotimer, etc.) triggert den erst einmal den Item-Update Prozess
                        - Die Variable "value" beinhaltet den Wert, der zugewiesen werden soll und wird von eval_trigger Item oder autotimer übergeben, "sh.item()" beinhaltet den aktuell gesetzten wert.
                        - Ist sh.item() == value, denn läuft auch keine Evaluierung noch wird ein autotimer angestoßen, außer enforce_update = yes, dann werden immer alle Operationen durchlaufen.
                        - Also sollte generell ein "enforce_updates" in Kombination mit dem autotimer vermieden werden, da mit jeden latent gesetzten wert der autotimer neu getriggert wird.

                        Für die Item Struktur "Fenster" sind also 3 Items notwendig:

                        [open] Fensterstatus
                        [state] 0: Fenster geschlossen, 1: Fenster offen < x Minuten, 2: Fenster offen > x Minuten
                        [warn] 1: wenn state==2, 0: wenn state < 2 (und Nebenbedingungen erfüllt sind, z.B. Außentemperatur < ...°C, etc)
                        [counter] Zähler, wird um 1 erhöht, wenn state von 0 auf 1 wechselt.

                        Mein Ziel ist insgesamt ein "Item-Template" zu schaffen, welches sich um das Fenster kümmert:
                        - Status
                        - Warnung bei zu langer Öffnung abhängig von Klimatischen Randbedingung, oder zu hoher Windgeschwindigkeit, etc.
                        - Alarm, sofern die Alarmanlage scharf ist und das Fenster in der Meldekette aufgenommen ist, etc.
                        - Heizung, Ventil sperren wenn das Fenster zu lange offen ist
                        - etc.

                        Vielen Dank
                        Markus

                        Kommentar


                          #13
                          Hallo Zusammen,

                          habe es mal implementiert und getestet. State geht zwar nach dem öffnen unmittelbar auf "1" und beim schließen wieder auf "0" aber nicht nach 1 Minute auf "2".

                          Hab ich was übersehen?

                          Code:
                                                          [[[[[state]]]]]
                          
                                                                  name = Fensterstatus (0:closed, 1:open, 2:länger als t offen)
                          
                                                                  type = num
                          
                                                                  visu_acl = r
                          
                                                                  autotimer = 1m = 2
                          
                                                                  eval = value if value < 2 or sh.EG.office.window.open.state() == 1 else sh.EG.office.window.open.state()
                          
                                                                  eval_trigger = EG.office.window.open
                          
                                                          [[[[[warn]]]]]
                          
                                                                  name = Fenster zu lange offen Warnung
                          
                                                                  type = bool
                          
                                                                  visu_acl = r
                          
                                                                  eval = value == 2
                          
                                                                  eval_trigger = EG.office.window.open.warn


                          Code:
                          > ls EG.office.window.*
                          Items:
                          ======
                          EG.office.window.open.state = 1
                          EG.office.window.open.warn = False
                          EG.office.window.open = True

                          Kommentar


                            #14
                            Leider sehe ich den Fehler auch nicht, aber dafür einen anderen:
                            In der letzten Zeile sollte EG.office.window.open.state stehen anstatt warn.

                            Ich weiss gar nicht, ob sh.py dies abfängt oder ob du damit eine Edlosschleife hast, die irgendwann das System auslastet.

                            Kommentar


                              #15
                              Danke smai, .warn habe ich in .state geändert und den Fehler gefunden: autotimer übergibt den wert als string und nicht als int...
                              Letztendlich funktioniert es jetzt. Danke an Alle!

                              Für die Leser hier noch einmal die Zusammenfassung vom "Fenstermodul". Vielleicht kann es ja jemand brauchen...

                              Item Config:
                              Code:
                                                              [[[[[counter]]]]]
                                                                      name = Zähler Zustandswechsel Fenster
                                                                      type = num
                                                                      cache = yes
                                                                      sqlite = init # init with last db entry
                                                                      eval_trigger = EG.office.window.open
                                                                      eval = sh.EG.office.window.open.counter() + 1  if (int(value) == 1) else sh.EG.office.window.open.counter()
                                                              [[[[[state]]]]]
                                                                      name = Fensterstatus (0:closed, 1:open, 2:länger als t offen)
                                                                      type = num
                                                                      visu_acl = r
                                                                      autotimer = 1m = 2
                                                                      eval = int(value) if int(value) < 2 or sh.EG.office.window.open.state() == 1 else sh.EG.office.window.open.state()
                                                                      eval_trigger = EG.office.window.open
                                                              [[[[[warn]]]]]
                                                                      name = Fenster zu lange offen Warnung
                                                                      type = bool
                                                                      visu_acl = r
                                                                      eval = value == 2
                                                                      eval_trigger = EG.office.window.open.state

                              Und hier noch einmal die jeweiligen Zustände:

                              Geschlossenes Fenster:
                              Code:
                              EG.office.window.open.counter = 9.0
                              EG.office.window.open.state = 0
                              EG.office.window.open.warn = False
                              EG.office.window.open = False
                              Fenster offen < 1 Minute:
                              Code:
                              EG.office.window.open.counter = 10.0
                              EG.office.window.open.state = 1
                              EG.office.window.open.warn = False
                              EG.office.window.open = True
                              Fenster offen > 1 Minute:
                              Code:
                              EG.office.window.open.counter = 10.0
                              EG.office.window.open.state = 2
                              EG.office.window.open.warn = True
                              EG.office.window.open = True
                              Fenster nach >> 1 Minute geschlossen
                              Code:
                              EG.office.window.open.counter = 10.0
                              EG.office.window.open.state = 0
                              EG.office.window.open.warn = False
                              EG.office.window.open = False


                              Kommentar

                              Lädt...
                              X