Ankündigung

Einklappen
Keine Ankündigung bisher.

Rollladen bei LUX-Wert >80000, länger als 10 Minuten auf 70% fahren

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

    Rollladen bei LUX-Wert >80000, länger als 10 Minuten auf 70% fahren

    Hallo zusammen.
    Ja, ich weiß das es Schw....-Kalt ist, aber der nächste Sommer kommt und ich will vorbereitet sein.

    Also, ich habe Rollläden, die mit Homematic-Schaltern gefahren werden.

    Esszimmer:
    Code:
    Rollershutter EZ_Rol_1LEVEL "Esszimmerrollladen K1 level" (gEZ_Rollladen, Esszimmer) {channel="homematic:HM-LC-Bl1PBU-FM:XXXXXXXX:NEQXXXXXX:1#LEVEL"}
    Wohnzimmer:
    Code:
    Rollershutter WZ_Rol1LEVEL "Wohnzimmer Rollladen K1 level" (gWZ_Rollladen) {channel="homematic:HM-LC-Bl1PBU-FM:XXXXXXXX:NEQXXXXXXX:1#LEVEL"}
    Des weiteren habe ich noch einen Sonnensensor:
    Code:
    Number LUX_K1LUX "Sonnensensor lux" (gSonnensensor, Terasse) {channel="homematic:HM-Sen-LI-O:XXXXXXXXX:OEQXXXXXXX:1#LUX"}
    und einen Temperatursensor auf der gleichen Seite:
    Code:
    Number A_Temp_K2TEMPERATURE "Aussentemperatur im Schatten" (gAussentemperatursensor, gTerasse, gchartTemp) {channel="homematic:HM-WDS30-OT2-SM-2:XXXXXXXX:NEQXXXXXXX:2#TEMPERATURE"}
    Ach ja und natürlich für die Terassentür noch einen Türgriffkontakt, der aufpassen soll, das die Rolllade nicht fährt, wenn die Tür geöffnet ist:
    Code:
    String EZ_Griff_1STATE "Terassentürgriff K1 state" (gEZ_Fenstergriff, Esszimmer) {channel="homematic:HM-Sec-RHS:XXXXXXX:LEQXXXXXXX:1#STATE"}
    Für Abends habe ich eine funktionierende Rule:
    Code:
    rule "Rollladen runter Abends"
    when
             Channel 'astro:sun:home:set#event' triggered START
    then
             createTimer(now.plusMinutes(30))
             [
              WZ_Rol1LEVEL.sendCommand(100)
              if (EZ_Griff_1STATE.state.toString =="CLOSED")
                    {
                    EZ_Rol_1LEVEL.sendCommand(100)
                    }
            ]
    end
    So, Schluß mit der Vorrede: Meine Überlegung ist jetzt, wie ich am Besten eine Sonnenschutzfunktion (Rule) erstellen kann?

    Wenn die Sonne länger als 10 Minuten scheint und die Temperatur höher als 20 Grad ist, dann sollen die Rollläden im Ess- und Wohnzimmer auf 80% herunterfahren und hochfahren, wenn entweder die Temperatur noch vor Sonnenuntergang unter 15 Grad fällt und der LUX-Wert unter z. B. 2000 für eine Zeit länger 30 Minuten gesunken ist.
    Ich könnte jetzt ja die oben stehende Rule abändern, aber wie bekomme ich den Timer so eingestellt, das die Rollläden nur gefahren werden, wenn die Sonne und die Temperatur länger als 10 Minuten die gewünschten Werte hatte. Die obige Rule schießt ja immer nach 30 Minuten, aber wenn in der Zwischenzeit die Bedingung nicht mehr gegeben ist, soll die Sonnenschutzfunktion ja nicht ausgelöst werden.

    Habe ich das zu kompliziert geschrieben?

    #2
    Hallo,

    ich bin zwar selbst noch recht neu dabei aber ich versuch mal Dir zu helfen. Bau mal die Regel so das Du als erstes deine Bedingungen abfragst also
    Code:
    if (temp > 20 Grad ) {
      createTimer(now.plusMinutes(30))    
         [           WZ_Rol1LEVEL.sendCommand(100)          
    if (EZ_Griff_1STATE.state.toString =="CLOSED")              
      {                 EZ_Rol_1LEVEL.sendCommand(100)                 }      
      ]
    }
    end
    Ob der Timer neu gestartet wird oder weiterläuft wenn die IF Bedingung mal nicht erfüllt war kann ich leider nicht sagen.
    Gruß

    Guido

    Kommentar


      #3
      Du hast mehrere Werte, die eine bestimmte Zeit nicht unter- oder überschritten werden dürfen. Eine Möglichkeit wäre, einen Timer zu starten, der den Laden verfährt, und den Timer zu canceln, wenn der Grenzwert unterschritten wird (mit einer weiteren Rule).
      Eine andere Möglichkeit wäre, die Werte (Temperatur und Helligkeit) zu persistieren. Dann kannst Du mit Item.minimumSince(now.minusMinutes(10)) nachschauen, ob der Wert unterschritten wurde. genauso kannst Du mit Item.maximumSince(now.minusMinutes(30)) nachschauen, ob der Wert nicht überschritten wurde.

      Kommentar


        #4
        Diese Antwort kam aus dem anderen Forum:
        Ich würde hier mit einer Kombination aus rule und Expire-Bindung arbeiten. z.B. Für den ersten Fall ein zusätzliches Switch Item das per Expire nach 10 Min den Status auf ON setzt. Dieses bei jeder Termperatur-Änderung (rule changed) unterhalb von 20 Grad (und ggf. abhängig von Tageszeit, Helligkeit, Sonnenauf/Untergang, usw.) auf OFF setzen. Wenn das 10 Min ausbleibt wird automatisch ON gesetzt und eine weitere changed to ON rule kann den Rolladen fahren. In gleicher Weise ist auch alles andere reralisierbar, soweit ich meine, übersichtlich und mit gernger Systembelastung.
        Es ist doch immer wieder interessant diese Unterschiedlichen Herangehensweisen zu sehen. Dieses Expire-Binding hab ich noch garnicht gesehen.
        Das muß ich mir mal anschauen. Das scheint das Timer-Problem ja etwas zu vereinfachen, oder seht ihr das anders?

        @udo1Toni: Hab gerade gesehen, das du zum Expire-Binding im Beitrag "Merker" etwas geschrieben hattest. Na, da muß ich mir am Wochenende mal ein paar Gedanken machen.
        Zuletzt geändert von hoggle1969; 27.02.2018, 09:42.

        Kommentar


          #5
          Eine weitere Variante wäre mit averageSince:

          Code:
          val SunLux = 45000
          val int LuxHysteresis=10
          ...
          rule "..."
          var Number Lux_five_avg = ESP8266_Five_Lux.averageSince(now.minusMinutes(LuxHysteresis))
              ESP8266_Five_Lux_AVG.postUpdate(Lux_five_avg)
          ...
          if (Lux_five_avg > SunLux)
          ...
          ESP8266_Five_Lux gibt mir den aktuellen Lux Wert, der Durchschnitt der letzten 10 Minuten wird per averageSince in der Variablen Lux_five_avg ermittelt, dieser per postUpdate zum Item ESP8266_Five_Lux_AVG übertragen und dann auf Lux_five_avg getriggert.
          ESP8266_Five_Lux_AVG dient nur zum Anzeigen des aktuellen Wertes in der GUI.

          Somit werden die Rollläden nur gefahren wenn ein bestimmter Luxwert für länger als xx Minuten überschritten wird.
          Codeschnippsel habe ich mal irgendwo hier gefunden ...
          Zuletzt geändert von sihui; 02.03.2018, 10:02.

          Kommentar


            #6
            Durch den Durchschnittswert bekommt man ein trägeres Verhalten und damit eine unaufgeregtere Steuerung hin. Coole Idee.
            Da werde ich mich mal heran tasten, werde aber auch noch die Temperatur mit ins Spiel bringen, denn, wenn es nur 10-15 Grad warm ist, dann möchte ich ja die Sonne als Heizung mit nutzen, aber ansonsten ist das super.
            Vielen Dank für diese Tipps.
            Wenn ich das fertig habe, stelle ich das mal hier vor.

            Kommentar


              #7
              Meine Erfahrung: man braucht nicht nur ein trägeres Verhalten beim Starten des Sonnenschutzes, sondern auch beim Beenden: bei mir wird nach dem Auslösen des averageSince Triggers ein virtuelles Item getriggert, welches dann per expire Binding (geht natürlich auch über Timer) erst nach xx Minuten wieder die Möglichkeit des Hochfahrens der Rollläden ermöglicht.
              Diese Funktion ist normalerweise auch in kommerziellen Produkten enthalten.
              Und vergiss nicht eine Funktion, die Automatik nach manueller Bewegung der Rollläden für eine gewisse Zeit zu sperren (ggf. auch über expire). Es gibt nichts nervigeres als eine bestimmte Position manuell angefahren zu haben und nach wenigen Minuten wird diese über die Automatik wieder übersteuert.

              Kommentar


                #8
                Hi.
                Kannst du mal ein Schnipsel aus deiner Rule posten?
                Ich hab das mit dem Expire-Binding noch nicht so verstanden. Wie ist das denn, wenn in der Zeit, wo sich die Bedingung ändert, startet das Binding den internen Timer dann wieder von vorne?

                Code:
                rule "Rollladen runter Abends"
                when
                         Channel 'astro:sun:home:set#event' triggered START
                then
                         createTimer(now.plusMinutes(30))
                                            [
                                             K_Rol_1LEVEL.sendCommand(70)
                                             WZ_Rol1LEVEL.sendCommand(100)
                                             B_Rol_1LEVEL.sendCommand(100)
                                             if (EZ_Griff_1STATE.state.toString =="CLOSED")
                                                {
                                                  EZ_Rol_1LEVEL.sendCommand(100)
                                                }
                                           ]
                end
                
                rule "Esszimmerrollladen nachträglich schließen"
                when
                          Item EZ_Griff_1STATE changed to "CLOSED"
                then
                          if (Astro_PhaseName.state.toString !="Day") and (aktuelle Uhrzeit vor 23.00 Uhr) and (EZ_Rol_1LEVEL == 0)
                             {
                               createTimer(now.plusSeconds(30))
                               [
                                EZ_Rol_1LEVEL.sendCommand(100)
                               ]
                             }
                end
                Die erste Rule funktioniert einwandfrei, bei der 2. weiss ich nicht weiter.
                1. wie frage ich die aktuelle Uhrzeitvernünftig ab (... aktuelle Uhrzeit vor 23.00 Uhr)
                2. EZ_Rol_1LEVEL ist ein Rollershutter Item. Kann ich die Position so wie in der Rule angegeben abfragen?
                3. Wenn ich merke, das ich die Tür doch nicht schließen wollte und innerhalb der 30 Sekunden die Tür wieder öffne, fährt der Rollladen trotzdem herunter?
                4. Geht das überhaupt mit den and-Anweisungen, oder muß ich alles in geschachtelte if-Bedingungen packen?

                Wie du siehst, habe ich das Expire noch garnicht angewendet. Geht das damit einfacher?

                Die Rules sollen erst einmal für den Abend sein. Für die Sonnenstandsabhängige Steuerung in Verbindung mit dem vorhandenen Sonnensensor und dem Außenthermometer möchte ich dann als nächstes machen.

                Kommentar


                  #9
                  Zitat von hoggle1969 Beitrag anzeigen
                  Hi.
                  Wie ist das denn, wenn in der Zeit, wo sich die Bedingung ändert, startet das Binding den internen Timer dann wieder von vorne?
                  Exakt, das ist das "Geheimnis" dabei und macht in diesem Falle das expire Binding einfach in der Nutzung, obwohl man es mit Timern natürlich auch realisieren könnte.

                  Items (für einen Rollladen):

                  Code:
                  Switch ShutterDelayTimerKitchen_East <switch> (gRestore) { expire="20m,command=OFF" } //für die verzögerte Öffnung nach Schließung durch die Sonnenautomatik
                  Switch ShutterOverrideTimerKitchen_East <switch> (gRestore) { expire="240m,command=OFF" } //für die Deaktivierung nach manueller Bewegung des Rollladens
                  Im Rule Teil für die Automatik kommt in die äußerste IF-Schleife

                  Code:
                  then
                          if (... && ShutterOverrideTimerKitchen_East.state==OFF ...) {
                  
                  
                          else if (... && ShutterOverrideTimerKitchen_East.state==OFF && ShutterDelayTimerKitchen_East.state==OFF ...) {
                  Der IF Teil öffnet, der ELSE Teil schließt den Rollladen.

                  Bei den anderen Fragen kann ich dir nicht helfen, ich suche mir immer Code Schnippsel und passe sie an meine Bedürfnisse an.
                  Ein "and" kannst du nicht verwenden, du musst ein "&&" nehmen.
                  Ansonsten bitte einmal die demo rules anschauen und die Doku, da stecken alle Basics drin die man braucht.

                  Viel Spaß.



                  Kommentar


                    #10
                    Deine Rule zum nachträglichen Schließen sieht doch schon mal gut aus. Um die "Unterbrechung" des Timers zu realisieren, benötigst Du an dieser Stelle allerdings ein paar Änderungen:

                    1. die Rule sollte auf alle Änderungen des Griffs reagieren (egal ob OPEN oder CLOSED)
                    Code:
                    when
                      Item EZ_Griff_1STATE changed
                    then
                    2. Abfrage, ob der Griff geschlossen wurde -> Timer für runterfahren setzen vorbereiten, ansonsten wird Timer gelöscht.
                    Code:
                    if (EZ_Griff_1STATE.state == "CLOSED") {
                      ez_roll_timer = createTime(now.plusSeconds(30)) [|
                                    EZ_Rol_1LEVEL.sendCommand(100)
                                   ]
                      }
                      else {
                        if (ez_roll_timer != null) ez_roll_timer.cancel()
                      }
                    }
                    Somit wird der Timer gelöscht, wenn Du den Türgriff innerhalb der 30 Sekunden wieder öffnest.

                    Nach der if-Abfrage auf CLOSED kannst du auch ein weiteres if-Statement einfügen, in dem Deine bisherigen Abhängigkeiten reinkommen, also
                    Code:
                    if (Astro_PhaseName.state.toString !="Day") and (aktuelle Uhrzeit vor 23.00 Uhr) and (EZ_Rol_1LEVEL == 0)
                    und Du danach dann erst den Timer startest...

                    Die Abfrage nach der Uhrzeit machst Du mit now.getHourOfDay(), d.h für eine Uhrzeit vor 23 Uhr:
                    Code:
                    if  ((Astro_PhaseName.state.toString !="Day") && (now.getHourOfDay() < 23) && (EZ_Rol_1LEVEL == 0))
                    Andreas

                    Kommentar


                      #11
                      Mhh, hab noch Fehler.
                      Was kann das sein?
                      Code:
                      val int ez_roll_timer=0
                      
                      rule "Esszimmerrollladen nachträglich schließen"
                      when
                              Item EZ_Griff_1STATE changed
                      then
                              if ((EZ_Griff_1STATE.state == "CLOSED") &&
                                 (Astro_PhaseName.state.toString !="Day") &&
                                 (now.getHourOfDay() < 23) &&
                                 (now.getHourOfDay() > 16) &&
                                 (EZ_Rol_1LEVEL == 0) &&
                                 (WZ_Rol1LEVEL == 100))
                                          {
                                            ez_roll_timer = createTime(now.plusSeconds(30))
                                            [|
                                            EZ_Rol_1LEVEL.sendCommand(100)
                                            ]
                                           }
                              else {
                                       if (ez_roll_timer != null) ez_roll_timer.cancel()
                                      }
                      end
                      Zeilenumbruch hinter den "&&" habe ich hier nur zur Übersicht eingefügt, im VSC stehen alle "&&" in einer Zeile.
                      Und der Fehler im Log:
                      Code:
                      2018-03-07 20:41:45.691 [vent.ItemStateChangedEvent] - EZ_Griff_1STATE changed from OPEN to TILTED
                      
                      ==> /var/log/openhab2/openhab.log <==
                      
                      2018-03-07 20:41:46.403 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Esszimmerrollladen nachträglich schließen': 'cancel' is not a member of 'java.lang.Integer'; line 30, column 39, length 22
                      
                      ==> /var/log/openhab2/events.log <==
                      
                      2018-03-07 20:42:19.432 [vent.ItemStateChangedEvent] - EZ_Griff_1STATE changed from TILTED to CLOSED
                      
                      ==> /var/log/openhab2/openhab.log <==
                      
                      2018-03-07 20:42:19.469 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Esszimmerrollladen nachträglich schließen': 'cancel' is not a member of 'java.lang.Integer'; line 30, column 39, length 22
                      Zuletzt geändert von hoggle1969; 07.03.2018, 20:46. Grund: Code und Fehler aktualisiert

                      Kommentar


                        #12
                        Deine Variablen-Deklaration für ez_roll_timer ist falsch. Benutze:
                        Code:
                        var Timer ez_roll_timer = null
                        am Anfang Deiner rule-Datei.

                        Der Fehler besagt, dass eine Variable vom Typ int keine Methode "cancel" bereitstellt...

                        Die Bedingungen der if-Abfrage können auch untereinander stehen. Gerade bei so vielen Bedingungen finde ich das übersichtlicher. Die Struktur wird da über die Klammern geregelt...

                        Kommentar


                          #13
                          Zu dem if() möchte ich noch folgenden Senf absondern:
                          Code:
                          if ((EZ_Griff_1STATE.state == "CLOSED") &&
                          (Astro_PhaseName.state.toString !="Day") &&
                          (now.getHourOfDay() < 23) &&
                          (now.getHourOfDay() > 16) &&
                          (EZ_Rol_1LEVEL == 0) &&
                          (WZ_Rol1LEVEL == 100))
                          1. Die meisten Klammern sind unnötig. Und zwar jeweils die um die Gleichungen.
                          2. Obwohl es funktioniert, ist das erste Statement nicht korrekt, denn ein State wird ohne Anführungszeichen geschrieben. openHAB ergänzt hier stillschweigend ein (ansonsten unnötiges) .toString
                          3. die dritte Bedingung sorgt dafür, dass der Laden nach 22:59:59 nicht mehr geschlossen wird. Ist das wirklich Absicht? Und nach 0 Uhr passiert ebenfalls nichts.
                          4. EZ_Rol_1LEVEL und WZ_Rol1LEVEL sind vermutlich beides Items. Deshalb muss der Vergleich mit einem .state ergänzt werden. Und da diese Items einen State vom Typ Number enthalten, muss das auch noch explizit erwähnt werden. Also eher so:
                          Code:
                          if (
                               EZ_Griff_1STATE.state == CLOSED &&
                               Astro_PhaseName.state.toString != "Day" &&
                               (EZ_Rol_1LEVEL.state as Number) == 0 &&
                               (WZ_Rol1LEVEL.state as Number) == 100 &&
                               (now.getHourOfDay() < 6) ||
                                now.getHourOfDay() > 16)
                             )
                          Beim letzten Teil sind natürlich Klammern notwendig, um das OR hierarchisch vor dem AND auszuführen. Der Zeitraum, in dem die Regel greift, ist dann 17 Uhr bis 5:59:59 Uhr.

                          Es gibt noch einen Stolperstein, denn die beiden Level könnten auch nicht vom Typ Number sein (wenn sie noch NULL sind). dann wird openHAB einen Fehlermeldung schmeißen. Entweder sorgt man dafür, dass der Status von Beginn an gesetzt ist, oder man fängt das vor dem eigentlichen Vergleich ab:
                          Code:
                          if(! EZ_Rol_1LEVEL.state instanceof Number) EZ_Rol_1LEVEL.postUpdate(0)
                          Dabei muss man sich allerdings genau überlegen, welchen Wert man hier als Default hinterlegt.

                          Kommentar


                            #14
                            Hallo udo1toni.
                            Das der Rollladen nach 23 Uhr gar nicht mehr runter fährt ist so gewollt, da die Tür schon mal genutzt wird, um sich ins Haus zu schleichen, wenn man mal später vom Nachbarn kommt als seine Frau. Wenn dann die Rolllade herunter fahren würde, dann könnte ich auch sofort klingeln.
                            Und das die Rolllade nicht vor 16 Uhr runter fahren soll, ist auch gewünscht.
                            Für den Notfall habe ich ja auch einen Schalter.
                            Tja, mal mit, mal ohne Klammern hatte ich bis jetzt nicht gewusst, aber habe es hoffentlich soweit für mich abgespeichert.

                            Dein letztes if habe ich nicht so richtig verstanden. Wie prüfe ich denn da auf NULL? Hat das etwas mit dem "!" am Anfang der Klammer zu tun (Hätte ich fast als Tippfehler interpretiert)

                            Den Rest schau ich mir mal an. Vielen Dank schon mal für die Hilfe. Wenn ich alles beisammen hab, bearbeite ich mal den 1. Post, so als kleines Programmschnipsel für andere.

                            Kommentar


                              #15
                              ...
                              Code:
                              if(! EZ_Rol_1LEVEL.state instanceof Number)
                              Hier wird nicht auf NULL getestet. Stattdessen wird geprüft, ob der übergebene Wert EZ_Rol_1LEVEL.state eine Instanz von Number ist. Wenn dies nicht der Fall ist (! ist das logische NOT) wird der nächste Befehl ausgeführt. Wie gesagt, das nur für den Fall, dass nicht sichergestellt ist, dass immer ein gültiger State zurückgeliefert wird.

                              Kommentar

                              Lädt...
                              X