Ankündigung

Einklappen
Keine Ankündigung bisher.

Regel Loop bestimmten "val" abrufen

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

    Regel Loop bestimmten "val" abrufen

    Hallo,
    komme in der openHAB community leider nicht mehr weiter... Erlaube mir daher auch euch hier zu belästigen.
    Versuche zurzeit die Raffstore so gut wie möglich zu automatisieren. Die Regel schaut aktuell so aus (und funktioniert nicht):

    items:
    Code:
    Group JalouAutoUpOnly
    
    Rollershutter rs_foyer_mitte "Foyer mitte" (Jalou, JalouAutoUpOnly, Garten_RS, sNacht, Fassade1) { knx="2/2/16,2/2/15,2/2/17+<2/2/106" }
    Rollershutter rs_foyer_mitte_lm "Foyer mitte LM" (Jalou_LM, Garten_LM, Fassade1_lm) { knx="2/2/15,2/2/15,2/2/18+<2/2/107" }
    Switch rs_foyer_mitte_auto (rs_auto)
    
    Rollershutter rs_gang_mitte "Gang mitte" (Jalou, JalouAutoUpOnly, sNacht, Fassade2) { knx="3/2/26,3/2/25,3/2/27+<3/2/109" }
    Rollershutter rs_gang_mitte_lm "Gang mitte LM" (Jalou_LM, Fassade2_lm) { knx="3/2/25,3/2/25,3/2/28+<3/2/110" }
    Switch rs_gang_mitte_auto (rs_auto)
    rule
    Code:
    rule "Test"
    when
    Item Test_Button received command ON
    then
    // ok rs_auto.members.filter [ i | i.state == ON ].forEach[i | logInfo("Steuerung", i.name + " ist ON!")]
    // rs_auto.members.findFirst [ i | i.state == ON ].sendCommand(OFF)
    
    val rs_foyer_mitte_up = 168
    val rs_gang_mitte_up = 207
    
    if (TagNacht.state == "Nacht") {
    // logInfo("Raffstore Steuerung:", "Es ist Nacht, hier gibts nichts zu tun.")
    return;
    }
    
    // up_Only
    JalouAutoUpOnly.members.forEach( i | {
    val i_auto = ScriptServiceUtil.getItemRegistry.getItem(i.name + "_auto")
    val i_lm = ScriptServiceUtil.getItemRegistry.getItem(i.name + "_lm")
    val i_up = ???
    
    if ((Astro_Azimuth.state > i_up) && (i_auto.state == ON)) {
    sendCommand(i_auto, OFF)
    if (i.state > 90) {
    sendCommand(i, 0)
    }
    logInfo("Beschattung","Raffstore Garten OG nach oben")
    }
    
    
    })
    end
    die items i_auto und i_lm werden umgewandelt wie gewünscht in z.B. rs_foyer_mitte_auto und rs_foyer_mitte_lm, aber wie bringe ich openHAB dazu i_up von den eingangs definierten "val" auszulesen?
    Möchte - wenn möglich - i_up nicht für jedes Raffstore als item definieren.

    Würde mich freuen, wenn ihr mir weiterhelfen könnt, die Regel müsste sonst ganz gut passen...

    Schönen Abend!

    #2
    Sehe da spontan verschiedene Möglichkeiten:
    • Packe die Werte in eine Hash-Map mit passendem Key
    • Fallunterscheidung nach Item-Namen und setzen mit if.. oder switch-case (das wird bei vielen Items unschön)
    • Über Item-Metadata: https://community.openhab.org/t/desi...eral-dps/78610 (habe ich noch nie benutzt, wäre nach meinem Gefühl allerdings die eleganteste Möglichkeit, zumal Du den Wert dann am Item statt im Script definieren würdest)
    Hoffe das bringt Dich einen Schritt weiter?

    Kommentar


      #3
      Um den letzten Vorschlag aufzugreifen: Ich nutze an einer Stelle die Tags, um Member einer Gruppe zu identifzieren, wo ein Namesschema für
      ScriptServiceUtil.getItemRegistry() nicht mehr weiterführt, etwa

      Code:
      Number En_LichtHV_heute "Energie Licht HV heute [%.2f kWh]" (gCntEnergieLichtHV) [ "CNT_TODAY" ]
      Number En_LichtHV_gestern "Energie Licht HV gestern [%.2f kWh]" (gCntEnergieLichtHV,gStromzaehlerArchiv) [ "CNT_YESTERDAY" ]
      String CntEnergieLichtHV_Persistenz (gCntEnergieLichtHV,gRestoreOnStartup) [ "CNT_PERSIST" ]
      Damit kann ich in der Gruppe gCntEnergieLichtHV die Member identifizieren, ohne dass ich bei den Item-Namen limitiert bin.

      In deinem Fall wäre es

      Code:
      Rollershutter rs_foyer_mitte "Foyer mitte" (Jalou, JalouAutoUpOnly, Garten_RS, sNacht, Fassade1) { knx="2/2/16,2/2/15,2/2/17+<2/2/106" } [ "168" ]
      
      Rollershutter rs_foyer_mitte_lm "Foyer mitte LM" (Jalou_LM, Garten_LM, Fassade1_lm) { knx="2/2/15,2/2/15,2/2/18+<2/2/107" } [ "207" ]
      Die Tags kannst du mit item.getTags() auslesen. An einer Stelle nutze ich auch mehrere Tags. Dort verwende ich Key-Value-Pairs:

      Code:
      Group gCntEnergieWaermepumpeKompressor (gCounterRecordingGroups) [ "CNT_MASTER=Kompressor", "CNT_COUNTER=En_Waermepumpe", "CNT_TRIGGER=CntEnergieWaermepumpeKompressor" ]
      Hier nutze ich die Tags, um in der Item-Datei Relationen zu definieren. "Kompressor" oder "En_Waermepumpe" sind Items, die für der Gruppe eine besondere Funktion haben, ohne dass die Member sind.
      openHAB 4.2

      Kommentar


        #4
        Zitat von Tokamak Beitrag anzeigen
        Um den letzten Vorschlag aufzugreifen: Ich nutze an einer Stelle die Tags, um Member einer Gruppe zu identifzieren, wo ein Namesschema für
        ScriptServiceUtil.getItemRegistry() nicht mehr weiterführt, etwa
        die Items sind eigtl. schon so gestaltet, dass ich mit ScriptServiceUtil.getItemRegistry() ganz gut zurecht komme, bloß der in der Regel definierte Wert (val) macht mir Probleme.

        Zitat von wknx Beitrag anzeigen
        Packe die Werte in eine Hash-Map mit passendem Key
        Hash-Map sagt mir leider nichts, eine Suche mit "openhab hashmap" hat leider auch keine (für mich) verständlichen Ergebnisse gebracht. Könntest du mich vielleicht in die richtige Richtung schubsen (Link? evtl. kuzes Beispiel?)?

        Zitat von wknx Beitrag anzeigen
        Fallunterscheidung nach Item-Namen und setzen mit if.. oder switch-case (das wird bei vielen Items unschön)
        Switch-case müsste ich hinbekommen!

        Zitat von wknx Beitrag anzeigen
        Über Item-Metadata: https://community.openhab.org/t/desi...eral-dps/78610 (habe ich noch nie benutzt, wäre nach meinem Gefühl allerdings die eleganteste Möglichkeit, zumal Du den Wert dann am Item statt im Script definieren würdest)
        Die verlinke Seite hab ich mir mal angesehen, aber auch hier muss ich die Items ja definieren, oder? Wollte das eigtl. vermeiden, da es nur banale Werte sind.
        Wenn ich tatsächlich über items gehe kann ich die auch alle per Hand einmal eingeben und gut ist...

        Schönen Start in die Woche!

        Grüße

        Kommentar


          #5
          Zitat von narf Beitrag anzeigen
          die Items sind eigtl. schon so gestaltet, dass ich mit ScriptServiceUtil.getItemRegistry() ganz gut zurecht komme, bloß der in der Regel definierte Wert (val) macht mir Probleme.
          Du hast das mit den Tags (in eckigen Klammern am Ende der Items-Definition, z.B. [ "168" ]) gesehen, die du im Programmcode leicht abfrangen kannst?

          Code:
          Rollershutter rs_foyer_mitte "Foyer mitte" (Jalou, JalouAutoUpOnly, Garten_RS, sNacht, Fassade1) { knx="2/2/16,2/2/15,2/2/17+<2/2/106" } [ "168" ]
          Rollershutter rs_foyer_mitte_lm "Foyer mitte LM" (Jalou_LM, Garten_LM, Fassade1_lm) { knx="2/2/15,2/2/15,2/2/18+<2/2/107" } [ "207" ]
          Im Programmcode wäre es dann in etwa so:

          Code:
          // up_Only
          JalouAutoUpOnly.members.forEach( i | {
            val i_auto = ScriptServiceUtil.getItemRegistry.getItem(i.name + "_auto")
            val i_lm = ScriptServiceUtil.getItemRegistry.getItem(i.name + "_lm")
            val i_up = Integer::parseInt(i.getTags(1))    // oder getTags(0), bin mir nicht sicher
          
            ...
          Des Weiteren solltest du die Number-states, also etwa i.state, in eine Zahl umwandeln:

          Code:
            if (i.state.intValue() > 90) { sendCommand(i, 0) }
          openHAB 4.2

          Kommentar


            #6
            Ah, jetzt geht ein Lichtlein auf. Das wird praktisch beim "Mutter"-Item als Tag drangehängt. Werde den Ansatz heute Abend versuchen!

            Zu deinem Hinweis mit den Number-states: läuft die Regel dadurch effizienter/schneller/(besser?) durch?
            Funktionieren tuts so auch.

            Kommentar


              #7
              Es funktioniert, weil Java das intern selbst konvertiert. Üblicherweise vermeidet man das aber, weil einem die Kontrolle verloren gehen kann.

              Im besagten Fall gibt es mehrere Möglichkeiten, intern umzuwandeln, bevor der Vergleich durchgeführt wird:
              • i.state wird in ein Integer umgewandelt
              • i.state wird in ein Float umgewandelt
              • i.state und 90 werden jeweils in einen String umgewandelt
              Nicht, dass der letzte Fall hier passieren würde. Aber angenommen, er würde passieren, und i.state ist 100, dann ist auf einmal i.state < 90, weil "100" < "90" ist.

              Um solche Überraschungen nicht zu erleben, wandelt man es selbst um.

              Insbesondere könnte i.state nach dem OH-Start noch nicht initialisert werden und wäre dann NULL. Im konkreten Fall würde man daher der Vollständigkeit halber schreiben:

              Code:
              if (i.state instanceof Number && (i.state as Number).intValue() > 90) { sendCommand(i, 0) }
              Das heißt, zunächst wird geprüft, ob es wirklich eine Number und damit nicht NULL ist, dann wird State als Number mittels intValue() in eine Zahl konvertiert.
              Zuletzt geändert von Tokamak; 24.02.2020, 12:05.
              openHAB 4.2

              Kommentar


                #8
                Zitat von narf Beitrag anzeigen
                Die verlinke Seite hab ich mir mal angesehen, aber auch hier muss ich die Items ja definieren, oder? Wollte das eigtl. vermeiden, da es nur banale Werte sind.
                Da würdest Du keine weiteren Items definieren, sondern ein bestehendes mit Schlüssel-Werte-Paaren erweitern.

                Kommentar


                  #9
                  Code:
                  Rule 'Test': Could not invoke method: java.lang.Integer.parseInt(java.lang.String) on instance: null
                  fehlt mir eine library?

                  In VS Code hab ich für "i.getTags(1)" außerdem folgende Anmerkung/Fehlermeldung:
                  Code:
                  Type mismatch: cannot convert from Set<String> to String(org.eclipse.xtext.xbase.validation.IssueCodes.incompatible_types)
                  Zuletzt geändert von narf; 24.02.2020, 20:34.

                  Kommentar


                    #10
                    Zitat von narf Beitrag anzeigen
                    Code:
                    Rule 'Test': Could not invoke method: java.lang.Integer.parseInt(java.lang.String) on instance: null
                    fehlt mir eine library?
                    Das ist ein Folgefehler des zweiten:
                    In VS Code hab ich für "i.getTags(1)" außerdem folgende Anmerkung/Fehlermeldung:
                    Code:
                    Type mismatch: cannot convert from Set<String> to String(org.eclipse.xtext.xbase.validation.IssueCodes.incompatible_types)
                    Mea culpa. getTags() gibt ein Set zurück.

                    Versuche es bitte mal

                    Code:
                    val i_up = Integer::parseInt(i.getTags().toArray().get(0))
                    (gib alle Tags als Set zurück, wandle das Set/die Menge in einen Array, nimm davon den ersten Wert, was geht, weil es nur einen Wert gibt, und wandle den in ein Integer um)

                    oder

                    Code:
                    val i_up = Integer::parseInt(i.getTags().iterator().next())
                    (wie vor, nur iteriere über das Set/die Menge, nimm das nächste/einzige Element und wandle es um)

                    Es könnte sein, dass du dafür java.util.Set und - im ersten Fall - java.util.Array importieren musst.
                    openHAB 4.2

                    Kommentar


                      #11
                      Danke für den Hinweis, kann es leider erst am Abend versuchen.
                      Bei einigen anderen Fenstern muss ich nicht nur i_up, sondern auch i_down verwenden, das heißt also, hier würde ich bei den Tags zwei Werte angeben.
                      Ist das auch möglich? Einfach "nur" mit get(x) rumspielen?

                      Gruß, schönen Tag!

                      Kommentar


                        #12
                        Jein. Ein Set ist nicht sortiert. Das heißt, du weißt nicht, ob du die Werte in der gleichen Reihenfolge wie in der Items-Definition erhältst. Willst du also zwei oder mehr Werte sicher unterscheiden, solltest du mit Key-Value-Pairs arbeiten, z.B.

                        Code:
                        Rollershutter rs_foyer_mitte "Foyer mitte" (Jalou, JalouAutoUpOnly, Garten_RS, sNacht, Fassade1) { knx="2/2/16,2/2/15,2/2/17+<2/2/106" } [ "up=168","down=87" ]
                        Da du weder die Reihenfolge kennst noch weißt, ob beide Werte angegeben sind, musst du das im Code berücksichtigen, etwa:

                        Code:
                        var Integer i_up=0
                        var Integer i_down=0
                        for (String tag: i.getTags()) {
                            val String[] keyValue=tag.split("=")
                            val value=Integer::parseInt(keyValue.get(1))
                            switch (keyValue.get(0)) {
                                case "up" : i_up=value
                                case "down" : i_down=value
                            }
                        }
                        So mache ich das normalerweise.

                        Einfacher kannst du es haben, indem du immer(!) beide Werte in einem String angibst, etwa:
                        Code:
                        Rollershutter rs_foyer_mitte "Foyer mitte" (Jalou, JalouAutoUpOnly, Garten_RS, sNacht, Fassade1) { knx="2/2/16,2/2/15,2/2/17+<2/2/106" } [ "168;87" ]
                        Das heißt, der Wert vor dem Semikolon is der für up, der andere für down. Dann schreibst du in etwa das als Code:

                        Code:
                        val String[] values=i.getTags().iterator().next().split(";")
                        val Integer i_up=Integer::parseInt(values.get(0))
                        val Integer i_up=Integer::parseInt(values.get(1))
                        Allerdings musst du dann immer das Semikolon angeben und zwei Zahlen angeben.

                        Wenn du nur dann das Semikolon angibst, wenn es auch einen down-Wert gibt, musst du das zusätzlich im Code abfangen. Das kriegst du mit den Beispielen dann sicher selbst hin.
                        Zuletzt geändert von Tokamak; 25.02.2020, 15:33.
                        openHAB 4.2

                        Kommentar


                          #13
                          Zitat von Tokamak Beitrag anzeigen
                          Das kriegst du mit den Beispielen dann sicher selbst hin.
                          Na da würd ich jetzt nicht drauf wetten. Werd ich aber nicht brauchen, wenn ich die Regel so aufbaue, wie ich mir das bisher gedacht habe.

                          Vielen Dank nochmal, werde später berichten!

                          Gruß

                          Kommentar


                            #14
                            habs bisher geschafft, up und down einzulesen, wollte dann auch noch das hier umsetzen:

                            Zitat von Tokamak Beitrag anzeigen
                            Code:

                            if (i.state.intValue() > 90) { sendCommand(i, 0) }

                            Bekomme allerdings folgende Fehlermeldung:
                            Code:
                            Rule 'Test': 'intValue' is not a member of 'org.eclipse.smarthome.core.types.State'; line 84, column 13, length 18
                            ohne ".intValue()" läuft die Regel wie geplant durch.

                            Schönen Abend!

                            Kommentar


                              #15
                              Solange das in der DSL läuft, sollte die Wandlung eher so aussehen:

                              Code:
                              if((i.state as Number).intValue > 90)
                              Der Befehl kann auch direkt die Methode verwenden:
                              Code:
                              i.sendCommand(0)
                              Solange nur der eine Befehl nach dem if ausgeführt werden soll, kann man die geschweiften Klammern auch weg lassen.

                              Kommentar

                              Lädt...
                              X