Ankündigung

Einklappen
Keine Ankündigung bisher.

Rule, Aktion bei Temperatur größer gleich einem bestimmten Wert

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

    Rule, Aktion bei Temperatur größer gleich einem bestimmten Wert

    Hallo,

    ich bin gerade an einer Rule, also es soll eine Mail verschickt werden wenn der Temperaturwert über 22, 5 Grad geht, es funktioniert die Mail wird bei 22,5 Grad verschickt, jedoch wenn die Temperatur weiter steigt auf 22,6 Grad wird wieder eine Mail verschickt, dies möchte ich nicht wie kann man das anpassen ?


    Rule :
    Code:
    rule "T-Mail"
    when
        Item Weathe_Temper changed or
        Time cron "0 0 0 * * ?" or
        System started
    then
    var State = Weathe_Temper.state as DecimalType
    if (State >= 22.5) {sendMail("XYZ@gmail.com","Temperatur Wohnzimmer über 22.5 Grad","Temperatur Wohnzimmer über 22.5 Grad")}
    end

    evt. so aber das "and" geht so nicht :
    if (State >= 22.5 and State <= 22.5) {sendMail("XYZ@gmail.com","Temperatur Wohnzimmer über 22.5 Grad","Temperatur Wohnzimmer über 22.5 Grad")}


    Mfg Jürgen

    #2
    Moin Jürgen,

    du musst dir ein Flag definieren, welchen das einmalige erreichen der Temperatur quasi speichert.

    Code:
    Code:
    var boolean TempReached = false
    rule "T-Mail"
    when
    Item Weathe_Temper changed or
    Time cron "0 0 0 * * ?" or
    System started
    then
    var State = Weathe_Temper.state as DecimalType
    if ((State >= 22.5) && (TempReached == false))
    { sendMail("XYZ@gmail.com","Temperatur Wohnzimmer über 22.5 Grad","Temperatur Wohnzimmer über 22.5 Grad")
    TempReached = true
    }
    end
    Die Boolsche Prüfung kann man auch eleganter machen z.B. !TempReached

    Thomas

    Kommentar


      #3
      Hallo Thomas,

      Danke für die Antwort, ich habs jetzt noch ein bischen anders gelöst über das "&&" :

      Code:
      rule "T-Mail"
      when
          Item Weathe_Temper changed or
          Time cron "0 0 0 * * ?" or
          System started
      then
      var State = Weathe_Temper.state as DecimalType
      if ((State >= 22.5) && (State <= 22.6)) {sendMail("XYZ@gmail.com","Temperatur Wohnzimmer 22.5 Grad","Temperatur Wohnzimmer 22.5 Grad")}
      if ((State <= 20.0) && (State >= 19.9)) {sendMail("XYZ@gmail.com","Temperatur Wohnzimmer 20.0 Grad","Temperatur Wohnzimmer 20.0 Grad")}
      end
      Jürgen
      Zuletzt geändert von Juergen151; 07.01.2017, 00:29.

      Kommentar


        #4
        Hallo Jürgen,

        Ich hatte ein ähnliches Problem und habe es auf die unten stehende Art gelöst, ich hoffe das hilft Dir und anderen weiter.
        Bei mir handelt es sich um den VOC Wert, lässt sich aber auch beliebig auf andere Werte abändern.
        Das größte Problem war für mich auch, dass bei jeder Änderung wieder eine neue Nachricht gesendet wurde. Wichtig war auch das z.B wenn der Wert auf über 1100ppm steigt ich eine Nachricht erhalte, der Wert aber (wie beim Lüften) auf 450 ppm fällt und wieder zurück auf 1100ppm, ich eine neue Benachrichtung erhalte.

        Code:
         var int reset_voc_wz = 0
         var int begrenzung_voc = 0
        
        rule "VOC Wohnzimmer"
        
        when
        
            Item OG_WZ_VOC_01_VOC changed 
        
        then
        
        if(OG_WZ_VOC_01_VOC.state > 1100 && reset_voc_wz == 0 && begrenzung_voc < 3) {
                var int voc_wert = (OG_WZ_VOC_01_VOC.state as DecimalType).intValue
                sendTelegram("bot1", "Wohnzimmer lüften, VOC Wert beträgt %s ppm CO2", voc_wert)
                reset_voc_wz = 1
                begrenzung_voc = begrenzung_voc + 1
                createTimer(now.plusSeconds(1200)) [|reset_voc_wz = 0]
                    }
        
        else if(OG_WZ_VOC_01_VOC.state < 452) {
            reset_voc_wz = 0
            begrenzung_voc = 0
              }
        end

        Ich hoffe ich konnte Dir und anderen weiter helfen, ich habe lange nach einer Lösung gesucht, bin aber dann selber an das Problem ran gegangen weil ich, bei den vielen Beispielen, immer finde dass sie zu kompliziert sind. Ich versuche immer alles soweit wie möglich zu vereinfachen um Bugs aus den Weg zu gehen.

        Achja die Regel wurde mit openHAB 2 getestet.

        LG

        Kommentar


          #5
          Zitat von Juergen151 Beitrag anzeigen
          Hallo Thomas,

          Danke für die Antwort, ich habs jetzt noch ein bischen anders gelöst über das "&&" :
          Wenn die Temperatur allerdings von 22.4 auf 22.7 springt kommt keine Mail.
          Das mit dem Flag ist da besser.
          Holger

          Kommentar


            #6
            Hallo zusammen,

            ich hoffe es ist ok, wenn ich diesen älteren Thread verwende, aber ich stehe vor der gleichen Problematik und hätte ein paar Verständnisfragen bzgl. des Codes, der hier diskutiert wurde.

            Zunächst zur when-Bedingung im Code des Threaderstellers:

            Code:
            when
            Item Weathe_Temper changed or
            Time cron "0 0 0 * * ?" or
            System started
            Warum wird die Regelausführung neben der Änderung des Item-Wertes auch täglich und bei Systemstart vorgenommen? Soll das einfach nur sicher stellen, dass mindestens einmal täglich die Temperatur gecheckt wird oder gibt es noch einen anderen Grund?

            Dann zum Vorschlag von dibbler42 bzgl. des Codes.

            Code:
             
            var boolean TempReached = false
            rule "T-Mail"
            when
            Item Weathe_Temper changed or
            Time cron "0 0 0 * * ?" or
            System started
            then
            var State = Weathe_Temper.state as DecimalType
            if ((State >= 22.5) && (TempReached == false))
            { sendMail("XYZ@gmail.com","Temperatur Wohnzimmer über 22.5 Grad","Temperatur Wohnzimmer über 22.5 Grad")
            TempReached = true
            }
            end
            Diesen Vorschlag fand ich sehr passend und habe ihn auch verwendet. Aber müsste die Variable "TempReached" nach Ausführung des Codes nicht wieder auf "false" zurückgesetzt werden, sobald die Temperatur bei der nächsten Messung wieder unter 22.5 Grad liegt? Sonst würde die Regel doch nur exakt ein einziges Mal ausgeführt werden oder?

            Gruß
            Timo

            Kommentar


              #7
              Ja, das Flag muss irgendwann zurückgesetzt werden, zeitgesteuert, dann wird die Meldung ggf. wiederholt oder aufgrund des Unterschreitens der Temperatur.

              ich würde dabei eine kleine Hysterese defenieren, um wiederholte Meldungen bei kleinen Schwankungen zu vermeiden. Also z.B. erst bei < 21.5 Grad und nicht bei < 22.5 zurücksetzen.

              Kommentar


                #8
                Danke für den Denkanstoss. Ich habe es jetzt mit "createTimer" versucht und meinen Code entsprechend angepasst.

                Zur besseren Veranschaulichung hier mein eigener Code für meinen Anwendungsfall:

                Code:
                // Variable für Timer und Zieltemperatur
                var Timer   timer = null
                var boolean Temp_erreicht = false
                
                // Temperaturüberwachung im Netzwerkschrank (reagiert bei über 50 Grad inkl. Prüfung, ob bereits eine Meldung raus ging)
                rule "Temperatur Netzwerkschrank"
                    when
                        Item Temp_EG_Technikraum_Netzwerk changed
                    then
                        if ((Temp_EG_Technikraum_Netzwerk.state > 50) && (Temp_erreicht == false)) {
                            if (timer==null) {
                            sendTelegram("openHABBot", "Temperatur im Netzwerkschrank ist über 50 Grad!")
                            Temp_erreicht = true
                            timer = createTimer (now.plusMinutes(60)) [|
                                Temp_erreicht = false
                                timer = null]
                            }
                        }
                end
                Würde das so funktionieren? Ich bin mir noch nicht so ganz sicher bzgl. der Syntax von createTimer und hab es mir aus der Doku und einem Beispiel zusammengebastelt. Ich möchte erreichen, dass nach einer Meldung über 50 Grad erst wieder frühestens nach 60 Minuten eine weitere Meldung generiert werden würde, sofern die Temperatur sich zwischenzeitlich geändert hat und weiterhin über 50 Grad liegt.

                Kommentar


                  #9
                  Ich denke, ich habe noch ein einfachere Lösung bzgl. der Rücksetzung des Flags entdeckt. Hier der Code.

                  Code:
                  // Variable zur Speicherung der Erreichung der Temperatur
                  var boolean Temp_erreicht = false
                  
                  // Temperaturüberwachung im Netzwerkschrank (reagiert bei über 50 Grad inkl. Prüfung, ob bereits eine Meldung raus ging)
                  rule "Temperatur Netzwerkschrank"
                      when
                          Item Temp_EG_Technikraum_Netzwerk changed
                      then
                          if ((Temp_EG_Technikraum_Netzwerk.state >= 50) && (Temp_erreicht == false)) {
                              Temp_erreicht = true
                              sendTelegram("openHABBot", "Temperatur im Netzwerkschrank ist über 50 Grad!")
                          }
                          else if (Temp_EG_Technikraum_Netzwerk.state <= 49) {
                              Temp_erreicht = false
                          }
                  end
                  Das sollte doch so funktionieren, oder?

                  Kommentar


                    #10
                    Kommt halt darauf an, was Du erreichen möchtest. Die Variante im Posting #9 wird exakt dann Alarm schlagen, wenn die Temperatur von unter 49°C auf 50°C oder darüber steigt. Wenn die Temperatur zwischen 49.000°C und 50.000°C pendelt, bekommst Du jedes Mal einen Alarm. Da das Delta mit 1°C relativ breit ist, wird es nicht all zu viele Meldungen geben.
                    Die Variante in Posting #8 wird jede Stunde eine Alarmmeldung ausgeben, solange die Temperatur über 50°C liegt, da erfahrungsgemäß ein Temperaturfühler immer minimal unterschiedliche Werte liefert, somit triggert die Rule bei jedem Temperaturupdate, die erste Hälfte der Bedingung ist erfüllt und die zweite Hälfte wird stündlich zurückgesetzt, ist also einmal pro Stunde ebenfalls erfüllt.

                    Man kann mit der ersten Variante noch etwas eleganter eine stündliche Erinnerung erreichen und erschlägt auch das Problem, dass ein Fallen der Temperatur unter 49°C und ein erneutes Steigen über 50°C nicht unmittelbar zu einem neuen Alarm führt:
                    Code:
                     // Variable für Timer
                    var Timer   tTemp = null
                    
                    // Temperaturüberwachung im Netzwerkschrank
                    rule "Temperatur Netzwerkschrank"
                    when
                        Item Temp_EG_Technikraum_Netzwerk changed
                    then
                        if(Temp_EG_Technikraum_Netzwerk.state instanceof Number) {
                            if((Temp_EG_Technikraum_Netzwerk.state as Number) >= 50) {
                                if(tTemp === null)
                                    tTemp = createTimer (now, [|
                                        sendTelegram("openHABBot", String::format("Die Temperatur im Netzwerkschrank beträgt %.1f°C!",(Temp_EG_Technikraum_Netzwerk.state as Number).floatValue))
                                       tTemp.reschedule(now.plusMinutes(60))
                                   ])
                            } else if((Temp_EG_Technikraum_Netzwerk.state as Number) < 49.8) {
                                tTemp?.cancel
                                tTemp = null
                            }
                        }
                    end
                    Der Timer läuft, sobald die Temperatur über 50°C steigt. Somit kann er auch als Indikator dienen. Innerhalb des Lambdas wird die Meldung ausgegeben, anschließend wird der Timer neu geplant. Sobald die Temperatur unter 49.8°C sinkt, wird der Timer abgebrochen und beim nächsten Ansteigen über 50°C wieder erzeugt.

                    Der Hauptunterschied besteht also im Fehlen des Flags und der anderen Verwendung des Timers (insbesondere wird der erste Timer mit der aktuellen Zeit angelegt, das heißt, das Lambda wird zuerst unmittelbar ausgeführt.
                    Falls die Temperatur noch nicht unter 49.8°C gesunken ist, wird die Meldung natürlich weiterhin stündlich ausgegeben.
                    Zuletzt geändert von udo1toni; 06.01.2019, 00:54.

                    Kommentar


                      #11
                      Vielen Dank für den überarbeiteten Code!

                      Ich habe ihn übernommen, erhalte aber ein paar Fehler im log.

                      Code:
                      2019-01-02 17:44:23.292 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'Temperatur Netzwerkschrank.rules' has errors, therefore ignoring it: [12,42]: mismatched input ',' expecting '}'
                      
                      [15,17]: extraneous input ')' expecting '}'
                      
                      [17,13]: no viable alternative at input 'tTemp'
                      
                      [20,5]: extraneous input '}' expecting 'end'
                      Konkret geht es um die folgenden Codezeilen:

                      12,42: tTemp = createTimer (now), [|
                      15,17: ])
                      17,13: tTemp?cancel
                      20,5 : }

                      Bei 15,17 war wohl nur die ) zu viel, die habe ich entfernt und bei 17,13 habe ich das ? durch einen . ersetzt. Müsste so passen, oder? Nach der Überarbeitung bleiben aber noch die Fehler bei 12,42 (gemeint ist das , hinter (now)) und 20,5 (da gibt es nur die }) übrig. Ich kann hier aber keine Fehler mehr erkennen.

                      Hast Du eine Idee, woran es noch liegen könnte?

                      Kommentar


                        #12
                        Ich vermute den Fehler beim ersten "createTimer". Wenn ich die Syntax richtig verstehe, muss mit dem now gleich eine Zeitangabe erfolgen. Ich habe den Code zwar soweit umbauen können, dass es keine Fehlermeldungen mehr gab, aber die Tests mit niedrigeren Temperaturen verliefen negativ.

                        Ich habe jetzt die Variante aus Posting #8 mit niedrigeren Temperaturen erfolgreich getestet und verwende daher nun diesen Code. Von daher habe ich keinen weiteren Handlungsbedarf, da meine Anforderungen erfüllt wurden.

                        Falls aber doch noch jemand eine Idee hat, wo beim letzten Code die Fehler liegen, würde mich das interessieren. Man will ja schließlich dazu lernen. Und natürlich wäre der Code von udo1toni eine elegantere Lösung als meine.

                        Kommentar


                          #13
                          Da ist ein schließende Klammer rein gerutscht:
                          Code:
                          tTemp = createTimer (now), [|
                          muss eigentlich so ausshen:
                          Code:
                          tTemp = createTimer (now, [|
                          Kleine Ursache, große Wirkung...

                          now ist übrigens ein gültiger Zeitstempel, der für Jetzt steht.

                          Kommentar


                            #14
                            Danke für die Korrektur, sieht schon besser aus!

                            Jetzt gibt es nur noch eine Meldung hierzu:

                            Code:
                             
                             tTemp?cancel
                            Müsste anstatt des ? nicht ein . stehen?

                            Kommentar


                              #15
                              Njain... Es muss tTemp?.cancel heißen... Das ist gleichbedeutend mit
                              Code:
                              if(tTemp !== null) tTemp.cancel

                              Kommentar

                              Lädt...
                              X