Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. setState findet manuell erzeugtes Objekt nicht

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    setState findet manuell erzeugtes Objekt nicht

    This topic has been deleted. Only users with topic management privileges can see it.
    • S
      Shai0Hulud last edited by Shai0Hulud

      Mein Javascript für meinen NodeRed-Adapter konnte ich mangels eigener Skills mit ChatGPT vereinfachen und übersichtlicher gestalten.

      Nur bei meiner Funktion, die den täglichen Durchschnittsverbrauch seit bestimmten Tagen (01.01.23, 01.07.23 usw) anzeigen soll, gibt es einen mir unerklärlichen Fehler (bzw. Warnung, die aber dazu führt, dass diese Werte nicht aktualisiert werden), sondern noch die Werte beinhalten, die durch mein altes umständliches Script berechnet wurden.

      Am Anfang des Scripts wird z.B. folgende Variable definiert:

      var idSetConsPerDay230101 = '0_userdata.0.Zuhause.ConsPerDay230101';
      

      (Consumption per Day since 230101, also Verbrauch pro Tag seit 01.01.23)


      6aeac086-e902-4574-a9aa-88e61b79d468-image.png

      In der von ChatGPT vorgeschlagenen Funktion soll dann dieses Objekt mit dem Durchschnittsverbrauch seit dem 01.01.23 gefüttert werden, diese sieht so aus:

      function calculateAverageConsumption(startDateString, consTarget, idSetPrefix) {
          const startDate = new Date(startDateString);
          const year = startDate.getFullYear().toString().slice(-2); // Die letzten beiden Stellen des Jahres
          const month = ('0' + (startDate.getMonth() + 1)).slice(-2); // Monat mit führender Null, um zweistellig zu sein
          const day = ('0' + startDate.getDate()).slice(-2); // Tag mit führender Null, um zweistellig zu sein
      
          var fullID = `${idSetPrefix}${year}${month}${day}`;
          console.log(fullID); // Debugging fullID
      
          const currentDate = new Date().valueOf();
          const daysDifference = Math.round((currentDate - startDate.valueOf()) / (1000 * 60 * 60 * 24));
      
          const consumptionDifference = consTarget - getState(idGetStrombezug).val;
          const averageConsumption = (Math.round((consumptionDifference / daysDifference) * -1000) / 1000).toLocaleString('de-DE', { maximumFractionDigits: 3 });
          
          console.log(averageConsumption); // Debugging averageConsumption
      
          setState(fullID, `${averageConsumption.replace(".", ",")} kWh`, true);
      }
      

      Die Debugging-Zeile für die fullID gibt folgendes aus:

      info javascript.0 (1017) script.js.Zuhause.Solar.Node-Red-Dashboard_v2: idSetConsPerDay230101

      Die Debuging-Zeile für den errechneten Durchschnittsverbrauch (averageConsumption) folgendes:

      info javascript.0 (1017) script.js.Zuhause.Solar.Node-Red-Dashboard_v2: 8,014

      Aufgerufen wird die Funktion wie folgt:

              calculateAverageConsumption("2023/01/01", 6321.6, 'idSetConsPerDay');
      
      

      (6321.6 ist der Gesamtstromverbrauch meines Hauses vom 01.01.23)

      Sieht mMn erstmal korrekt aus!

      Trotzdem werden die Objekte im iobroker nicht aktualisiert. Das ist mir erst aufgefallen, nachdem ich sie manuell mit "0 kWh" überschrieben habe.

      **Das Log vom iobroker meckert folgendermaßen:

      warn State "idSetConsPerDay230101" not found**

      Dieser Zustand/Objekt existiert doch aber, was ist hier also das Problem?

      Danke!


      PS: Hier noch die Darstellung über NodeRed: 9c700ecf-9bf0-4fb0-9e0f-0b14019c58ac-image.png

      Codierknecht paul53 2 Replies Last reply Reply Quote 0
      • Codierknecht
        Codierknecht Developer Most Active @Shai0Hulud last edited by

        @shai0hulud sagte in setState findet manuell erzeugtes Objekt nicht:

        warn State "idSetConsPerDay230101" not found

        Ist das Leerzeichen da zufällig drin?

        S 1 Reply Last reply Reply Quote 0
        • S
          Shai0Hulud @Codierknecht last edited by

          @codierknecht

          Ich kann kein überflüssiges Leerzeichen entdecken.

          Codierknecht 1 Reply Last reply Reply Quote 0
          • Codierknecht
            Codierknecht Developer Most Active @Shai0Hulud last edited by

            @shai0hulud
            6e5d4e57-19c6-4a88-a733-3457016a6a90-grafik.png

            S 1 Reply Last reply Reply Quote 0
            • paul53
              paul53 @Shai0Hulud last edited by

              @shai0hulud sagte: warn State "idSetConsPerDay230101" not found

              Das ist eine ungültige ID. Es muss an idSetPrefix der String "0_userdata.0.Zuhause.ConsPerDay" übergeben werden.

              S 1 Reply Last reply Reply Quote 0
              • S
                Shai0Hulud @Codierknecht last edited by

                @codierknecht

                Da ist tatsächlich kein Leerzeichen. Ich hab die Zeile aus dem Log komplett kopiert und in Notepad++ eingefügt.

                Wenn ich meinen Text aus meinem Beitrag markiere, ist auch kein Leerzeichen erkennbar.

                1 Reply Last reply Reply Quote 0
                • S
                  Shai0Hulud @paul53 last edited by

                  @paul53 said in setState findet manuell erzeugtes Objekt nicht:

                  0_userdata.0.Zuhause.ConsPerDay

                  Danke! Das funktioniert tatsächlich. Verwirrt mich aber als JS-Noob etwas. Andere Werte übergebe ich doch auch mit z.B.

                  setState(idSetStromverbrauch, nStrBez, true) statt setState('0_userdata.0.Zuhause.StromverbrauchGZ', nStrBez, true)

                  Codierknecht paul53 2 Replies Last reply Reply Quote 0
                  • Codierknecht
                    Codierknecht Developer Most Active @Shai0Hulud last edited by

                    @shai0hulud
                    Die Frage ist: Mit welchem Wert für "idSetPrefix" wird die Funktion aufgerufen?

                    function calculateAverageConsumption(startDateString, consTarget, idSetPrefix)
                    
                    S 1 Reply Last reply Reply Quote 0
                    • paul53
                      paul53 @Shai0Hulud last edited by paul53

                      @shai0hulud sagte: Verwirrt mich aber als JS-Noob etwas.

                      Du hast uns den Aufruf der Funktion calculateAverageConsumption(startDateString, consTarget, idSetPrefix) nicht gezeigt. Man kann beim Aufruf auch eine Variable übergeben, die allerdings den richtigen String enthalten muss.

                      @shai0hulud sagte in setState findet manuell erzeugtes Objekt nicht:

                      mit ChatGPT

                      ist kein guter JS-Programmierer.

                      S 2 Replies Last reply Reply Quote 0
                      • S
                        Shai0Hulud @Codierknecht last edited by

                        @codierknecht

                        Bisher mit 'idSetConsPerDay'

                        nun mit '0_userdata.0.Zuhause.ConsPerDay'

                        Alle Warnungen weg, Werte im Dashboard werden wieder aktualisiert.

                        Codierknecht 1 Reply Last reply Reply Quote 0
                        • S
                          Shai0Hulud @paul53 last edited by

                          @paul53

                          Doch, ich hatte es erwähnt:

                          "Aufgerufen wiurd die Funktion wie folgt:

                                  calculateAverageConsumption("2023/01/01", 6321.6, 'idSetConsPerDay');
                          
                          

                          "

                          Nun nutze ich

                                  calculateAverageConsumption("2023/01/01", 6321.6, '0_userdata.0.Zuhause.ConsPerDay');
                          
                          
                          1 Reply Last reply Reply Quote 0
                          • Codierknecht
                            Codierknecht Developer Most Active @Shai0Hulud last edited by Codierknecht

                            @shai0hulud sagte in setState findet manuell erzeugtes Objekt nicht:

                            Bisher mit 'idSetConsPerDay'

                            In Hochkommata? Dann wird nur dieser String übergeben.
                            Du willst ja nicht den Namen dieser Variablen übergeben, sondern den Inhalt derselben.

                            Also so:

                                    calculateAverageConsumption("2023/01/01", 6321.6, idSetConsPerDay);
                            
                            S 1 Reply Last reply Reply Quote 0
                            • S
                              Shai0Hulud @paul53 last edited by

                              @paul53 said in setState findet manuell erzeugtes Objekt nicht:

                              @shai0hulud sagte in setState findet manuell erzeugtes Objekt nicht:

                              mit ChatGPT

                              ist kein guter JS-Programmierer.

                              Besser als ich 😏

                              1 Reply Last reply Reply Quote 0
                              • S
                                Shai0Hulud @Codierknecht last edited by

                                @codierknecht

                                idSetConsPerDay ist keine Variable, sondern nur das Prefix, welches über die Funktion mit dem jeweiligen Datum ergänzt wird und zur korrekten Variable zusammengebastelt wird, also z.B. idSetConsPerDay230101.

                                calculateAverageConsumption("2023/01/01", 6321.6, idSetConsPerDay);
                                

                                gibt direkt einen Fehler "Cannot find name". Kann er ja auch nicht finden.

                                Codierknecht 1 Reply Last reply Reply Quote 0
                                • Codierknecht
                                  Codierknecht Developer Most Active @Shai0Hulud last edited by Codierknecht

                                  @shai0hulud sagte in setState findet manuell erzeugtes Objekt nicht:

                                  idSetConsPerDay ist keine Variable

                                  Sehe ich in Deinem Eingangspost aber anders:

                                  var idSetConsPerDay230101 = '0_userdata.0.Zuhause.ConsPerDay230101'; 
                                  

                                  Natürlich ist das etwas anderes.
                                  Wobei da auch besser const stehen sollte.

                                  Wozu wird das zu Beginn mit "230101" definiert?
                                  Alles etwas schwierig ohne den Gesamtüberblick

                                  S 1 Reply Last reply Reply Quote 0
                                  • S
                                    Shai0Hulud @Codierknecht last edited by

                                    @codierknecht Sorry, nicht eindeutig genug ausgeführt. Der 01.01.23 war nur beispielhaft gezeigt, es gibt mehrere Daten, für die der tägliche Durchschnittsverbrauch angezeigt wird:

                                    bd215b55-2cad-4c37-be95-0352377630df-image.png

                                    Gesamtes Funktionsteil sieht so aus (wird alle 60minuten aktuialisiert):

                                    function calculateAverageConsumption(startDateString, consPast, idSetPrefix) {
                                        const startDate = new Date(startDateString);
                                        const year = startDate.getFullYear().toString().slice(-2); // Die letzten beiden Stellen des Jahres
                                        const month = ('0' + (startDate.getMonth() + 1)).slice(-2); // Monat mit führender Null, um zweistellig zu sein
                                        const day = ('0' + startDate.getDate()).slice(-2); // Tag mit führender Null, um zweistellig zu sein
                                    
                                        const fullID = `${idSetPrefix}${year}${month}${day}`;
                                    //    console.log(fullID); // Debugging-Anweisung hinzufügen
                                    
                                        const currentDate = new Date().valueOf();
                                        const daysDifference = Math.round((currentDate - startDate.valueOf()) / (1000 * 60 * 60 * 24));
                                    
                                        const consumptionDifference = getState(idGetStrombezug).val - consPast;
                                        const averageConsumption = (Math.round((consumptionDifference / daysDifference) * 1000) / 1000).toLocaleString('de-DE', { maximumFractionDigits: 3 });
                                    //    console.log(averageConsumption);
                                    
                                        setState(fullID, `${averageConsumption.replace(".", ",")} kWh`, true);
                                    }
                                    
                                        // Initialisierung der Variable, um mehrfache Aufrufe zu verhindern
                                        if (!NRDB.averageConsumptionCalculated) {
                                            calculateAverageConsumption("2023/01/01", 6321.6, '0_userdata.0.Zuhause.ConsPerDay');
                                            calculateAverageConsumption("2023/07/01", 8165.5, '0_userdata.0.Zuhause.ConsPerDay');
                                            calculateAverageConsumption("2023/09/01", 8340.0, '0_userdata.0.Zuhause.ConsPerDay');
                                            calculateAverageConsumption("2023/11/01", 8667.0, '0_userdata.0.Zuhause.ConsPerDay');
                                            calculateAverageConsumption("2024/01/01", 9220.3, '0_userdata.0.Zuhause.ConsPerDay');
                                            NRDB.averageConsumptionCalculated = true;
                                    
                                            // Setzen von NRDB.averageConsumptionCalculated auf false und Starten des Timers
                                            setTimeout(function () {
                                                NRDB.averageConsumptionCalculated = false;
                                            }, 60 * 60 * 1000); // 60 Minuten in Millisekunden
                                        }
                                    
                                    
                                    Codierknecht 1 Reply Last reply Reply Quote 0
                                    • Codierknecht
                                      Codierknecht Developer Most Active @Shai0Hulud last edited by

                                      @shai0hulud

                                      Ich habe noch immer nicht verstanden, warum Du das zu Beginn gleich für "230101" definierst.

                                      var idSetConsPerDay230101 = '0_userdata.0.Zuhause.ConsPerDay230101'; 
                                      

                                      Ich würde das (prinzipiell) in etwa so machen:

                                      var moment = require('moment');
                                      
                                      const statePrefix = '0_userdata.0.Zuhause.ConsPerDay'; 
                                      
                                      function calculateAverageConsumption(startDateString, consTarget, idSetPrefix) {
                                          let date = moment(startDateString).format('YYMMDD');
                                          const fullID = `${statePrefix}${date}`;
                                          ...
                                      }
                                      

                                      Eine stündliche Ausführung würde ich über einen Schedule lösen und nicht per Timeout.

                                      Dass Du den Code ab Zeile 20 eingerückt hast, ist der Lesbarkeit nicht wirklich zuträglich.
                                      Ich weiß: Klingt nach Erbesenzählerei, aber die Lesbarkeit ist das A und O für die spätere Wartung und Erweiterung von Code.

                                      S 1 Reply Last reply Reply Quote 1
                                      • S
                                        Shai0Hulud @Codierknecht last edited by

                                        @codierknecht Ich kann Dir das nicht erklären, warum ich da so in dieser Form zu Beginn definiere. JS-Noob und so. Ich habe mir das alles mit Google zusammengeschustert und war happy, dass der NodeRed-Adapter am Ende meine Werte so anzeigen konnte wie von mir gewünscht.

                                        ChatGPT kam erst am Ende ins Spiel, habe nur um Vereinfachung gebeten. Woraufhin das Script mit 170 Zeilen auf immerhin 130 Zeilen geschrumpft ist. Und bis auf diesen Teil mit den täglichen Durchschnittsverbrauchswerten ab bestimmten Tagen hat auch alles sofort funktioniert.

                                        Das Einrücken ist nicht bewusst passiert, ist glaube ich durch das Copy und Paste von ChatGPT gekommen.

                                        Danke für Deinen Vorschlag, das probier ich mal aus!

                                        VG!

                                        S 1 Reply Last reply Reply Quote 0
                                        • S
                                          Shai0Hulud @Shai0Hulud last edited by Shai0Hulud

                                          @shai0hulud

                                          Vorschlag funktioniert, konnte "idSetPrefix" aus der Funktion so natürlich entfernen, brauche jetzt nur noch 2 Optionen für die Funktion und hab mir von ChatGPT mit den Datumsformaten helfen lassen, da bei der restlichen Funktion ein anderes Datumsformat genutzt wurde und damit die Differenz in Tagen extrem groß wurde (knapp 20000 Tage statt nur 400 z.B.).

                                          Danke nochmal!

                                          Dass mit dem Schedule statt Timeout schaue ich mir auch noch an.

                                          1 Reply Last reply Reply Quote 0
                                          • First post
                                            Last post

                                          Support us

                                          ioBroker
                                          Community Adapters
                                          Donate

                                          975
                                          Online

                                          31.8k
                                          Users

                                          80.0k
                                          Topics

                                          1.3m
                                          Posts

                                          javascript
                                          3
                                          19
                                          479
                                          Loading More Posts
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          Community
                                          Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                                          The ioBroker Community 2014-2023
                                          logo