Ankündigung

Einklappen
Keine Ankündigung bisher.

Erkennen, ob es heute schon geregnet hat

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

    #16
    Ja richtig, regen_count als Item und persistieren,dann ist es auch nach einem Neustart wieder da.
    Regen pro Woche dann vielleicht als 2. Item welches jedesmal beim Rücksetzen der täglichen Werte aufaddiert wird.

    Holger

    Kommentar


      #17
      Also erstmal vielen Dank für die Hilfe. Ich habe es jetzt so mal getestet und so läuft es.
      Was natürlich für die Zukunft schick wäre:
      • rollierende Ermittlung der Wochenregenzeit
      • Umrechnung der Minuten in Stunden:Minuten (Modulo...)
      Da werde ich noch etwas herumknobeln.

      Viele Grüße,
      HajoKA

      Code:
      var Integer regen_count = 0
      rule "minuetliche Werte"
      when[INDENT]Time cron "0 * * * * ?"[/INDENT]
       
       then[INDENT]if (wetter_regen.state == OPEN ) regen_count = regen_count +1[/INDENT][INDENT]if (wetter_regen.state == OPEN ) Regenminuten.postUpdate(regen_count)[/INDENT][INDENT]if (wetter_regen.state == OPEN ) RegenminutenWoche.postUpdate(regen_count)[/INDENT][INDENT]if (regen_count >= 60) Regen_in_24h.postUpdate(OPEN)[/INDENT][INDENT]if (now.getHourOfDay() == 20 && now.getMinuteOfHour() == 0) {[/INDENT][INDENT=2]regen_count = 0[/INDENT][INDENT]        Regen_in_24h.postUpdate(CLOSED)[/INDENT][INDENT]}[/INDENT]
       
       end
      rule "Montags Reset"
      when[INDENT]Time cron "0 1 20 ? * MON *"[/INDENT]
       
       then[INDENT]RegenminutenWoche.postUpdate(0)[/INDENT]
       
       end
      Zuletzt geändert von hajoka; 16.09.2018, 20:19.

      Kommentar


        #18
        Warum setzt Du den Regenzähler um 20 Uhr auf null zurück? Normalerweise beginnt der Tag doch um 0 Uhr...

        Da Du die ersten drei mal die gleiche Bedingung verwendest, kannst Du auch gleich den Block klammern und nur einmal die Bedingung abfragen (so wie bei der letzten Bedingung).
        Was den Wochenzähler betrifft, sollte es reichen, den hochzuzählen. Am einfachsten geht das so:
        Code:
        if (!(RegenminutenWoche.state instanceof Number)) { //Nur für den Fall, dass das Item nicht initialisiert ist
            RegenminutenWoche.postUpdate(0) //Item mit 0 initialisieren
            Thread::sleep(300)  // openHAB ein bisschen Zeit geben
        }
        RegenminutenWoche.postUpdate((RegenminutenWoche.state as Number) + 1)
        Wahlweise kannst Du das natürlich genauso machen, wie bei den Minuten (also mit einer Variablen)

        Kommentar


          #19
          Zitat von udo1toni Beitrag anzeigen
          Warum setzt Du den Regenzähler um 20 Uhr auf null zurück? Normalerweise beginnt der Tag doch um 0 Uhr...
          Da Du die ersten drei mal die gleiche Bedingung verwendest, kannst Du auch gleich den Block klammern und nur einmal die Bedingung abfragen (so wie bei der letzten Bedingung).
          Wahlweise kannst Du das natürlich genauso machen, wie bei den Minuten (also mit einer Variablen)
          Guten Morgen,

          20h deshalb, weil das meine normale Beregnungszeit ist. Da schaut er, wieviel Regen in den letzten 24 fiel (und soll dann mal entscheiden, ob er die Beregnungsventile öffnet). Danach wird neu gezählt. Das erschien mir so am logischsten.

          Ja, dass mein Code sagen wir mal etwas "traditionell" ist, ist mir klar. Daher auch meine Frage der Guidance zur Programmierung. Ich habe zwar zurückliegende Programmiererfahrung, aber nicht mit Java. Daher taste ich mich da so ran. Ich habe es mittlerweile auch geklammert. Nur: das ist bei mir halt "trial and error". Wenn es funktioniert, dann lasse ich es im Zweifel stehen. Und die Testläufe haben gestern Abend sehr gut geklappt.

          VG Hajoka

          Kommentar


            #20
            Zitat von hajoka Beitrag anzeigen
            20h deshalb, weil das meine normale Beregnungszeit ist. Da schaut er, wieviel Regen in den letzten 24 fiel (und soll dann mal entscheiden, ob er die Beregnungsventile öffnet). Danach wird neu gezählt. Das erschien mir so am logischsten.
            Ja,so ergibt es natürlich Sinn.
            Ja, dass mein Code sagen wir mal etwas "traditionell" ist, ist mir klar. Daher auch meine Frage der Guidance zur Programmierung. Ich habe zwar zurückliegende Programmiererfahrung, aber nicht mit Java. Daher taste ich mich da so ran. Ich habe es mittlerweile auch geklammert. Nur: das ist bei mir halt "trial and error". Wenn es funktioniert, dann lasse ich es im Zweifel stehen. Und die Testläufe haben gestern Abend sehr gut geklappt.
            Keine Frage, funktioniert genauso. Ich war nur irritiert, weil Du vier Zeilen weiter unten bewiesen hast, dass Du die Klammern { } und deren Funktion bereits kennst

            Es sollte noch eine andere Möglichkeit (ohne extra Rules) geben, nämlich wenn Du dafür sorgst, dass der Regensensor nicht OPEN und CLOSED zurück gibt, sondern 1 und 0 (kommt auf den Sensor und das zugrunde liegende Binding an, wie kompliziert das ist.) Dann kannst Du den Sensor als Number Item abbilden und dieses über eine Persistence Policy ausschließlich minütlich speichern lassen.
            In den Rules kannst Du
            Code:
            MyNumSensor.sumSince(now.withTimeStartOfDay.minusHours(4))
            verwenden, um die Anzahl Regenminuten seit gestern 20 Uhr zu erhalten, entsprechend auch
            Code:
             MyNumSensor.sumSince(now.withTimeStartOfDay.minusDays(now.getDayOfWeek - 1))
            für die Wochensumme. Diese Daten brauchst Du dann nur in der Rule aufzurufen, in der Du sie benötigst (um zu bestimmen ob und wie lange die Bewässerung laufen soll...), es läuft also im Zweifel nur einmal am Tag eine Rule, statt jede Minute.

            Allerdings hat der Ansatz über die Rules den angenehmen Nebeneffekt, dass Du problemlos eine aktuelle Anzeige der Regendauer erhältst, was bei der beschriebenen Methode mangels Item nicht gegeben ist.
            Dafür könntest Du aber problemlos einen Graphen einbinden, der die Regendauer über die Zeit abbildet, was bei Deiner Lösung nicht ohne weiteren Aufwand zu erledigen ist, hat also alles seine Vor- und Nachteile.

            Kommentar


              #21
              Würde das so funktionieren?

              Irrigigation_Time ist ein number item, das über setpoint in der Sitemap gesetzt wird. Damit kann ich die Beregnungsdauer einstellen.

              Ich sehe zwei Unklarheiten:
              Kann ich das Number Item so in den Timer schreiben?
              Öffnen Ventil eins (Node15/2), nach der definierten Zeit schließen, eine Minute Pause, dann Öffnen Ventil zwei (Node15/1). Danach abschalten...
              Und die zweite Frage ist, wie ich von der Syntax mehrere Befehle in einen Timer unterbringe (letztes Abschalten + Nachrichtenversand). Sie einfach so ohne Semikolon o.ä. hereinzuschreiben fände ich ungewohnt. Allerdings meldet das Logfile keinen Fehler in der RUle.

              Aber: vielen Dank. Mit "harten Zahlen" eingetragen funktioniert es.

              Code:
              [FONT=courier new](...)
              if (regen_count < 60)
              {
              sendNotification("xx@xxx.com", "Regnerzyklus läuft")
              Node15_Switch2.sendCommand(ON)
              timer=createTimer(now.plusMinutes(Irrigation_Time)) [| Node15_Switch2.sendCommand(OFF) ]
              timer=createTimer(now.plusMinutes(Irrigation_Time+1)) [| Node15_Switch1.sendCommand(ON) ]
              timer=createTimer(now.plusMinutes(Irrigation_Time+Irrigationtime+1)) [| Node15.Switch1.sendCommand(OFF) sendNotification("xx@xxx.com", "Regnerzyklus beendet") ]
              }
              (...)[/FONT]
              Zuletzt geändert von hajoka; 22.09.2018, 08:28.

              Kommentar


                #22

                Du musst den State von Irrigation_Time casten:

                Code:
                (Irrigation_Time.state as Number)
                (Irrigation_Time.state as Number) + 1
                gibt dir den numerischen Wert aus. Evtl vorher den State noch auf NULL prüfen.

                Klar, du kannst mehrere Befehle in einen Timer aufnehmen, hier mein Wecker z.b.:
                Code:
                 [COLOR=#d4d4d4]createTimer(now[/COLOR][COLOR=#d4d4d4].[/COLOR][COLOR=#d4d4d4]plusSeconds([/COLOR][COLOR=#b5cea8]60[/COLOR][COLOR=#d4d4d4]), [ |[/COLOR]
                  [COLOR=#d4d4d4]                harmonyStartActivity([/COLOR][COLOR=#ce9178]"Radio"[/COLOR][COLOR=#d4d4d4])[/COLOR]
                  [COLOR=#4ec9b0]Thread[/COLOR][COLOR=#c586c0]::[/COLOR][COLOR=#d4d4d4]sleep([/COLOR][COLOR=#b5cea8]1000[/COLOR][COLOR=#d4d4d4]) [/COLOR]
                  [COLOR=#d4d4d4]                harmonyPressButton([/COLOR][COLOR=#ce9178]"MarantzAVReceiver"[/COLOR][COLOR=#d4d4d4], [/COLOR][COLOR=#ce9178]"InputInternetRadio"[/COLOR][COLOR=#d4d4d4])[/COLOR]
                  [COLOR=#4ec9b0]Thread[/COLOR][COLOR=#c586c0]::[/COLOR][COLOR=#d4d4d4]sleep([/COLOR][COLOR=#b5cea8]5000[/COLOR][COLOR=#d4d4d4]) [/COLOR]
                  [COLOR=#d4d4d4]                harmonyPressButton([/COLOR][COLOR=#ce9178]"SonyTV"[/COLOR][COLOR=#d4d4d4], [/COLOR][COLOR=#ce9178]"PowerOff"[/COLOR][COLOR=#d4d4d4])[/COLOR]
                  [COLOR=#d4d4d4]            ])[/COLOR]

                Holger

                Kommentar


                  #23
                  Wie schon an andere Stelle mehrfach erwähnt, Thread::sleep(int) sollte nur für kurze (int <= 500) Wartezeiten verwendet werden, da es den Thread blockiert und openHAB nur 5 Threads zur Ausführung von Rules zur Verfügung hat.
                  createTimer() erwartet als Argumente zum einen eine Zeitangabe als absoluten unix-Zeitstempel, zum anderen ein Lambda (das ist alles, was zwischen zwei eckigen Klammern [] steht). Das Lambda wird bei Ablauf des Timers ausgeführt. Es spielt keine Rolle, wie viele Befehle im Lambda stehen.
                  now liefert den Zeitstempel. Die Methode .plusMinutes() erwartet (wie eigentlich alle Methoden von now) zwingend ein integer als Argument, Du musst also sicherstellen, dass Dein State vom Typ Integer ist.
                  In Deiner Rule setzt Du dreimal hintereinander einen Timer, aber Du verwendest jedesmal den gleichen Handle (die Variable timer), was im besten Fall dazu führt, dass Du nur keinen Zugriff auf den Timer mehr hast, vielleicht wird auch nur der zuletzt definierte Timer ausgeführt, weil der andere Code jeweils überschrieben wird, oder openHAB beginnt, sich seltsam zu verhalten

                  Allgemein muss man sich immer überlegen, was denn da eigentlich passiert.
                  Du hast zwei Regner, der erste Regner wird gestartet, nach Ablauf einer festgelegten Zeit wird der Regner gestoppt, nach einer Minute wird der andere Regner gestartet, nach Ablauf der festgelegten Zeit wird auhc der zweite Regner gestoppt und eine Nachricht versendet.
                  das Ganze ist quasi ein Programmschalter zur Ablaufsteuerung, so wie er früher in Waschmaschinen oder Gschirrspülern verbaut war. Was Du also brauchst, ist eine solche Ablaufsteuerung.:
                  1. ein Programmschrittzähler
                  2. ein Timer
                  Eine Rule, wie man soetwas realisiert habe ich hier gepostet: https://community.openhab.org/t/trin...e-rule/50832/4 Notfalls kann ich diese Rule angepasst auf die regner hier nochmal erstellen

                  Kommentar

                  Lädt...
                  X