Ankündigung

Einklappen
Keine Ankündigung bisher.

Stateengine Plugin Support

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

    Könntest Du mal
    - beschattung_se_state_suspend_nacht
    - beschattung_se_state_nacht
    posten?

    Ich möchte nachts oder während der Abwesenheit nur ein kurzes suspend fahren.
    Dabei übernehme ich den suspend state aus der plugin.yaml per se_use: stateengine.state_suspend.rules.suspend und muss beim Eintritt die se_suspend_time sichern und dann überschreiben, oder? Wie machst Du das?

    Kommentar


      se_state_nacht sieht inkl. Templates so aus:
      Code:
      beschattung_se_template_helligkeit:
          rules:
              se_template_nacht_max_helligkeit: eval:se_eval.get_relative_itemvalue('..settings.nacht.max_helligkeit') if se_eval.get_relative_itemvalue('..settings.beschattungstyp') == 'jalousien.eg' else se_eval.get_relative_itemvalue('{}.stateengine.settings.nacht.max_helligkeit'.format(se_eval.get_relative_itemvalue('..settings.beschattungstyp').replace('jalousien.kino', 'jalousien.og')))
              se_template_nacht_max_helligkeit_hysterese: eval:400 + (se_eval.get_relative_itemvalue('..settings.nacht.max_helligkeit') if se_eval.get_relative_itemvalue('..settings.beschattungstyp') == 'jalousien.eg' else  se_eval.get_relative_itemvalue('{}.stateengine.settings.nacht.max_helligkeit'.format(se_eval.get_relative_itemvalue('..settings.beschattungstyp').replace('jalousien.kino', 'jalousien.og'))))
              se_template_nacht_forced_max_helligkeit: eval:se_eval.get_relative_itemvalue('..settings.nacht.forced_max_helligkeit') if se_eval.get_relative_itemvalue('..settings.beschattungstyp') == 'jalousien.eg' else se_eval.get_relative_itemvalue('{}.stateengine.settings.nacht.forced_max_helligkeit'.format(se_eval.get_relative_itemvalue('..settings.beschattungstyp').replace('jalousien.kino', 'jalousien.og')))
              se_template_abend_max_helligkeit: eval:se_eval.get_relative_itemvalue('..settings.abend.max_helligkeit') if se_eval.get_relative_itemvalue('..settings.beschattungstyp') == 'jalousien.eg' else se_eval.get_relative_itemvalue('{}.stateengine.settings.abend.max_helligkeit'.format(se_eval.get_relative_itemvalue('..settings.beschattungstyp').replace('jalousien.kino', 'jalousien.og')))
              se_template_abend_max_helligkeit_hysterese: eval:400 + (se_eval.get_relative_itemvalue('..settings.abend.max_helligkeit') if se_eval.get_relative_itemvalue('..settings.beschattungstyp') == 'jalousien.eg' else  se_eval.get_relative_itemvalue('{}.stateengine.settings.abend.max_helligkeit'.format(se_eval.get_relative_itemvalue('..settings.beschattungstyp').replace('jalousien.kino', 'jalousien.og'))))
      
      beschattung_se_typ:
          settings:
              beschattungstyp:
                  type: str
                  cache: True
                  eval: >-
                    "screens" if sh..self.property.path.startswith(("screens", "markise")) else
                    "jalousien.kino" if (sh..self.property.path.split('.')[-4] in ["osten_wohnen", "osten_stiegenhaus", "sueden_stiegenhaus"]) else
                    "jalousien.og" if ("jalousien.og." in sh..self.property.path) else
                    "jalousien.eg" if ("jalousien.eg." in sh..self.property.path) else
                    "unknown"
                  enforce_updates: True
                  crontab: init = 'nothing'
      
      beschattung_se_state_nacht:
          settings:
              nacht:
                  hoehe:
                      type: num
                      visu_acl: rw
                      cache: True
                  lamellen:
                      type: num
                      visu_acl: rw
                      cache: True
                  aktiv:
                      type: bool
                      visu_acl: rw
                      cache: True
      
          rules:
              se_item_nacht_aktiv: ..settings.nacht.aktiv
              se_item_hoehe: ...hoehe
              se_item_lamellen: ...lamellen
              se_item_helligkeit: wetterstation.helligkeit.maximal
              se_template_nacht_start: eval:se_eval.get_relative_itemvalue('..settings.nacht.startzeit') if se_eval.get_relative_itemvalue('..settings.beschattungstyp') == 'jalousien.eg' else se_eval.get_relative_itemvalue('{}.stateengine.settings.nacht.startzeit'.format(se_eval.get_relative_itemvalue('..settings.beschattungstyp').replace('jalousien.kino', 'jalousien.og')))
              se_template_nacht_end: eval:se_eval.get_relative_itemvalue('..settings.nacht.endzeit') if se_eval.get_relative_itemvalue('..settings.beschattungstyp') == 'jalousien.eg' else se_eval.get_relative_itemvalue('{}.stateengine.settings.nacht.endzeit'.format(se_eval.get_relative_itemvalue('..settings.beschattungstyp').replace('jalousien.kino', 'jalousien.og')))
      
              nacht:
                  name: nacht
      
                  on_enter_or_stay:
                      se_action_hoehe:
                        - 'function: set'
                        - 'to: item:..settings.nacht.hoehe'
                        - 'order: 1'
                      se_action_lamellen:
                        - 'function: set'
                        - 'to: item:..settings.nacht.lamellen'
                        - 'order: 2'
      
                  enter:
                      se_max_helligkeit: template:nacht_max_helligkeit
                      se_value_nacht_aktiv: True
                      se_min_time: '09:00'
                      se_max_time: '16:00'
                      se_negate_time: True
      
                  enter_hysterese:
                      se_max_helligkeit: template:nacht_forced_max_helligkeit
                      se_value_laststate:
                        - var:current.state_id
                        - eval:se_eval.get_relative_itemid('..rules.suspend_nacht')
                      se_value_nacht_aktiv: True
                      se_min_time: '09:00'
                      se_max_time: '16:00'
                      se_negate_time: True
      
                  enter_zeit:
                      se_value_laststate:
                        - var:current.state_id
                        - eval:se_eval.get_relative_itemid('..rules.suspend_nacht')
                      se_value_nacht_aktiv: True
                      se_min_time: template:nacht_end
                      se_max_time: template:nacht_start
                      se_negate_time: True
      
          struct:
              - beschattung_se_typ
              - beschattung_se_template_helligkeit
      Das suspend_nacht ist hinsichtlich der Aktionen eine 1:1 Kopie aus dem suspend struct der plugin.yaml. Die Bedingungen sehen so aus:
      Code:
                  enter_manuell_nacht:
                      se_value_laststate: eval:se_eval.get_relative_itemid('..rules.nacht')
                      se_value_nacht_aktiv: True
                      se_min_time: '09:00'
                      se_max_time: '16:00'
                      se_negate_time: True
                      se_value_trigger_source: eval:se_eval.get_relative_itemid('..manuell')
                      se_value_suspend_active: True
                  enter_stay:
                      se_value_laststate: var:current.state_id
                      se_agemax_suspend: var:item.suspend_time
                      se_value_suspend: True
                      se_value_suspend_active: True

      Kommentar


        Ok, dann hast Du für suspend_nacht die gleiche Dauer wie das Standard suspend, oder?

        Kommentar


          Hab ich aktuell tatsächlich.. ich hab aber auch noch einen anderen Status, bei dem die "Suspend Zeit" weniger lang ist.. dieser wird eingenommen, wenn ich eine bestimmte Taste drücke und sieht dann so aus..

          Code:
          beschattung_se_state_taster:
              status:
                  taster:
                      type: bool
                      eval: or
                      crontab: init
                      eval_trigger:
                          - ....kz.taster
                          - ....lz.taster
          
                      start:
                          date_time:
                              type: str
                              visu_acl: ro
                              cache: True
          
                          unix_timestamp:
                              remark: Can be used for the clock.countdown widget
                              type: num
                              visu_acl: ro
                              eval: "0 if sh...date_time() in ['', ' '] else sh.tools.dt2ts(shtime.datetime_transform(sh...date_time())) * 1000"
                              eval_trigger: ..date_time
                              crontab: init
          
              settings:
                  taster:
                      aktiv:
                          type: bool
                          visu_acl: rw
                          cache: True
                          initial_value: True
          
                      dauer:
                          type: num
                          cache: True
                          initial_value: 10
          
                          duration_format:
                              type: str
                              visu_acl: ro
                              eval: "'{}h {}i 0s'.format(int(sh...()//60), round((sh...()%3600)%60))"
                              eval_trigger: ..
                              crontab: init
          
              rules:
                  se_item_taster_start: ..status.taster.start.date_time
                  se_item_taster_kz: ...kz.taster
                  se_item_taster_lz: ...lz.taster
          
                  taster:
                      name: taster
          
                      on_enter_or_stay:
                          se_action_retrigger:
                            - 'function: special'
                            - 'value: retrigger:..retrigger'
                            - 'delay: eval:se_eval.get_relative_itemvalue("..settings.taster.dauer") * 60 - se_eval.get_relative_itemproperty("..state_name", "last_change_age")'
                      on_enter:
                          se_action_taster_start:
                            - 'function: set'
                            - 'to: eval:str(shtime.now())'
          
                      on_leave:
                          se_action_taster_kz:
                            - 'function: set'
                            - 'to: False'
                          se_action_taster_lz:
                            - 'function: set'
                            - 'to: False'
                          se_action_taster_start:
                            - 'function: set'
                            - 'to:  '
                            - 'delay: 1'
          
                      enter_manuell:
                          se_value_trigger_source:
                            - eval:se_eval.get_relative_itemid('...kz.taster')
                            - eval:se_eval.get_relative_itemid('...lz.taster')
          
                      enter_stay:
                          se_value_laststate: var:current.state_id
                          se_max_age: eval:se_eval.get_relative_itemvalue('..settings.taster.dauer') * 60

          Im Übrigen ist der neue Release zum Testen bereit. Bin gespannt, was alles schiefgeht am besten machst du davor ein backup von deinem cache Verzeichnis. Ich hab jetzt ein Item suspendduration.seconds. Das befüllt das Nicht-seconds automatisch und umgekehrt.
          Ist aber sonst auch einiges geändert, da es doch noch ein paar Problemchen gab..
          https://github.com/onkelandy/plugins...ne/stateengine

          Kommentar


            Du könntest für unterschiedliche Suspendzeiten ja auch einfach die Variable se_suspend_time entsprechend befüllen. Dürfte eigentlich kein Problem sein..

            Kommentar


              Zitat von Onkelandy Beitrag anzeigen
              Das suspend_nacht ist hinsichtlich der Aktionen eine 1:1 Kopie aus dem suspend struct der plugin.yaml. Die Bedingungen sehen so aus:
              Ich wollte mit se_use: stateengine.state_suspend.rules.suspend nur den state übernehmen, was nicht funktioniert hat...
              hast du den code 1:1 aus der plugin.yaml kopiert oder benutzt du struct bzw. se_use?


              Kommentar


                Ich hab den Code aus dem plugin.yaml in ein struct kopiert und binde das ein. se_use schau ich mir bei Gelegenheit mal an, aber ich denke grad über eine Erweiterung des Suspend Zustands im plugin.yaml nach, damit man den auch zumindest 2 Mal mit unterschiedl. Dauer und versch. Conditions einfach nutzen kann.

                Kannst du dir bitte den aktuellsten Stand von meinem Repo ziehen und mal "generell" testen? Es gab noch einige Änderungen. Wichtig wäre, dass alles min. so gut läuft wie bisher

                Kommentar


                  gama - du versuchst offenbar mit se_use auf ein struct zuzugreifen, das geht natürlich nicht. Du müsstest dir ein struct mit den stateengine.state_x zusammenbauen und darauf fann referenzieren. Wobei ich denke, dass das Hauptitem nicht gleich wie das Plugin heißen sollte.. Ich bin aber zuversichtlich,dass ich was Einfacheres hinbekomme.

                  Kommentar


                    Ich habe gestern mal mit ein paar Ideen gespielt, alles noch nicht so prickelnd. Was ich jedenfalls machen werde, ist beim struct mehrere suspenddurations einstellen zu lassen. Und se_suspend_time wird dann immer mit einer passenden Durationsetting bestückt, abhängig von einem numerischen Wert in einem "suspendvariation" Item. Dieses würde also durch die anderen States, zB Nacht gesetzt werden. Das funktioniert soweit mal prima und ich denke mit nem einfachen Beispiel auch verständlich.

                    Probleme macht definitiv das se_use. Das hab ich nicht mehr getestet und da passt einiges nicht. Andererseits wäre es der richtige Ansatz, um einen eigenen Suspend State auf Basis des bestehenden zu erstellen.. structs sind hier leider zu unflexibel. Ich schau mir das nochmals an mit dem se_use.

                    Ein anderer Ansatz wäre, beim suspend Item einfach noch ein zusätzlich bool Item abzufragen (für jede "Variant" ein anderes). Auch das wäre einfach im struct zu lösen, ist aber glaub nicht sonderlich komfortabel. Denn dann bräuchte es einen Zustand "drüber", der zuerst den bool Wert setzt und anschließend in den darunter liegenden speziellen Suspend State wechselt.

                    Falls du gama eine generelle Idee hast, wie man die Funktionalität einfach und nutzerfreundlich bereitstellen könnte, lass es mich bitte wissen.

                    Kommentar


                      Ideen hätte ich schon, sind aber an objektorientierte Programmierung angelehnt, die mit einfachen structs nicht funktionieren - deshalb dachte ich, dass se_use vielleicht eine Alternative ist. Ich denke, die Einfachheit wird im aktuellen Status Quo so erreicht, dass man möglichst viele fertige structs von states im plugin.yaml hat. Und ein zweiter, anpassbarer suspend ist sicher nicht verkehrt.

                      Ich habe zwei States, bei denen ein bestehender suspend aufgelöst werden soll: ASLEEP (Nacht) und COOLING_AWAY. Cooling Away macht dicht, wenn es zu warm und niemand mehr im Haus ist. FREE ist der Default Status (es wird weder Position noch Winkel gestellt) und kann nicht per stetting deaktiviert werden.

                      Denkbar wären noch UNLOCKED_WINDOW, sollte z.B. ein Fenster geöffnet werden, fährt der Rolladen hoch (z.B. Brand), sofern man das nicht direkt am Aktor mit einer Fahrbegrenzung löst.

                      Somit wäre meine State Reihenfolge:

                      lock:
                      suspend_v1:
                      ASLEEP:
                      UNLOCKED_WINDOW:
                      COOLING_AWAY
                      suspend:
                      PRIVACY
                      COOLING
                      OPEN:
                      FREE:

                      Kommentar


                        gama Ich hab nun ein großes Update zum Plugin am Start, kannst du es bitte testen? Am besten den Branch runterladen und den stateengine Ordner ersetzen (gerne zuvor Backup ) https://github.com/onkelandy/plugins...ne/stateengine

                        Die wichtigste Neuerung für se_use: Structs lassen sich nun über struct:stateengine.state_lock.rules.lock einbinden. Auch eigene! Außerdem kann man nun auch Listen angeben, evals, Items, etc. Wenn man se_use mit eval nutzt, wird der State zur Laufzeit vor dem Check neu generiert. Dadurch wäre ne ganze Menge möglich. Und das se_name Attribut wird nun auch etwas optimierter eingebunden (hoffe ich).

                        Allerdings muss ich gestehen, fehlt mir die Idee, wie man nun am einfachsten einen guten suspend State hinbekommt, der durch einen anderen State "aufgelöst" wird und dann aber wieder aktiv wird. Meine ursprüngliche Vision wäre gewesen, dass man Dank dynamischem se_use einfach immer state_suspend nutzen kann und die restlichen Bedingungen kommen dann zur Laufzeit vom vorigen Zustand (zB Nacht) dazu. Aber da ja alle Aktionen auch übernommen werden, ist es kein suspend mehr. Das se_use sorgt ja für einen "gesamten Merge" beider Stati. Hoffe, du konntest folgen

                        Man müsste also so oder so einen eigenen suspend_nacht Zustand erstellen. Dort dann mit se_use den suspend einbinden. Allerdings müssen dann alle Bedingungssets gleich heißen wie im struct, damit's gemergt wird. Irgendwie ne Sackgasse - aber du hattest oben von Ideen geredet... bitte gerne

                        Kommentar


                          Das Update sehe ich mir gerne an. Danke schon einmal für die Umsetzung!

                          Eigentlich bräuchte man klassische Objekte für unser Vorhaben. Gerfühlt kommt man mit se_use und structs sehr schnell an die Grenzen - insbesondre wenn es einfach bleiben soll. Ich glaube mittlerweile, es ist am einfachsten wenn man den code der structs aus plugin.yaml in einen eigenen struct kopiert, sofern es (wie z.B. mit zwei Suspend Modi) komplexer wird. Oder man legt einfach einen von Haus aus weiteren struct im plugin.yaml an, der über 2 suspend States verfügt.

                          Kommentar


                            hi gama Das Update hat es in den neuen 1.8 Release geschafft. Hab für se_use noch ne Optimierung für den develop am Start, aber generell sollte es passen.
                            Deinen Vorschlag hatte ich sogar schon umgesetzt. Die Structs sind nun als eigene Objekte angelegt und man kann beliebig drauf zugreifen. Aktuell wird es halt von se_use nur für States unterstützt, aber das ließe sich ja ändern. Aber ich sehe noch nicht ganz, wie das die Sache nun einfacher macht - vielleicht du ?

                            Du kannst dir's ja mal ansehen. Der Suspendmodus hat nun ein paar neue Items im Struct und passt sich dynamisch an, wenn nötig. Aber auch das überzeugt mich noch nicht ganz

                            Kommentar


                              Für 1.8.1 wird der suspend Modus wieder normal wie vorher.. Die manipulierte Variante bleibt aber als state_suspend_dynamic als Struct erhalten. Ich dreh mich grad massiv im Kreis. Weder Sub-Structs, noch se_use helfen irgendwie, einfach einen vernünftigen zweiten Suspend-State zu konfigurieren. Kommt sicher auch drauf an, was man genau möchte. Das Sinnvollste schiene mir, man definiert den suspend ganz oben (unter lock und release) und kann festlegen, welche States den Suspend auflösen können. z.B. durch ein Attribut "se_releasedby" und Angabe der State IDs...?

                              Kommentar


                                Mit dem Auflösen geht es weiter. In meinem Fall, löse ich den Suspend dadurch auf, indem ich lock aktiviere und gleich wieder deaktiviere. Das hat den Vorteil, dass ich nur einen Taster auf dem MDT Schalter belegen muss, aber zwei Funktionen mittels dem "Doppelklick Sperren/Entsperren" auslösen kann. Ich glaube, dass wenn es über eine Standardanwendung hinaus geht, man einen eigenen, vollen struct anlegen muss.

                                Kommentar

                                Lädt...
                                X