Ankündigung

Einklappen
Keine Ankündigung bisher.

rule mit Variablen nutzen

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

    rule mit Variablen nutzen

    Hallo!

    Damit ich mit Alexa meine Rollos steuern kann, mache ich das mit einem Switch über eine Regel:
    office.items:
    Code:
    Rollershutter eg_buero_ro_ost    "Büro EG Rollo Ost"        <rollershutter>    (gBueroEG, gEGRollo)  {knx="1/0/7, 1/0/6, 1/0/107"}
    Switch eg_buero_ro_ost_alexa "Büro Ost"
    office.rules:
    Code:
    rule "og_buero_ro_ost_alexa"
    when
        Item og_buero_ro_ost_alexa received command
    then
    
    switch(receivedCommand) {
        case ON : og_buero_ro_ost.sendCommand(UP)
        case OFF : og_buero_ro_ost.sendCommand(DOWN)
    }
    end
    Das wird aber ziemlich schnell unübersichtlich und Gefummel.
    Lässt sich die Regel (rule) nicht mit Variablen füttern, so dass der Rollershutter (eg_buero_ro_ost) zum Beispiel als Variable übergeben wird? Oder etwas ähnliches in der Art?

    #2
    Du kannst z.B. alle Rollladen-Items in einer Gruppe zusammenfassen, die Rule auf alle Items triggern lassen und dann anschließend im Rumpf der rule prüfen, welches Item zuletzt getriggert wurde. Wenn die Itemnamen geschickt gewählt sind, ergibt sich der zu steuernde Name aus dem Itemnamen, über das der Befehl herein gekommen ist, dann kann man also den Befehl entsprechend generieren.

    Eine Variablenübergabe gibt es hingegen nicht, weder für Rules noch (leider) für Scripte. Bei ersterem ist das auch unlogisch, die Rule ist eventbasiert, wo sollte da die Variable her kommen; Beim Script ist es schon eher ärgerlich, weil man sich viele Codedoppelungen sparen könnte, wenn man Standardbefehlsabfolgen in Funktionen zusammenfassen könnte.
    Einen Ausweg können Lambdas darstellen, aber die Mechanismen zu verstehen ist nicht trivial, die Anzahl der übergebbaren Variablen ist begrenzt (maximal 9 Variablen) und fix, außerdem funktionieren bestimmte Dinge innerhalb der Lambdas anders als im restlichen Code.

    Kommentar


      #3
      Danke für die Antwort!
      Zitat von udo1toni Beitrag anzeigen
      die Rule auf alle Items triggern lassen und dann anschließend im Rumpf der rule prüfen, welches Item zuletzt getriggert wurde
      So ganz verstehe ich das leider nicht (hauptsächlich den letzten Teil). Könntest du das ggf. etwas ausformulieren, oder hast vielleicht sogar ein Beispiel für mich?!

      Kommentar


        #4
        Aaaalso...
        .items
        Code:
        Group:Switch Alexa
        Rollershutter eg_buero_ro_ost "Büro EG Rollo Ost" <rollershutter> (gBueroEG, gEGRollo) {knx="1/0/7, 1/0/6, 1/0/107"}
        Switch alexa_eg_buero_ro_ost "Büro Ost" (Alexa)
        Rollershutter eg_buero_ro_sued "Büro EG Rollo Süd" <rollershutter> (gBueroEG, gEGRollo) {knx="1/1/7, 1/1/6, 1/1/107"}
        Switch alexa_eg_buero_ro_sued "Büro Süd"(Alexa)
        Rollershutter eg_buero_ro_west "Büro EG Rollo West" <rollershutter> (gBueroEG, gEGRollo) {knx="1/2/7, 1/2/6, 1/2/107"}
        Switch alexa_eg_buero_ro_west "Büro West"(Alexa)
        Rollershutter eg_buero_ro_nord "Büro EG Rollo Nord" <rollershutter> (gBueroEG, gEGRollo) {knx="1/3/7, 1/3/6, 1/3/107"}
        Switch alexa_eg_buero_ro_nord "Büro Nord"(Alexa)
        .rules
        Code:
        rule
        when
            Item alexa_eg_buero_ro_ost received command or
            Item alexa_eg_buero_ro_sued received command or
            Item alexa_eg_buero_ro_nord received command or
            Item alexa_eg_buero_ro_west received command
        then
            val String myItem = Alexa.members.sortBy[lastUpdate].last.name.substring(6)  // Name des zuletzt aktualisierten Items aus der Gruppe ohne die ersten 6 Zeichen
            sendCommand(myItem,if(receivedCommand == ON) "UP" else "DOWN")
        end
        Ich habe sowas nicht in Nutzung, aber eigentlich sollte es so funktionieren. Schau Dich mal im englischen Forum um, da gibt es einige Codebeispiele.

        Es gibt noch etwas Grundsätzliches zu beachten: Wie Du siehst, habe ich nicht die Gruppe als Trigger verwendet, sondern alle Items separat aufgeführt. Der Hintergrund ist, dass ein Gruppenitem die Rule mehrfach triggert, wenn sich ein Item ändert.

        Der Trick bei den Namen ist, die Itemnamen so zu gestalten, dass man einheitlich auf den Namen zugrefen kann. substring schneidet die ersten n Zeichen ab, das Gegenstück, welches die letzten n Zeichen abschneidet, konnte ich leider auf die Schnelle nicht finden.
        Zuletzt geändert von udo1toni; 13.09.2017, 20:58.

        Kommentar


          #5
          Das sieht prima aus. Besten Dank! Alles im Ansatz verstanden. Zumindest minimiert sich dann einiges im Code (vor allem Fehlerquellen).
          Du hast der Rule keinen Namen gegeben. Das habe ich nachgeholt, der ist ja eigentlich nicht wichtig. Oder?
          Weiterhin gibt es hier gleich zwei Fehler:
          Code:
          val String myItem = Alexa.members.sortBy[lastUpdate].last.name.substring(6)
          The method or field Alexa is undefined.
          Type mismatch: cannot convert implicit first argument from Object to Item.
          Der zweite Fehler ist bei dem Wort "lastUpdate". Ich denke, dass der nur wegen des ersten Fehlers auftaucht. Oder?

          Kommentar


            #6
            Rulename: Ups... der gehört da natürlich hin, keine Frage. Was da steht ist aber egal, Hauptsache, er ist eindeutig (kommt also in openHAB nicht an anderer Stelle nochmal als Rulename vor)

            Du hast gesehen, dass ich die Gruppe Alexa in der items-Datei angelegt habe? Gruppen müssen als (Gruppen-)Item definiert sein, damit man sie benutzen kann.

            Kommentar


              #7
              Zitat von udo1toni Beitrag anzeigen
              Du hast gesehen, dass ich die Gruppe Alexa in der items-Datei angelegt habe?


              Klar. Aber nicht eingebaut. Da war ich zu schnell. Weil den oberen Teil hatte ich ja schon, bis auf die erste Zeile.
              Danke für die Hinweise und deine Geduld!

              Wenn ich zusätzlich jetzt noch die Option haben möchte, mehrere Rolladen gleichzeitig fahren zu lassen, packe ich die dann in eine Gruppe und gebe der dann ne andere Rule, gelle?

              Kommentar


                #8
                Der normale Weg wäre, eine Gruppe zu definieren, in der alle zu fahrenden Rollläden zusammengefasst sind, und dieser Gruppe den Steuerbefehl zu geben, dann sollte openHAB automatisch allen Gruppenmitgliedern den Steuerbefehl senden. Da Du das ganze über Alexa wirst machen wollen, brauchst Du eh ein extra Item, dann kannst Du auch gleich eine andere Rule schreiben (als Beispiel nehme ich die vorhandene Gruppe gEGRollo und nehme an, dass es ein Alexa Item alexa_gEGRollo gibt:
                Code:
                rule "alle Läden"
                when
                    Item alexa_gEGRollo received command
                then
                    gEGRollo.members.filter(r|(r.state as DecimalType).intValue != if(receivedCommand==ON) 0 else 100).forEach(r|r.sendCommand(if(receivedCommand==ON) UP else DOWN))
                end
                ...

                HÄ?

                Also übersetzt: Wenn der Befehl reinkommt, nimm die Gruppenmitglieder und schau nach, welchen Status sie haben. Nimm nur die, deren Status nicht dem gewünschten Status entspricht. Schicke jedem dieser Items den Steuerbefehl.
                ON bedeutet: fahre hoch, gewünschter Status ist also 0 (= offen)
                OFF bedeutet: fahre runter, gewünschter Status ist also 100 (=geschlossen)

                Da wir diesmal die Methode Item.sendCommand() verwenden können, ist es nicht notwendig, eine Konvertierung nach String vorzunehmen, wie in der anderen Rule.

                Kommentar


                  #9
                  Goil. Das schaffe ich heute leider nicht mehr zu testen. Bedanke mich aber dennoch schon 1000mal bei dir. Ich gebe hier auf jeden Fall nochmal Rückmeldung!

                  Kommentar


                    #10
                    Hallo!
                    Gerade teste ich das Script von letzter Woche. Alexa sagt zwar "OK", aber es passiert nichts. Im Log steht aber folgender Fehler:
                    Code:
                    18:25:01.011 [ERROR] [l.script.engine.ScriptExecutionThread] - Rule 'AlexaRolloBuero': cannot invoke method public abstract java.lang.String org.eclipse.smarthome.core.items.Item.getName() on null
                    Damit kann ich leider nichts anfangen. "AlexaRolloBuero" ist der Name der Rule.
                    Muss ich noch etwas aktivieren oder im Code hinzufügen? Habe ich was falsch gemacht?

                    Kommentar


                      #11
                      Ja, vermutlich hast Du was falsch gemacht.
                      Bitte zeig mal:
                      • alle beteiligten Items (die Definition)
                      • die Rule

                      Kommentar


                        #12
                        Habe es gerade nicht zur Hand, aber es ist nahezu 1:1 von hier kopiert.

                        Kommentar


                          #13
                          Ja, das hilft aber nicht...

                          kopiert -> Möglicherweise ist an irgendeiner Stelle eine kleine Abweichung
                          nahezu -> es sind definitiv Abweichungen vorhanden.

                          Wie soll man einen Fehler finden, wenn man dazu keine Unterlagen hat?

                          Kommentar


                            #14
                            Ich gebe dir da zu100% Recht. Ich wollte nur ein kurzes Feedback da lassen. Ich poste morgen die Zeilen.

                            Kommentar


                              #15
                              Hallo!

                              hier kommen die Anpassungen:
                              alexa-rollo.rules:
                              Code:
                              Group:Switch Alexa
                              rule AlexaRolloBuero
                              when
                                  Item alexa_og_buero_ro_ost received command or
                                  Item alexa_eg_buero_ro_ost received command or
                                  Item alexa_eg_buero_ro_nord received command or
                                  Item alexa_eg_buero_ro_flur received command or
                                  Item alexa_eg_buero_ro_werk received command
                              then
                                  val String myItem = Alexa.members.sortBy[lastUpdate].last.name.substring(6)  // Name des zuletzt aktualisierten Items aus der Gruppe ohne die ersten 6 Zeichen
                                  sendCommand(myItem,if(receivedCommand == ON) "UP" else "DOWN")
                              end
                              home.items:
                              Code:
                              Rollershutter og_buero_ro_ost    "Rollo Büro Roger"        <rollershutter>    (gBueroOG, gOGRollo)                                        {knx="1/1/6, 1/1/5, 1/1/106"}
                              Switch alexa_og_buero_ro_ost     "Rollo Büro Roger"                                                                     ["Switchable"]
                              Rollershutter eg_buero_ro_ost    "Rollo Büro Ost"        <rollershutter>    (gBueroEG, gEGRollo)                                        {knx="1/0/7, 1/0/6, 1/0/107"}
                              Switch alexa_eg_buero_ro_ost "Rollo Büro Ost"                                                                         ["Switchable"]
                              Rollershutter eg_buero_ro_nord    "Rollo Büro Nord"         <rollershutter>    (gBueroEG, gEGRollo)                                        {knx="1/0/5, 1/0/4, 1/0/105"}
                              Switch alexa_eg_buero_ro_nord "Rollo Büro Nord"                                                                     ["Switchable"]
                              Rollershutter eg_buero_ro_flur    "Rollo Büro Flur"         <rollershutter>    (gBueroEG, gEGRollo)                                        {knx="1/0/3, 1/0/2, 1/0/103"}
                              Switch alexa_eg_buero_ro_flur "Rollo Büro Flur"                                                                     ["Switchable"]
                              Rollershutter eg_buero_ro_werk    "Rollo Werkstatt"         <rollershutter>    (gBueroEG, gEGRollo)                                        {knx="1/0/9, 1/0/8, 1/0/109"}
                              Switch alexa_eg_buero_ro_werk "Rollo Werkstatt"                                                                     ["Switchable"]

                              Kommentar

                              Lädt...
                              X