Ankündigung

Einklappen
Keine Ankündigung bisher.

Rule für Präsenzsteuerung

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

    [Codebeispiel] Rule für Präsenzsteuerung

    Hallo Forum,
    ich habe mir eine Präsenzsteuerung über zwei Handys gebastelt. Wobei ich über zwei bash.Scripte bei Anwesenheit die Ausgabe ON, und bei Abwesenheit OFF bekomme.

    Nun habe ich zwei Rules erstellt die jeweils bei Anunft auslöst zb:

    Code:
    rule "Frank ist Zuhause"
       when
          Item IphoneBt_Output changed to ON
       then
          sendCommand(PSSLichtAmSchrankWohnzimmer_Switch, ON)
    end
    Das läuft auch soweit. Allerdings muss ich beide Auslöser verknüpfen damit ein Handy nicht schon die Aktion auslöst, sondern erst wenn beide nicht mehr da sind. Hierzu habe ich folgende Rule gebaut :

    Code:
    rule "Frank ist nicht Zuhause"
       when
          Item IphoneBt_Output changed to OFF or
          Item S3Wlan_Output changed to OFF
       then
          if ( IphoneBt_Output.state == OFF && S3Wlan_Output.state == OFF ) {
                sendCommand(PSSLichtAmSchrankWohnzimmer_Switch, OFF)
          }
    end
    Im log find ich noch eine Meldung, dass die Items auslösen, jedoch wird der Switch nicht geschaltet:

    Code:
    2017-11-15 10:58:52.890 [ItemStateChangedEvent     ] - S3Wlan_Output changed from ON to OFF
    Vielleicht hätte jemand einen Tipp ?

    Gruß
    Frank

    #2
    Zum suchen des Fehlers könntest Du ein wenig loggen. Die Rule an sich sieht eigentlich gut aus. Es bietet sich an, die Funktionen in einer Rule zusammenzufassen.
    Code:
    rule "Handy Präsenz"
    when
        Item IphoneBt changed or
        Item S3Wlan_Output changed
    then
        logInfo("praesenz","IphoneBt: {} S3Wlan_Output: {}",IphoneBt.state,S3Wlan_Output.state)
        logInfo("praesenz","PSSLichtA mSchrankWohnzimmer_Switch: {}",PSSLichtAmSchrankWohnzimmer_Switch.state)
        if(IphoneBt.state != ON && S3Wlan_Output.state != ON)
            if(PSSLichtAmSchrankWohnzimmer_Switch.state != OFF)
                PSSLichtAmSchrankWohnzimmer_Switch.sendCommand(OFF)
        else
            if(PSSLichtAmSchrankWohnzimmer_Switch.state != ON)
                PSSLichtAmSchrankWohnzimmer_Switch.sendCommand(ON)
    end
    Im Ergebnis triggert die Rule jedesmal, wenn sich der Zustand eines der Handies ändert. Es werden zwei Logzeilen in openhab.log erzeugt, mit Datum&Uhrzeit und dem Zustand der drei beteiligten Items.
    Falls beide Telefone nicht im Status ON sind, wird der Zustand vom Licht überprüft und wenn nötig auf OFF geändert.
    Falls mindestens eines der Telefone im Zustand ON ist, wird der Zustand vom Licht überprüft und wenn nötig auf ON geändert.

    Die zusätzliche Abfrage verhindert unnötige Schaltvorgänge. Wenn das keine Rolle spielt, reduziert sich der "aktive" Teil der Rule auf eine Zeile:
    Code:
    PSSLichtAmSchrankWohnzimmer_Switch.sendCommand(if(IphoneBt.state != ON && S3Wlan_Output.state != ON) OFF else ON)
    Warum habe ich die Logik umgedreht? Es gibt noch den Zustand NULL, falls ein Item nicht initialisiert ist. Indem ich die Logik umdrehe, vermeide ich also, dass die Rule in bestimmten Situationen nicht funktioniert wie erwartet.

    Wann immer möglich, sollte man die Action vermeiden und stattdessen die Methode verwenden. Das wird auch in der offiziellen Dokumentation erklärt.

    Kommentar


      #3
      Meine Rule schaut nun so aus :

      Code:
      rule "Frank ist nicht Zuhause"
      when
          Item IphoneBt_Output changed or
          Item S3Wlan_Output changed
      then
          logInfo("praesenz","IphoneBt_Output: {} S3Wlan_Output: {}",IphoneBt_Output.state,S3Wlan_Output.state)
          logInfo("praesenz","PSSLichtAmSchrankWohnzimmer_Switch: {}",PSSLichtAmSchrankWohnzimmer_Switch.state)
          PSSLichtAmSchrankWohnzimmer_Switch.sendCommand(if(IphoneBt_Output.state != ON && S3Wlan_Output.state != ON) OFF else ON)
      end
      Jedoch läuft sie noch nicht. Log:

      Code:
      ==> /var/log/openhab2/events.log <==
      2017-11-15 21:02:12.377 [ItemStateChangedEvent     ] - IphoneBt_Output changed from ON to OFF
      
      ==> /var/log/openhab2/openhab.log <==
      2017-11-15 21:02:13.351 [INFO ] [ipse.smarthome.model.script.praesenz] - IphoneBt_Output: OFF S3Wlan_Output: OFF
      2017-11-15 21:02:13.355 [INFO ] [ipse.smarthome.model.script.praesenz] - PSSLichtAmSchrankWohnzimmer_Switch: OFF
      
      ==> /var/log/openhab2/events.log <==
      2017-11-15 21:02:13.378 [ItemCommandEvent          ] - Item 'PSSLichtAmSchrankWohnzimmer_Switch' received command OFF
      2017-11-15 21:02:37.871 [ItemStateChangedEvent     ] - IphoneBt_Output changed from OFF to ON
      
      ==> /var/log/openhab2/openhab.log <==
      2017-11-15 21:02:37.889 [INFO ] [ipse.smarthome.model.script.praesenz] - IphoneBt_Output: ON S3Wlan_Output: OFF
      2017-11-15 21:02:37.900 [INFO ] [ipse.smarthome.model.script.praesenz] - PSSLichtAmSchrankWohnzimmer_Switch: OFF
      
      ==> /var/log/openhab2/events.log <==
      2017-11-15 21:02:37.954 [ItemCommandEvent          ] - Item 'PSSLichtAmSchrankWohnzimmer_Switch' received command OFF

      Kann ich nicht verstehen, sollte doch laufen oder ?

      Kommentar


        #4
        Der Einzeiler ist ja schön und gut, aber ich finde ihn unübersichtlich und fehlerträchtig.... Und es macht das Debuggen nicht einfacher...

        Andreas

        Kommentar


          #5
          Wie sind denn die Items IphoneBt und S3Wlan_Output definiert?

          Kommentar


            #6
            Also ich habe zwei Bash-Scripts bei denen ich zwei Ausgaben erhalte entweder "ON" oder "OFF" Für die Bluetooth Abfrage:

            Code:
            #!/bin/bash
            #1=Frank, 2=Tina
            case $1 in
                       1) MAC="48:4B:AA:97:63:EC" ;;
                       2) MAC="11:22:33:44:55:66" ;;
            esac
            if sudo /usr/bin/l2ping -c 1 48:4B:xx:xx:xx:xx &> /dev/null
               then
                  echo "ON"
               else
                  echo "OFF"
            fi
            Und für die Wlan Abfrage:

            Code:
            #!/bin/bash
            
            if [ -z "192.168.11.7" ] ;then
                echo "So nicht"
                exit 1;
            fi
            
            ping -c1 192.168.11.x > /dev/null
            if [ $? -ne 0 ]; then
                    echo "OFF"
            else
                    echo "ON"
            fi
            Dann habe ich in der PaperUI über das Exec-Binding zwei Things erstellt, die jeweils ein Bash Script ausfürt, und dann zwei Items über den Output.

            Damit kann ich bei beiden Items die Werte ON und OFF nutzen, jedoch die Verknüpfung geht nicht.

            Kommentar


              #7
              Ich könnte es jetzt auf die Spitze treiben und meine Frage wörtlich wiederholen Aber ich formuliere es nochmal exakt:
              Wie sind denn die Items IphoneBt und S3Wlan_Output in der items-Datei definiert? Genauer: Sind die Items vielleicht String Items?

              Kommentar


                #8
                Hm ja, ...leider ja
                Es sollte wohl so aussehen oder ?
                Code:
                Switch IphoneBt "Handy Frank" { exec="<[frank.sh 1:60000:REGEX((.*?))]" }
                Switch S3Wlan "Handy Jutta" { exec="<[jutta.sh 2:60000:REGEX((.*?))]"
                läuft nur leider nicht ......

                Kommentar


                  #9
                  Nein, exec lässt sich nur mit String Items richtig verbinden (dazu gibt einen Issue auf github), allerdings nur in openHAB2. Egal.
                  Jedenfalls musst Du logischerweise dann mit Strings arbeiten:
                  Code:
                  rule "Handy Präsenz"
                  when
                      Item IphoneBt changed or
                      Item S3Wlan_Output changed
                  then
                      logInfo("praesenz","IphoneBt: {} S3Wlan_Output: {}",IphoneBt.state,S3Wlan_Output.state)
                      logInfo("praesenz","PSSLichtA mSchrankWohnzimmer_Switch: {}",PSSLichtAmSchrankWohnzimmer_Switch.state)
                      if(IphoneBt.state[COLOR=#FF0000].toString[/COLOR] != [COLOR=#FF0000]"[/COLOR]ON[COLOR=#FF0000]"[/COLOR] && S3Wlan_Output.state[COLOR=#FF0000].toString[/COLOR] != [COLOR=#FF0000]"[/COLOR]ON[COLOR=#FF0000]"[/COLOR])
                          if(PSSLichtAmSchrankWohnzimmer_Switch.state != OFF)
                              PSSLichtAmSchrankWohnzimmer_Switch.sendCommand(OFF)
                      else
                          if(PSSLichtAmSchrankWohnzimmer_Switch.state != ON)
                              PSSLichtAmSchrankWohnzimmer_Switch.sendCommand(ON)
                  end
                  vermutlich ist das .toString in diesem Fall nicht unbedingt nötig.
                  Nochmal die Alternative für unübersichtlichen, dafür aber kompakten
                  Code:
                  PSSLichtAmSchrankWohnzimmer_Switch.sendCommand(if(IphoneBt.state[COLOR=#FF0000].toString[/COLOR] != [COLOR=#FF0000]"[/COLOR]ON[COLOR=#FF0000]"[/COLOR] && S3Wlan_Output.state[COLOR=#FF0000].toString[/COLOR] != [COLOR=#FF0000]"[/COLOR]ON[COLOR=#FF0000]"[/COLOR]) OFF else ON)
                  Zuletzt geändert von udo1toni; 16.11.2017, 22:03.

                  Kommentar


                    #10
                    Genau das war es, vielen Dank für deine Hilfe

                    Kommentar

                    Lädt...
                    X