Ankündigung

Einklappen
Keine Ankündigung bisher.

OH2 rule Wochentag, nur wenn Item ON

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

    OH2 rule Wochentag, nur wenn Item ON

    Hallo,
    bin gerade dabei die Bewässerung zu konfigurieren und spiel regelmäßig mit den Zeiten usw. rum. Nun meint mein Gärtner ich soll mal versuchen nur an zwei Tagen zu bewässern. Das wird mit steigender Temperatur dann sicher mehr und ich möchte nicht jedesmal in die cron Angaben der Rule eingreifen.

    Meine Idee war deshalb, für jeden Wochentag ein Switch-Item (WT_Mo / WT_DI / WT_MI ...) anzulegen und die Rule nach folgender Logik aufzubauen:
    Jeden Tag um 6 Uhr soll OH abchecken ob das Item WT_* (WT_Mo für Montag) für den jeweiligen Wochentag auf ON oder OFF und erst dann den weiteren Code der Rule abrattern.

    Klingt recht kompliziert oder zumindest nach Umweg, falls ihr ne bessere Idee habt - immer her damit! Falls es wirklich so gehen sollte, dann bräuchte ich allerdings auch noch den richtigen Code :/

    Grüße

    #2
    Je nachdem, wie Du die Bewässerung ansonsten auslöst, wäre es eventuell einfacher, in der Rule, die ohnehin die Bewässerung steuert, abzufragen, ob der zum Wochentag passende Schalter aktuell ON oder OFF ist. Wenn der Name für die einzelnen Switches geschickt gewählt ist, reichen da ca. 2 Zeilen Code.

    Code:
    Group WTWasser
    Switch WT_1 "Montag [%s]" (WTWasser)
    Switch WT_2 "Dienstag [%s]" (WTWasser)
    Switch WT_3 "Mittwoch [%s]" (WTWasser)
    Switch WT_4 "Donnerstag [%s]" (WTWasser)
    Switch WT_5 "Freitag [%s]" (WTWasser)
    Switch WT_6 "Samstag [%s]" (WTWasser)
    Switch WT_7 "Sonntag [%s]" (WTWasser)
    Code:
    rule "Bewaesserung"
    when
        Time cron "0 30 6 * 3-10 ?" // jeden Morgen 6:30, März bis Oktober
    then
        if(!rainy) { //falls kein Regen...
            if(WTWasser.members.filter(w|w.name=="WT_"+now.getDayOfWeek.toString && w.state==ON).size!=0) {
                //Starte die Bewässerung
            }
        }
    end
    Das ist natürlich nur ein Rumpf, schlimmer noch, ich hab's nicht wirklich getestet... Die Idee kann ich aber erläutern:
    Ich definiere eine Gruppe WTWasser, in der 7 Items für jeden Wochentag sind, die Items sind im Namen mit 1-7 "durchnumeriert".
    Dadurch reicht in der Rule tatsächlich eine einzige Zeile, in der die Gruppenitems gefiltert werden, nach solchen, deren Name den Tag der Woche enthalten und gleichzeitig den Status ON haben. Natürlich kann es maximal ein Item geben, welches diese Bedingungen erfüllt. Falls also mehr als Null Items die Filterbedingungen erfüllen, wird bewässert.
    Das Abschalten könnte natürlich immer passieren, erhöht die Zuverlässigkeit (falls jemand während das Wasser läuft den Schalter für den aktuellen Wochentag umlegt...)
    Zuletzt geändert von udo1toni; 01.04.2017, 20:06. Grund: Schlüsselwort korrigiert

    Kommentar


      #3
      Vielen Dank für deine Anwort!
      Vom Grundgedanken war ich eh bei der Idee. Die Benennung der Items versteh ich auch noch, aber zum Rule hab ich folgende Verständnisfragen.
      Code:
      if(!rainy) {
      woher weiß denn OH obs regnet oder nicht?
      Code:
      if(WTWasser.members.filter(w|w.name=="WT_"+now.dayOfWeek.toString && w.state==ON).size!=0) {
      Kann man das irgendwie aufschlüsseln, dass mans (bzw. ich) auch versteht - so wie die Excel Formelauswertung?
      Wäre mir sicher für weitere Rules ein große Hilfe. So scheiterts (vom Verständnis her) schon ganz früh...

      Vielen Dank inzwischen, werde den Code am Abend auf jeden Fall testen!
      Grüße

      Kommentar


        #4
        Also, das if(!rainy) war nur als Andeutung gemeint, dass man die Bewässerung auch vom Wetter abhängig machen müsste, hatte ich dann vergessen, bei der Erläuterung mit dazu zu schreiben, sorry.

        Die Aufschlüsselung der Zeile sieht wie folgt aus:
        • WTWasser ist die Gruppe
        • .members meint alle unmittelbar der Gruppe zugehörigen Items. Falls innerhalb der Gruppe weitere Gruppen vorhanden sind, werden diese nicht berücksichtigt.
        • .filter() bewirkt eine Filterung der übergebenen Liste, in diesem Fall wird also nur ein Teil der Gruppe betrachtet. Welcher das ist, steht in der Klammer.
        • w| definiert den Bezeichner für das einzelne Gruppenmitglied, der Reihe nach wird jedes einzelne Gruppenmitglied zu w, so dass die nachfolgenden Operationen immer auf ein einzelnes Gruppenmitglied bezogen sind.
        • w.name ist der Name des Items, also WT_1 bis WT_7
        • now liefert den aktuellen Zeitpunkt mitsamt Datum, entsprechend liefert
        • now.getDayOfWeek den Wochentag als Zahl (1 - 7). Weil wir die Zahl in einen String einbauen wollen, hängt noch ein
        • .toString dran, diese Methode liefert den Wert als String zurück (allerdings nur, wenn es auch eine gültige Zahl gibt, aber .getDayOfWeek liefert immer eine Zahl, passt also)
        • Die erste Bedingung des Filters ist, dass .name == "WT_" + now.getDayOfWeek.toString ist, also z.B. am Montag soll der Name des Items WT_1 sein, am Dienstag soll der Name WT_2 sein usw.
        • Die zweite Bedingung ist .state==ON, der Status des Items muss also ON sein
        • Beide Bedingungen sind mit && verknüpft, das ist das bool'sche Und, es müssen also beide Bedingungen erfüllt sein.
        • .size schließlich gibt die Anzahl der Items zurück, die der Filter liefert. Da je Wochentag genau ein Item vorhanden ist, kann immer maximal ein Item zurückgeliefert werden, falls der aktuelle Wochentag auch eingeschaltet ist, dieser Teil der Zeile liefert also entweder 0 oder 1, die drum herum liegende if()-Bedingung prüft, ob der gelieferte Wert != (ungleich) 0 ist.

        Zuletzt geändert von udo1toni; 01.04.2017, 20:07. Grund: Schlüsselwort korrigiert

        Kommentar


          #5
          Super Sache, vielen Dank! Natürlich wärs Klasse, wenn ich die Bewässerung vom Wetter abhängig machen könnte. Mal schauen, wie man das "rainy" generieren kann. Aber Eines nach dem Anderen!

          Werde (hoffentlich) am Wochenende den Part hier einbauen, aber ein Problem, welches ich bereits jetzt habe wird bestehen bleiben: die Automatik (derzeit für jeden Tag zur Bestimmten Zeit eine bestimmte Dauer) wird beim Reboot automatisch über Rule eingeschalten. Nun verliert openHAB ja beim Reboot den Status des Items (Switch).

          Wie kann ich denn openHAB dazu bringen, sich den Status zu merken? Muss ich wirklich über Persistence gehen? Da würde ja eine Datenbank angelegt, oder? Bissl overkill für "letzten Status".

          Gruß

          Kommentar


            #6
            Du musst nur die betreffenden Items persistieren und mit restoreOnStartup automatisch wiederherstellen lassen. MapDB ist speziell für den Restore gut geeignet, da es sich exakt den aktuellen Status merkt. Ansonsten kannst Du auch andere Persistence Services verwenden, rrd4j, InfluxDB oder auch JDBC (MySQL, Postgre SQL, SQLite, Maria DB,...), je nachdem, was Du mit "historischen" Daten tun möchtest, gibt es jeweils Vor- und Nachteile.
            Zu den SQL Datenbanken ist zu sagen, dass es hier vor allem auf den Geschmack oder auch schon vorhandene SQL Engines ankommt, wenn schon irgendwo zuhause ein MySQL läuft, muss man nicht mit PostgreSQL anfangen, vielleicht hat man Auswertungstools, die einem ans Herz gewachsen sind, oder...

            Ansonsten läuft beispielsweise Grafana sehr gut mit einem darunter liegenden InfluxDB, die mitgelieferte Chart Engine wiederum funktioniert mit rrd4j (welches auch den Vorteil bietet, eine fixe Dateigröße zu haben - dafür aber unter Verlust der zeitlichen Genauigkeit, je älter die Daten sind).

            Konkret legst Du nach Installation von MapDB über Paper UI (Addons->Persistence->MapDB) eine Datei /etc/openhab2/persistence/mapdb.persist an, mit folgendem Inhalt:

            Code:
            // MapDB persistence service
            
            Items {
                    // let's store items to restore on startup
                    WTWasser* : strategy = everyChange,restoreOnStartup
            }
            Danach sollte bei Neustart der Zustand der Items WT_1 bis WT_7 erhalten bleiben.

            Erklärung zur Syntax: Im Persistence File hat das * die Bedeutung "das vorstehende Item ist eine Gruppe, persistiere nicht die Gruppe, sondern die Gruppenmitglieder."
            Ansonsten kannst Du auch einzelne Items oder auch Gruppen (ohne deren Mitglieder) (dann ohne Stern) hier auflisten, mit Komma getrennt.
            Es gibt auch die Möglichkeit, auf zeitlichen Trigger oder bei Updates zu persistieren, kommt halt immer auf die Anwendung an.

            Spätestens, wenn Du in einer Rule den letzten Status eines Items (oder z.B. den Durchschnitt über einen bestimmten Zeitraum) auswerten willst, kommst Du mit der Persistence in Berührung.

            Kommentar


              #7
              Sehr geil, danke!

              Kommentar


                #8
                Hmm, habs mal mit meinem einzigen Schalter versucht, klappt leider nicht:

                item:
                Code:
                Switch BW_Auto "Bewässerung Automatik" (AB_Garten)
                mapdb.persist
                Code:
                // MapDB persistence service
                
                Items {
                        // let's store items to restore on startup
                        BW_Auto : strategy = everyChange,restoreOnStartup
                }
                mit dem BW_Auto Switch schalte ich derzeit meine Automatik:
                Code:
                rule "Garten Beregnung auto"
                when
                Time cron "0 0 7 * * ?"
                then
                if (BW_Auto.state == ON) {
                var int Laufzeit = (BW_Auto_LZ.state as DecimalType).intValue
                sendCommand(BW_Z1, ON)
                createTimer(now.plusMinutes(Laufzeit))[|
                sendCommand(BW_Z1, OFF)]
                }
                end
                Wenn ich nun die Automatik einschalte geht BW_Auto auf ON:
                Code:
                2017-03-30 23:50:46.122 [ItemCommandEvent          ] - Item 'BW_Auto' received command ON
                2017-03-30 23:50:46.129 [ItemStateChangedEvent     ] - BW_Auto changed from OFF to ON
                Doch nach Neustart hab ich nun wieder OFF:
                Code:
                2017-03-30 23:54:17.698 [ItemRemovedEvent ] - Item 'BW_Auto' has been removed.
                ???
                Und in der Sitemap scheint mir der Switch auch wieder auf AUS zu stehen.

                Kommentar


                  #9
                  Hmmm... vielleicht ist der Strategy-Teil des Files nicht optional (ich hatte den weg gelassen, weil er für die Aufgabe unnötig ist). Leg das File mal so an:
                  Code:
                   // MapDB persistence service
                  
                   Strategies {
                          // we don't need a cron strategy, but maybe...
                          everyMinute : "0 * * * * ?"
                  }
                  
                  Items {
                          // let's store items to restore on startup
                          BW_Auto : strategy = everyChange,restoreOnStartup
                  }

                  Kommentar


                    #10
                    Scheint nun nach mehrmaligem Reboot zu klappen. Ansonsten meld ich mich schon nochmal
                    Danke inzwischen
                    Zuletzt geändert von narf; 31.03.2017, 14:40.

                    Kommentar


                      #11
                      Wollt's jetzt auch mit den Wochentagen implementieren, bekomme aber folgenden Fehler:
                      Code:
                      2017-04-01 14:07:03.334 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule Bewaesserung: The name '<XMemberFeatureCallImplCustom>.toString' cannot be resolved to an item or type.

                      Kommentar


                        #12
                        versuch mal statt .dayOfWeek. .getDayOfWeek. (blöderweise gibt es beides, ich komme dann gerne mal durcheinander... ich hab's oben schon korrigiert, falls jemand anderes hierüber stolpert.)
                        Zuletzt geändert von udo1toni; 01.04.2017, 20:08.

                        Kommentar

                        Lädt...
                        X