Ankündigung

Einklappen
Keine Ankündigung bisher.

State machine mit Item-Definitionen

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

    State machine mit Item-Definitionen

    Hallo,

    ich habe mir jüngst überlegt, wie man Abläufe in SmarthomeNG mit State Machines handhaben könnte. Konkret geht es um die Realisierung einer Alarmanlage entsprechend dem beigefügten Diagramm.

    StateMachine.png

    Nach ein paar Irrwegen ist es mir jetzt weitestgehend gelungen. Möglich sind auch hierarchische Zustände und Nebenläufigkeit.

    Der untere Code ist zwar etwas üppig geworden, aber man sieht dann den vollständigen Aufbau des Automaten.

    Vielleicht hilft er ja dem einen oder anderen für eigene Projekte...

    Grüße Thorsten

    P.S.: Die KNX-Kommunikation habe ich der Übersicht halber gelöscht.


    Code:
    alarm:
        signal:
        state:
            type: num
            initial_value: 1
            on_update:
    
            state1: # alarm system off
                ev1:
                    type: bool
                    knx_dpt: 1
                    knx_listen: 0/3/32
                    on_update:
                      - (sh....(2)) if (sh....() == 1) else None
            state2: # alarm system on
            state21: # alarm system on
                type: num # state of this substate
    
                autocond:
                    type: num
                autonext:
                    type: num
                    on_update: sh...autocond(sh...())
                autodelay:
                    type: num
                    on_update: sh...(sh...autonext()) if ((value == -1) and (sh...() == sh...autocond())) else None
                    autotimer: sh...autodelay() = -1 = latest
    
                entry:
                    type: num
                    eval_trigger: ...
                    eval: value
                    on_update: # lal
                      - (sh...(211)) if (sh....() == 2) else (sh...(0))
                state211: # alarm system preparation
                    ev1:
                        type: num
                        eval_trigger: ...
                        eval: value
                        on_update:
                          - (sh....autonext(212),sh....autodelay(15)) if (sh....() == 211) else None
                state212: # alarm system armed
                    ev1:
                        type: num
                        eval_trigger:
                          - alarm.event_ug
                          - alarm.event_eg
                        eval: value
                        on_update:
                          - sh....(213) if (sh....() == 212) else None
                    ev2:
                        type: num
                        eval_trigger: alarm.event_og
                        eval: value
                        on_update:
                          - sh....(215) if (sh....() == 212) else None
                state213: # alarm system prealarm
                    ev1:
                        type: num
                        eval_trigger: ...
                        eval: value
                        on_update:
                          - (sh....autonext(214),sh....autodelay(30)) if (sh....() == 213) else None
                state214: # alarm system ealarm
                    ev1:
                        type: num
                        eval_trigger: ...
                        eval: value
                        on_update:
                          - (sh.alarm.signal.state(2)) if (sh....() == 214) else None
                state215: # alarm system ealarm
                    ev1:
                        type: num
                        eval_trigger: ...
                        eval: value
                        on_update:
                          - (sh....autonext(212),sh....autodelay(20)) if (sh....() == 215) else None
                    ev2:
                        type: num
                        eval_trigger: alarm.event
                        eval: value
                        on_update:
                          - sh.....(2) if (sh....() == 215) else None
            state22: # alarm system on
                type: num
    
                entry:
                    type: num
                    eval_trigger: ...
                    eval: value
                    on_update:
                      - (sh...(221)) if (sh....() == 2) else (sh...(0))
                state221:
                    ev1:
                        type: bool
                        knx_dpt: 1
                        knx_listen: 0/3/32
                        on_update:
                          - sh....(222) if (sh....() == 221) else None
                state222:
                    type: num
    
                    entry:
                        type: num
                        eval_trigger: ...
                        eval: value
                        on_update:
                          - (sh...(2221)) if (sh....() == 222) else (sh...(0))
    
                    state2221: # step 1
                        ev1:
                            type: bool
                            knx_dpt: 1
                            knx_listen: 0/3/31
                            on_update:
                              - sh....(2222) if (sh....() == 2221) else None
                        ev2:
                            type: bool
                            knx_dpt: 1
                            knx_listen: 0/3/32
                            on_update:
                              - sh.....(221) if (sh....() == 2221) else None
    
                    state2222: # step 2
                        ev1:
                            type: num
                            knx_dpt: 1
                            knx_listen: 0/3/32
                            on_update:
                              - sh......(1) if (sh....() == 2222) else None
                        ev2:
                            type: num
                            knx_dpt: 1
                            knx_listen: 0/3/31
                            on_update:
                              - sh......(2) if (sh....() == 2222) else None


    Angehängte Dateien

    #2
    Du weißt aber schon, dass es dafür ein mächtiges Plugin gibt https://github.com/i-am-offline/smar.../Version_1.4.0

    Kommentar


      #3
      Wusste ich noch nicht. Grundsätzlich fände ich es gut mehr Automaten-Theorie in den SmarthomeNG-Standardumfang zu bringen. Auch das mit den Zeitfunktionen finde ich schon mal sehr gut.

      Bist du der Autor des Plugin? Kannst du ein Minimalbeispiel geben, wie man aus einem Zustand A in Zustand B kommt, falls Bedingung x erfüllt ist bzw. in Zustand C, falls Bedingung y erfüllt ist? Danke!

      Kommentar


        #4
        Hi,

        die Doku mit Beispielen findest Du hier: https://github.com/i-am-offline/smar...autoblind/wiki

        Gruß, Waldemar
        OpenKNX www.openknx.de

        Kommentar


          #5
          Der Autor hat sich leider zurück gezogen. Ich hab hier einen Blogeintrag erstellt:
          https://www.smarthomeng.de/starting-...toblind-plugin

          Wird irgendwann mal erweitert.

          Kommentar


            #6
            Zitat von zittho Beitrag anzeigen
            Hallo,

            ich habe mir jüngst überlegt, wie man Abläufe in SmarthomeNG mit State Machines handhaben könnte. Konkret geht es um die Realisierung einer Alarmanlage entsprechend dem beigefügten Diagramm.

            ... Grundsätzlich fände ich es gut mehr Automaten-Theorie in den SmarthomeNG-Standardumfang zu bringen. ...
            Hallo zittho,
            interessanter Ansatz. Aber vielleicht geht es anschaulicher mit einem Plugin:
            vielleicht willst Du Dir mal dies ansehen. Mein Ansatz eines Plugins für finite Automaten unter Verwendung des gebräuchlichen Modells mit states, events und transitions, die mit durch Items und Attributen implementiert werden. Inkl. Backend WebIF.
            Der Status: "works for me" / "ungetestet", aber ich finds wesentlich nachvollziehbarer, als das "mächtige" Plugin.

            Eine Alramanlage könnte damit so aussehen:
            FSM_Alarm.PNG

            Kommentar


              #7
              walldi Da autoblind zwar funktioniert, aber nicht mehr entwickelt wird und va. dein WebIF sehr spannend aussieht, würd ich mir das gerne mal ansehen.
              Kurze Info, hier fehlt das Bild: https://git.wallmeier.info/dirk/plug...ind_example.md
              Auf das CD Player Example kommt man auch nur mit Login?

              Meine erste Frage... wie handhabt dein Plugin manuelle Betätigungen, also "Pausen" der Automatisierung? Da ist beim autoblind Plugin genau zu spezifizieren, welche KNX GA ignoriert werden können/sollen/müssen. Ohne diese Funktion hat das "suspend" nie funktioniert..

              Kommentar


                #8
                Irgendwie kann ich mich mit AutoBlind nicht anfreunden. Wirkt etwas überkompliziert bzw. ist zu wenig auf Automaten zugeschnitten. Mich irritieren manche Besonderheiten, etwa dass eindeutige Items nochmals mit as_item_ referenziert werden.

                Ich frage mich auch, ob man wirklich ein Plugin braucht. Mein obiges Beispiel ist vor allem deshalb etwas aufgebläht, weil Hierarchien und Nebenläufigkeit implementiert sind. Für flache endliche Automaten wird es deutlich übersichtlicher.

                Kommentar


                  #9
                  Prinzipiell ist es eh gut, wenn es verschiedene Ansätze gibt.. man nimmt sich dann das, was besser passt.

                  Vieles aus dem autoblind Plugin ist wohl inzwischen tatsächlich mit Boardmitteln umsetzbar, zB relative Items. Der Ansatz von walldi, alles mit evals zu lösen, ist auch sehr übersichtlich und definitiv schlüssiger. Vielleicht kann man ja auch ein paar Ideen vom autoblind Plugin einfließen lassen...va. in den Ansatz von walldi, der schön übersichtlich scheint.

                  Kommentar


                    #10
                    Zitat von Onkelandy Beitrag anzeigen
                    walldi....
                    Meine erste Frage... wie handhabt dein Plugin manuelle Betätigungen, also "Pausen" der Automatisierung? Da ist beim autoblind Plugin genau zu spezifizieren, welche KNX GA ignoriert werden können/sollen/müssen. Ohne diese Funktion hat das "suspend" nie funktioniert..
                    Ich würde sagen, "manuell" ist ein State neben "automatik". Die Events, die in/aus den States führen, werden von den entspr Items getriggert.

                    Kommentar


                      #11
                      Zitat von zittho Beitrag anzeigen
                      .. . Mein obiges Beispiel ist vor allem deshalb etwas aufgebläht, weil Hierarchien und Nebenläufigkeit implementiert sind. Für flache endliche Automaten wird es deutlich übersichtlicher.
                      Dann will ich am Wochenende mal hierarchische FSM einbauen, die im OpenStack Automaton bereits vorgesehen ist.
                      Wenn ich damit deine Alarmanlage nachbilden, sehen wir, ob das noch Übersicht bleibt.

                      Kommentar


                        #12
                        Zitat von walldi Beitrag anzeigen

                        Dann will ich am Wochenende mal hierarchische FSM einbauen, die im OpenStack Automaton bereits vorgesehen ist.
                        Wenn ich damit deine Alarmanlage nachbilden, sehen wir, ob das noch Übersicht bleibt.
                        Das wäre eine prima Sache. Ich vermute, dass Nebenläufigkeit dann einfach durch zwei getrennte aber auf gleicher Ebene definierte FSM realisiert werden kann?

                        Kommentar


                          #13
                          walldi Könntest bitte die Metadaten im plugin.yaml komplettieren? Danke!

                          Mit welcher shng und Python Version arbeitest du denn?
                          Ich musste fürs WebIF das pydot via pip3 installieren - da gab es aber mehrere Fehlermeldungen, ist wohl nicht für Python3 gedacht?
                          graphviz musste ich via apt-get install installieren.

                          Nach manuellem Ändern der pydot startet nun das Plugin, ich bekomme die Info bezüglich "SmartFSM Instance:.."
                          Danach ist aber aus, es scheint also kein run ausgeführt zu werden...
                          Zuletzt geändert von Onkelandy; 29.09.2018, 23:56.

                          Kommentar


                            #14
                            Hallo Onkelandy ,
                            danke für das Interesse. Ich werde heute abend diverse Änderungen hochladen, die für hierarchische FSM notwendig sind.
                            Ich arbeite auf/für einem venv mit Python3.4 (auf einem bananapi):
                            Code:
                            (pyenv) smarthome@smarthome:/opt/smarthome_1.5dev$ sudo apt install graphviz
                            [sudo] password for smarthome:
                            Paketlisten werden gelesen... Fertig
                            Abhängigkeitsbaum wird aufgebaut.
                            Statusinformationen werden eingelesen.... Fertig
                            [MARKIEREN]graphviz ist schon die neueste Version[/MARKIEREN]
                            
                            (pyenv) smarthome@smarthome:/opt/smarthome_1.5dev$ python
                            [MARKIEREN]Python 3.4.2[/MARKIEREN] (default, Oct  8 2014, 14:38:51)
                            [GCC 4.9.1] on linux
                            Type "help", "copyright", "credits" or "license" for more information.
                            ...
                            
                            (pyenv) smarthome@smarthome:/opt/smarthome_1.5dev$ pip install pydot
                            [MARKIEREN]Requirement already satisfied: pydot in ./pyenv/lib/python3.4/site-packages (1.2.4)[/MARKIEREN]
                            Requirement already satisfied: pyparsing>=2.1.4 in ./pyenv/lib/python3.4/site-packages (from pydot) (2.2.0)
                            graphviz wurde ursprünglich nicht mit pip installiert:
                            Code:
                            (pyenv) smarthome@smarthome:/opt/smarthome_1.5dev$ pip install graphviz
                            Collecting graphviz
                              Downloading https://files.pythonhosted.org/packages/47/87/313cd4ea4f75472826acb74c57f94fc83e04ba93e4ccf35656f6b7f502e2/graphviz-0.9-py2.py3-none-any.whl
                            Installing collected packages: graphviz
                            Successfully installed graphviz-0.9
                            Zuletzt geändert von walldi; 30.09.2018, 15:00.

                            Kommentar


                              #15
                              Hi walldi! Soll graphviz mit apt-get oder pip3 installiert werden oder ist es quasi egal..? Ich werde es dann noch auf dem Raspi testen, auf dem Mac bin ich jedenfalls leider gescheitert, aber schau ich mir auch nochmals an. Welche pydot Version hast du denn?

                              Kommentar

                              Lädt...
                              X