Ankündigung

Einklappen
Keine Ankündigung bisher.

Betriebsstunden Zähler

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

    Betriebsstunden Zähler

    Hallo, ich würde gern in Openhab die Betriebsstunden von einem Betriebsmittel zählen.

    Leider fehlt mir dabei jeglicher Ansatz. Bei einer steigenden Flanke von einem Bool wert soll die Zeit gemessen werden bei einer fallenden endet die Zeitmessung.
    Beim nächsten Zyklus soll die dann ermittelte Zeit zu dem ersten wert addiert werden.
    Hat jemand so etwas schon mit Openhab gemacht ?

    Danke und Gruß

    Guido
    Gruß

    Guido

    #2
    Na ja, Flanken kann openHAB strenggenommen ja nicht... aber so:
    Code:
    // Globale Variablen immer zu Beginn der Datei definieren!
    
    var DateTime dtStart = null
    
    rule "Einschaltzeit bestimmen"
    when
        Item myItem changed
    then
        if(previousState == NULL) return;
        if(myItem.state == ON)
            dtStart = now
        if(myItem.state == OFF) {
            var Number nDiff = now.millis - dtStart.millis
            myCounter.postUpdate((myCounter.state as Number) + nDiff/3600000)
        }
    end
    Bei dem Code gehe ich davon aus, dass myCounter ein Number Item ist, welches volle Stunden und deren Bruchteile anzeigt. Dieses Item muss logischerweise persistiert werden, z.B. mit mapdb, es sei denn, man möchte auch historische Werte verwenden, dann natürlich eher rrd4j oder eine sql Variante.
    Sobald das Item seinen Status ändert, triggert die Rule. War der alte Status NULL, wurde openHAB gerade gestaret und die Rule bricht ab.
    Ist der aktuelle Status ON, wird der aktuelle Zeitpunkt gespeichert, ist er OFF, wird die Differenz zum Start berechnet und auf den Counter aufaddiert.

    Kommentar


      #3
      Hallo Udo,

      vielen Dank für den Code und die Erklärungen.

      Ich werde das gleich mal probieren.

      Grüße
      Gruß

      Guido

      Kommentar


        #4
        Wenn es nicht ganz so genau sein muss kann man das mit einem Timer machen.
        Bei mir löst der einmal pro Minute aus und schaut ob das Gerät eingeschaltet ist und erhöht einen persistierten Minutenzähler.
        Das hat mir ausgereicht.

        Holger

        Kommentar


          #5
          Na ja, ganz ehrlich... Polling ist ziemlich an der openHAB Philosophie vorbei. Warum 1440 mal pro Tag eine Rule ausführen, wenn es auch ausreicht, das zehn oder zwanzig mal am Tag zu tun? Die Auflösung in Millisekunden ist nur der Tatsache geschuldet, dass DateTime auf Millisekunden basiert, sprich, das macht am wenigsten Arbeit...

          Kommentar


            #6
            Hallo,

            leider funktioniert der Zähler nicht.

            muss es
            previousState == NULL) return; oder myitem.previousState == NULL) return;

            if(myItem.state == ON) dtStart = now
            oder
            if(myItem.state == ON) { dtStart = now} heißen?
            Gruß

            Guido

            Kommentar


              #7
              Die Rule ist so eigentlich schon richtig. es kann allerdings sein, das openHAB sich an ein, zwei Dingen stört. Ich hab deshalb mal den Startwertspeicher geändert.

              Ergänze bitte auch ein bisschen Logging:
              Code:
              // Globale Variablen immer zu Beginn der Datei definieren!
              
              var Number nStart = null
              
              rule "Einschaltzeit bestimmen"
              when
                  Item myItem changed
              then
                  logInfo("duration","Rule gestartet!")
                  if(previousState == NULL) {
                      logInfo("duration","Alter Wert war NULL, Abbruch!")
                      return;
                  }
                  if(myItem.state == ON) {
                      nStart = now.millis
                      logInfo("duration","myItem wurde eingeschaltet. Startwert {}",dStart)
                  }
                  if(myItem.state == OFF) {
                      var Number nDiff = now.millis - nStart
                      logInfo("duration","myItem wurde ausgeschaltet. Differenz {}",nDiff)
                      myCounter.postUpdate((myCounter.state as Number) + nDiff/3600000)
                  }
              end
              Was das klammern betrifft: {} sind genau dann erforderlich, wenn man mehrere Anweisungen zu einem Block zusammenfassen muss. z.B. weil vorher ein if steht (nur die nachfolgende Anweisung wird bedingt ausgeführt). Da nun logInfo in jedem der Blöcke steht, muss zwangsläufig auch überall geklammert werden.


              Zuletzt geändert von udo1toni; 07.09.2019, 06:11. Grund: EDIT: Variablennamen dem neuen Typ angepasst (dtStart -> nStart)

              Kommentar


                #8
                Hallo Udo,

                logging hatte ich schon hinzugefügt, die Rule wird getriggert und auch der ON Status wird ausgeführt. aber der Off Status wird offensichtlich nicht erkannt.
                Gruß

                Guido

                Kommentar


                  #9
                  Gibt es Fehlermeldungen? Eventuell gibt es ja eine exeption, bevor das Logging ausgegeben wird...

                  Kommentar


                    #10
                    dieser code steht beim ausschalten

                    2019-09-06 22:26:10.421 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Einschaltzeit bestimmen': An error occurred during the script execution: Could not invoke method: org.eclipse.xtext.xbase.lib.LongExtensions.operato r_minus(long,byte) on instance: null
                    Gruß

                    Guido

                    Kommentar


                      #11
                      Aha. Hast Du denn mal den Datentyp angepasst, wie in meinem Posting #7 vorgeschlagen?

                      Kommentar


                        #12
                        Das habe ich tatsächlich nicht gemacht. Habs grade nachgeholt werde berichten.

                        Danke
                        Gruß

                        Guido

                        Kommentar


                          #13
                          Jetzt bekomme ich den Fehler


                          myItem wurde ausgeschaltet. Differenz 9614

                          2019-09-07 20:45:51.322 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Einschaltzeit bestimmen': Could not cast NULL to java.lang.Number; line 30, column 38, length 32

                          das bezieht sich auf die Zeile

                          Local_BH_Brenner.postUpdate((Local_BH_Brenner.stat e as Number) + nDiff/3600000)
                          Gruß

                          Guido

                          Kommentar


                            #14
                            Ich vermute, dein Item Local_BH_Brenner ist der Counter. Wenn der noch nie initialisiert wurde - das ist er auch nicht, wenn OH neu gestartet wurde, sofern du ihn nicht persisitierst -, hat der den "Wert" NULL.

                            Um den Wert erstmalig zu initialisieren, musst du eine Abfrage einbauen:
                            Code:
                            if (Local_BH_Brenner.state==NULL)
                                Local_BH_Brenner.postUpdate(nDiff/3600000)
                            else
                                Local_BH_Brenner.postUpdate((Local_BH_Brenner.state as Number) + nDiff/3600000)
                            oder, für Freunde des ternären Operators, wie ich es einer bin,
                            Code:
                            Local_BH_Brenner.postUpdate((if (Local_BH_Brenner.state==NULL) 0 else Local_BH_Brenner.state as Number) + nDiff/3600000)
                            openHAB 4.2

                            Kommentar


                              #15
                              Hallo und danke für den Hinweis,

                              die Abfrage
                              Code:
                               if (Local_BH_Brenner.state==NULL)
                              hatte ich eingebaut leider lief diese auf einen Fehler. Ich habe das jetzt geändert und zwar auf
                              Code:
                               if (Local_BH_Brenner.state inctanceof Number)
                              sonst wird erst erst initialisiert.

                              Gruß Guido
                              Zuletzt geändert von Höhlenbär; 08.09.2019, 20:19. Grund: Korrektur
                              Gruß

                              Guido

                              Kommentar

                              Lädt...
                              X