Ankündigung

Einklappen
Keine Ankündigung bisher.

Rule um Wert eines Items an ein anderes Item übergeben

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

    Rule um Wert eines Items an ein anderes Item übergeben

    Hallo,

    Ich möchte den Wert des Items "WEZ_Waermemenge_VerbrauchTag" an das Item ""WEZ_Waermemenge_VerbrauchVortag" übergeben.

    So funktioniert das leider nicht:
    Code:
    WEZ_Waermemenge_VerbrauchVortag = WEZ_Waermemenge_VerbrauchTag
    so erhalte ich den Fehler "The method postupdate(Number) is undefined for the type NumberItem"

    Code:
    WEZ_Waermemenge_VerbrauchVortag.postupdate(WEZ_Waermemenge_VerbrauchTag.state as Number)
    Das Item ist so definiert:

    Code:
    Number          WEZ_Waermemenge_VerbrauchVortag "Wärmemengenbedarf gestern [%d kWh]"                  (KG_Heizung)
    Wie kann ich den Wert dem anderen Item zuweisen?






    #2
    Fehler gefunden, es muss .postUpdate statt .postupdate lauten

    Kommentar


      #3
      das musst du über eine Rule machen.

      Die Rule könnte so aussehen:

      Code:
      rule "WEZ_Waermemenge_VerbrauchTag in WEZ_Waermemenge_VerbrauchVortag übergeben"
      when Item WEZ_Waermemenge_VerbrauchTag update
      then WEZ_Waermemenge_VerbrauchTag.postUpdate(WEZ_Waermemenge_VerbrauchVortag.state as DecimalType)
      end
      das macht, das bei jeder Änderung des Item WEZ_Waermemenge_VerbrauchTag, der dann gültige Wert in WEZ_Waermemenge_VerbrauchVortag geschrieben wird...

      Macht meiner Meinung aber wenig Sinn, was soll den dabei rauskommen? bzw. was ist die Intension?

      Kommentar


        #4
        Das mit der Rule war mir schon klar, ich möchte den letzten Wert von WEZ_Waermemenge_VerbrauchTag um 23:59 in WEZ_Waermemenge_VerbrauchVortag speichern.

        Mache das nun so:


        Code:
        rule "Waermemenge Bedarf Vortag"
        when
            Time cron "0 59 23 1/1 * ? *"       // Regel wir jeden Tag um 23:59 ausgeführt
        then
        WEZ_Waermemenge_VerbrauchVortag.postUpdate(WEZ_Waermemenge_VerbrauchTag.state as Number)
        
        end

        Kommentar


          #5
          ok, lass sich im ersten post noch nicht so wegen der Rule...
          am besten ist, wenn man die komplette Rule reinpackt, da es auch Fehler in der "when" Bedingung geben kann und dies der Grund sein kann...

          ich glaube auch dein Time cron könntest du nochmal checken, dass 1/1 sieht für mich komisch aus, habe aber geschaut, das gibt es
          da ja ein " * " für every Value steht, es könnte also der Cron

          Code:
          Time cron "0 59 23 * * ?"
          besser sein
          (so läuft es bei mir) aber wenn es openhab frisst, dann funktioniert dann lass es so

          Kommentar


            #6
            In
            Code:
            Time cron "0 59 23 1/1 * ? *"
            bedeutet der 4. Wert 1/1, dass bei Tag 1 begonnen wird und in 1er-Schritten hochgezählt wird.

            Da so jeder Tag getroffen wird, ist der Ausdruck also gleichwertig mit
            Code:
            Time cron "0 59 23 * * ? *"
            openHAB 4.2

            Kommentar


              #7
              Ich habe mir die cron hier erstellt: http://www.cronmaker.com/

              Ich hab jetzt noch ein anderes Problem mit einer ähnlichen Rule.
              Warum funktioniert hier die Zuweisung der Zahlen zum Item "HeizungStatus" nicht?

              Code:
              rule "Heizung Status"
              when
                  Item HeizungDP007 changed to 1 or
                  Item HeizungDP008 changed to 1 or
                  Item HeizungDP009 changed to 1 or
                  Item HeizungDP010 changed to 1 or
                  Item HeizungDP011 changed to 1
              then 
                  if (HeizungStatus == NULL)
                      HeizungStatus.postUpdate(0)
                  logInfo("heizung.rules", "Der Status hat sich geändert")
                  if(HeizungDP007 == 1)
                  {
                      HeizungStatus.postUpdate(11)
                      logInfo("status","Status: {}",HeizungStatus)
                  }
                  if(HeizungDP008 == 1)
                  {
                      HeizungStatus.postUpdate(12)
                      logInfo("status","Status: {}",HeizungStatus)
                  }
                  if(HeizungDP009 == 1)
                  {
                      HeizungStatus.postUpdate(13)
                      logInfo("status","Status: {}",HeizungStatus)
                  }
                  if(HeizungDP010 == 1)
                  {
                      HeizungStatus.postUpdate(14)
                      logInfo("status","Status: {}",HeizungStatus)
                  }
                  if(HeizungDP011 == 1)
                  {
                      HeizungStatus.postUpdate(15)
                      logInfo("status","Status: {}",HeizungStatus)
                  }
              end
              Item:

              Code:
              Number          HeizungStatus       "Heizung Status [MAP(heizung.map):%s]"

              Kommentar


                #8
                Du möchtest den Status der Items betrachten, nicht das Item selbst. Entsprechend musst Du im Vergleich if(HeizungStatus.state == NULL) schreiben (für jedes Item...)

                Das logInfo() ist so auch nicht korrekt. Du möchtest ja wiederum den Status ausgeben, nicht das Item.
                Ist immer exakt eines der Items 1 und alle anderen nicht? Ansonsten wird die Rule mit hoher Wahrscheinlichkeit nicht wie gewünscht funktionieren.
                Vermutlich könnte Deine Rule wesentlich einfacher funktionieren, allerdings fehlen dazu Hintergrundinformationen.

                Kommentar


                  #9
                  Werde ich morgen mal probieren.

                  Zitat von udo1toni Beitrag anzeigen
                  Ist immer exakt eines der Items 1 und alle anderen nicht? Ansonsten wird die Rule mit hoher Wahrscheinlichkeit nicht wie gewünscht funktionieren.
                  Vermutlich könnte Deine Rule wesentlich einfacher funktionieren, allerdings fehlen dazu Hintergrundinformationen.
                  Ja, ich kann an der Heizung folgendes einstellen: Standby, Woche 1, Woche 2, Konstant, Sparbetrieb. Daher kann immer nur eins von denen aktiv sein. Welches aktiv ist bekomme ich über die Items HeizunDP007 - HeizungDP011 gemeldet.
                  In meiner Übersicht möchte ich aber nur ein Item haben und nicht fünf.


                  Kommentar


                    #10
                    dann mach es lieber so:

                    Items:
                    Code:
                    Group HeizungBetrieb
                    Number HeizungDP007_11 (HeizungBetrieb)
                    Number HeizungDP008_12 (HeizungBetrieb)
                    Number HeizungDP009_13 (HeizungBetrieb)
                    Number HeizungDP010_14 (HeizungBetrieb)
                    Number HeizungDP011_15 (HeizungBetrieb)
                    Durch die Benennung der Items wird die nachfolgende Regel sehr elegant
                    Code:
                    rule "Heizung Status"
                    when
                        Member of HeizungBetrieb changed to 1
                    then
                        val nBaNew = Integer::parseInt(triggeringItem.name.split("_").get(1))
                        val nBaOld = if(HeizungStatus.state instanceof Number) (HeizungStatus.state as Number).intValue else 0
                        if(nBaNew != nBaOld) {
                            HeizungStatus.postUpdate(nBaNew)
                            logInfo("heizung", "Der Status wurde von {} nach {} geändert.",nBaOld,nBaNew)
                        }
                    end
                    In der ersten Zeile wird nBaNew aus dem Namen des Items abgeleitet, welches die Rule getriggert hat (also seinen Zustand gewechselt hat). Dabei wird der Name am Zeichen _ getrennt und der 2. Teil in ein Integer gewandelt.

                    In der 2. Zeile wird der alte Wert ermittelt. Falls das Item eine gültige Zahl zurück liefert (instanceof Number) wird dieser Wert verwendet, ansonsten wird 0 angenommen.
                    Falls die beiden Werte voneinander abweichen (nBaNew != nBaOld, != bedeutet nicht gleich, == bedeutet gleich) wird der neue Wert ins Item geschrieben und eine Zeile geloggt.
                    Man könnte auch mit dem Zahlenwert 007 bis 011 arbeiten, z.B. könte man auch ein split("P").get(1) verwenden und damit den String am P auseinander reißen. Dann müsste man halt noch vier addieren, um auf den korrekten Wert zu kommen.
                    Die umgekehrte Richtung kann man ähnlich elegant erledigen, falls zum Umschalten der Betriebsart auch unterschiedliche Items verwendet werden müssen.
                    Zuletzt geändert von udo1toni; 10.06.2020, 15:20.

                    Kommentar


                      #11
                      Zitat von udo1toni Beitrag anzeigen
                      dann mach es lieber so:
                      Danke!

                      Zitat von udo1toni Beitrag anzeigen
                      Die umgekehrte Richtung kann man ähnlich elegant erledigen, falls zum Umschalten der Betriebsart auch unterschiedliche Items verwendet werden müssen.
                      Genau so ist es, zum umschalten ist es auch wieder so dass es 5 Items gibt.

                      Kommentar


                        #12
                        Der Trick funktioniert anderssrum genauso:
                        Code:
                        rule "Heizung steuern"
                        when
                            Item HeizungStatus received command // wird nicht getriggert wenn sich der Status ändert (postUpdate)
                        then
                            if(!(receivedCommand instanceof Number)) { // empfangenes Kommando nicht vom Typ Number
                                logWarn("heat","Heizung steuern: Befehl nicht unterstützt: {}",receivedCommand)
                                return;
                            }
                            val nRc = (receivedCommand as Number).intValue
                            if(nRc > 15 || nRc < 11) { // empfangenes Kommando vom Typ Number, aber zu groß oder zu klein
                                logWarn("heat","Heizung steuern: Befehl nicht unterstützt: {}",receivedCommand)
                                return;
                            }
                            gHeizung.members.filter[i|Integer::parseInt(i.name.split("_").get(1)) == nRc].head.sendCommand(1)
                        end
                        In der Gruppe gHeizung wären dann alle Steueritems, die dann jeweils eine 1 als Befehl empfangen.

                        Und ja, es reicht das eine Item für Status und Befehl. Wenn Du ein Selection Widget verwendest, kannst Du einfach aus der Liste auswählen, alternativ kannst Du ein Switch Widget verwenden, dann gibt es für jeden Modus eine Schaltfläche. Fünf Tasten könnten mit kurzer Beschriftung noch gerade so in eine Zeile passen.

                        Der erste Teil der Rule filtert alle ungültigen Befehle aus (nur für den Fall...)
                        Die eigentliche Arbeit passiert komplett in der letzten Zeile:
                        gHeizung.members.filter[] -> filtere die Liste der Member der Gruppe gHeizung
                        i| -> die Variable, die für jedes einzelne Item der Liste steht
                        i.name.split("_").get(1) -> hole aus dem Namen den Teil nach dem 1. Unterstrich (Name analog zu den Status-Items)
                        Integer:: parseInt() -> (ohne das Leerzeichen, hier nur wegen automatischer Ersetzung) übersetze den String als Integer

                        Das Ergebnis des Filters ist eine Liste (mit einem Item, aber eine Liste). Entsprechend wählt .head das erste Item aus und .sendCommand() sendet den Befehl.
                        Zuletzt geändert von udo1toni; 11.06.2020, 19:31. Grund: Rule korrigiert

                        Kommentar


                          #13
                          Zitat von udo1toni Beitrag anzeigen
                          Der Trick funktioniert anderssrum genauso:
                          Code:
                          rule "Heizung steuern"
                          when
                          HeizungStatus received command // wird nicht getriggert wenn sich der Status ändert (postUpdate)
                          then
                          if(!(receivedCommand instanceof Number)) { // empfangenes Kommando nicht vom Typ Number
                          logWarn("heat","Heizung steuern: Befehl nicht unterstützt: {}",receivedCommand)
                          return;
                          }
                          val nRc = (receivedCommand as Number).intValue
                          if(nRc > 15 || nRc < 11) { // empfangenes Kommando vom Typ Number, aber zu groß oder zu klein
                          logWarn("heat","Heizung steuern: Befehl nicht unterstützt: {}",receivedCommand)
                          return;
                          }
                          gHeizung.members.filter[i|Integer::parseInt(i.name.split("_").get(1)) == nRc].head.sendCommand(1)
                          end
                          Hier erhalte ich in VSC für "HeizungStatus" die Meldung "no viable alternative at input 'HeizungStatus'".
                          Das "receivedCommand" ist eine Variable die ich noch definieren muss? -> "var receivedCommand = 0"?
                          Denn dort erhalte ich die Meldung "The method or field receivedCommand is undefined".

                          Zitat von udo1toni Beitrag anzeigen
                          Und ja, es reicht das eine Item für Status und Befehl.
                          Meinst Du hier das Item "HeizungStatus"?

                          Kommentar


                            #14
                            Die Variable receivedCommand ist eine implizite Variable, die Du nicht definieren darfst, sie steht in einer Rule, die auf received command triggert, automatisch zur Verfügung.

                            Es fehlt natürlich wieder mal das Schlüsselwort Item passiert mir gerne... Die Zeile muss also
                            Code:
                                Item HeizungStatus received command
                            heißen.

                            Kommentar


                              #15
                              Der Fehler ist nun weg. Danke.
                              Jetzt hab ich hier aber noch ein anderes Problem, meine GA sind vom Datentyp "1.007 Schritt".
                              Da funktioniert das mit der 0/1 nicht. Wie muss ich hier das ganze dann senden?


                              Kommentar

                              Lädt...
                              X