Ankündigung

Einklappen
Keine Ankündigung bisher.

Rule: Licht an bei Anruf

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

    Rule: Licht an bei Anruf

    Hallo,

    ich baue mir gerade ein Rule zusammen, die mir das Licht an und wieder ausschaltet (3x) wenn wir einen Anruf bekommen.
    Das ganze funktioniert auch soweit, allerdings was mir nicht gefällt ist, dass am Schluss das Licht immer ausgeschaltet wird.
    Wie kann ich mir den den vorherigen Wert in einer Rule merken? Am Ende soll das Licht quasi blinken aber wenn es zuvor angeschalten war soll es das auch nach der Anrufnotifikation bleiben.

    Aktuell sieht die Rule so aus:

    Code:
    rule "Anruf"
    when
       Item FritzBox_Ringing changed to ON
    then
       logInfo("Anruf.rules", "Anruf erkannt")
       if(TV_Wohnzimmer_Power.state == ON)
       {
           logInfo("Anruf.rules", "Wohnzimmer TV ist angeschaltet -> Ton wird ausgeschaltet")
           sendCommand(TV_Wohnzimmer_Mute, ON)
       }
       if(TelefonBlinken.state == ON && (FritzBox_Handy_One.state == OPEN || FritzBox_Handy_Two.state == OPEN)
       {[INDENT]if((now.getHourOfDay >= 7 || now.getHourOfDay <= 22))
    {
    EG_Kueche_Deckenspots.sendCommand(ON)
    EG_Esszimmer_Deckenspots.sendCommand(ON)
    EG_Wohnzimmer_Deckenspots.sendCommand(ON)
    
    createTimer(now.plusSeconds(2)) [| sendCommand(EG_Kueche_Deckenspots, OFF) ]
    createTimer(now.plusSeconds(2)) [| sendCommand(EG_Esszimmer_Deckenspots, OFF) ]
    createTimer(now.plusSeconds(2)) [| sendCommand(EG_Wohnzimmer_Deckenspots, OFF) ]
    
    createTimer(now.plusSeconds(4)) [| sendCommand(EG_Kueche_Deckenspots, ON) ]
    createTimer(now.plusSeconds(4)) [| sendCommand(EG_Esszimmer_Deckenspots, ON) ]
    createTimer(now.plusSeconds(4)) [| sendCommand(EG_Wohnzimmer_Deckenspots, ON) ]
    
    createTimer(now.plusSeconds(6)) [| sendCommand(EG_Kueche_Deckenspots, OFF) ]
    createTimer(now.plusSeconds(6)) [| sendCommand(EG_Esszimmer_Deckenspots, OFF) ]
    createTimer(now.plusSeconds(6)) [| sendCommand(EG_Wohnzimmer_Deckenspots, OFF) ]
    
    createTimer(now.plusSeconds(8)) [| sendCommand(EG_Kueche_Deckenspots, ON) ]
    createTimer(now.plusSeconds(8)) [| sendCommand(EG_Esszimmer_Deckenspots, ON) ]
    createTimer(now.plusSeconds(8)) [| sendCommand(EG_Wohnzimmer_Deckenspots, ON) ]
    
    createTimer(now.plusSeconds(10)) [| sendCommand(EG_Kueche_Deckenspots, OFF) ]
    createTimer(now.plusSeconds(10)) [| sendCommand(EG_Esszimmer_Deckenspots, OFF) ]
    createTimer(now.plusSeconds(10)) [| sendCommand(EG_Wohnzimmer_Deckenspots, OFF) ]
    }[/INDENT]
         }
    end
    Gibt es eine schönere Art das Licht an und wieder auszuschalten als den gleichen Code 6x zu schreiben?

    Vielen Dank
    Marcus

    #2
    Wenn du in eine IF Schleife Schaust welches Licht an ist so kannst du dann dir den Status holen.

    nutzt du einach eine Variable mit einer Zahl dann kannst du eine Schleife bauen die sich so oft wiederholt wie du möchtest.

    MfG

    Kommentar


      #3
      Aber hallo kann man das schöner machen

      Das erste wäre mal, die Items, die blinken sollen, in einer Gruppe zusammenzufassen, z.B. Group:Switch gTelBlink und dann nur diese Gruppe zu switchen. Weiterhin hat Sefina ja schon vorgeschlagen, einen Zähler zu verwenden. z.B. so:
      Code:
      var Timer tBlinken = null
      
      rule "Anruf"
      when
          Item FritzBox_Ringing changed to ON
      then
          logInfo("Anruf.rules", "Anruf erkannt")
          if(TV_Wohnzimmer_Power.state == ON) {
              logInfo("Anruf.rules", "Wohnzimmer TV ist angeschaltet -> Ton wird ausgeschaltet")
              TV_Wohnzimmer_Mute.sendCommand(ON)
          }
          if(TelefonBlinken.state == ON && (FritzBox_Handy_One.state == OPEN || FritzBox_Handy_Two.state == OPEN))
              if(now.getHourOfDay >= 7 || now.getHourOfDay <= 22)
                  if(tBlinken === null) {
                      var int loop = 6
                      tBlinken = createTimer(now, [  //der erste Durchlauf geschieht sofort
                          loop = loop - 1
                          gTelBlink.sendCommand(if(loop % 2 == 1) ON else OFF) //abwechselnd ON und OFF
                          if (loop > 0)
                              tBlinken.reschedule(now.plusSeconds(2)) //jeder weitere Durchlauf wird um 2 Sekunden verzögert
                          else
                              tBlinken = null //zuletzt Timer für nächsten Anruf initialisieren
                      ])
                  }
      end
      Eventuell möchtest Du auch, dass die Leuchten ihren Zustand vor dem Klingeln wieder einnehmen. Dann wäre eine Persistenz ein eleganter Weg (über die Gruppe kannst Du dann mit einer Zeile den alten Zustand wieder erreichen:
      Code:
      gTelBlink.members.forEach[i|i.sendCommand(i.historicState(now.minusSeconds(12)).state)]
      Das müsste dann in den else-Teil (mit tBlinken = null in {} gesetzt)
      Zuletzt geändert von udo1toni; 31.12.2017, 00:18.

      Kommentar


        #4
        Hallo,

        vielen Dank an euch beide.
        Ich bin gerade erst dabei mich mit den Rules und der dazugehörigen Sprache/Syntax auseinander zu setzen, sehe schon, da kann ich noch viel lernen.

        Udo, deine Rule funktioniert soweit ganz gut, das einzige was noch nicht klappt ist das setzen des alten Zustandes.
        Ich bekomme im Visual Studio Code - Editor auch die Meldung "Type mismatch: cannot convert from State to String".
        Wie bekomme ich denn das ganze jetzt noch zu einem String? toString() war nicht die Lösung.

        Vielen Dank für eure Hilfe
        Gruß Marcus

        Kommentar


          #5
          Eigentlich sollte eine Umwandlung gar nicht nötig sein. Aber wenn, sähe die Zeile dann so aus:

          Code:
          gTelBlink.members.forEach[i|i.sendCommand(i.historicState(now.minusSeconds(12)).state.toString)]
          So meckert zumindest der Designer nicht (der spuckt ohne das .toString die gleiche Fehlermeldung aus).

          Kommentar


            #6
            Super,
            danke dir jetzt klappt es. Ich hatte auch exceptions im Log die die gleiche Meldung ausgegeben haben.
            Lag also gar nicht so schlecht mit meinem toString().

            Vielen Dank
            Marcus

            Kommentar

            Lädt...
            X