Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. [Gelöst] [Frage] setState schreibt "null" statt Wert?

    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

    [Gelöst] [Frage] setState schreibt "null" statt Wert?

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

      Hallo Skripter :ugeek:

      ich bin ein ganz Neuer :oops:

      Ich habe auch schon brav viewtopic.php?f=8&t=9236 abgearbeitet :!:

      Zu ioBroker kam ich durch den Wunsch für meine Heizung endlich mal eine vernünftige Visualisierung zu realisieren… Bisher hatte ich mit JavaScript überhaupt nichts zu tun, aber mit etwas Google und natürlich Dank der vielen Beiträge im Forum bin ich recht weit gekommen :shock: Jetzt scheitere ich aber an der bisher größten Hürde für mich: Es läuft nicht alles der Reihe nach sondern irgendwie gleichzeitig :lol:

      Trotzdem bin ich nach nicht mal einer Woche extrem begeistert von ioBroker. Vielen Dank all denen die dazu in vielen Stunden Entwicklungszeit beigetragen haben!

      Nun aber zum Problem bei dem ich jetzt nicht mehr weiterkomme:

      • Die Funktion fOzwSetVals bekommt die ID eines Datenpunkts übergeben.
      • Aus dieser wird der Wert und eine "ozwId" ermittelt.
      • Damit wird dann ein http request gebastelt.
      • Bei positiver Rückmeldung von der Heizung möchte ich den entsprechenden Datenpunkt auf ack=true setzen.
      • Meistens ist aber da der zugehörige Variablenwert schon weg, weil der Rest der Funktion schon durchgelaufen ist und damit die Variable nicht mehr da ist (?)
      • Ich brauche den Wert aber schon für den Request, muss ihn also vorher schon bestimmen.

      Wie löse ich das sauber?

      Funktion:

      let fOzwSetVals = function(statName) {
          log ("OzwSetVals called!");
      
          var ozwSetValue = getState(statName).val;
          var ozwId = getObject(statName).common.ozwId;
      
          require("request")
      
              (ozwUrl + '/api/menutree/write_datapoint.json?SessionId=' + sessionId + '&Id=' + ozwId + '&Type=Enumeration' + '&Value=' + ozwSetValue + '&EnumValue=' + ozwSetValue, function (error, response, results) {
                  if(error) {
                      log("OZW Wert schreiben fehlgeschlagen! (http request)");
                  }
                  else {
                      ozwObject = JSON.parse(results);
                      switch (ozwObject.Result.Success) {
                          case 'true':
                              log("OZW Wert erfolgreich geschrieben!","info");
                              setState(statName,ozwSetValue,true); //HIER ist unter Umständen ozwSetValue "nicht mehr da..."
                              break;
                          case 'false':
                              log("OZW Wert schreiben fehlgeschlagen! (OZW Rückmeldung)","warn");
                              log(JSON.stringify(results),"warn");
                              break;
                          default:
                              log("OZW Wert schreiben fehlgeschlagen, unbekannte OZW Rückmeldung!","warn");
                              log(JSON.stringify(results),"warn");
                      }
                  }
              });
      
          log("EndeGelände");
      };
      

      Log Ausgabe:

      Man sieht, dass nach der ersten Änderung "Ende Gelände" vor "Wert erfolgreich geschrieben" erreicht wird. Mein Versuch den Datenpunkt auf Ack=True zu setzen geht dann in die Hose, es wird auch der Wert auf "Null" gesetzt. Das führt dazu, dass die übergeordnete Funktion eine Änderung erkennt und die Funktion erneut aufruft… Käse 😢

      javascript.0	2018-10-10 23:27:26.191	warn	script.js.ozw.ozwtest2: "{\n \"Result\": {\n\t\t\"Success\": \"false\",\n\t\t\"Error\": {\n\t\t\t\"Txt\": \"value not valid\",\n\t\t\t\"Nr\": \"9\"\n\t\t}\n\t}\n} \n"
      javascript.0	2018-10-10 23:27:26.190	warn	script.js.ozw.ozwtest2: OZW Wert schreiben fehlgeschlagen! (OZW Rückmeldung)
      javascript.0	2018-10-10 23:27:25.919	info	script.js.ozw.ozwtest2: EndeGelände
      javascript.0	2018-10-10 23:27:25.919	info	script.js.ozw.ozwtest2: getObject(id=javascript.0.scriptEnabled.ozw.ozwtest2.OzwAutoSetVals.set_tww_mod, enumName=undefined) => {"_id":"javascript.0.scriptEnabled.ozw.ozwtest2.OzwAutoSetVals.set_tww_m
      javascript.0	2018-10-10 23:27:25.919	info	script.js.ozw.ozwtest2: getState(id=javascript.0.scriptEnabled.ozw.ozwtest2.OzwAutoSetVals.set_tww_mod, timerId=0) => {"val":null,"ack":true,"ts":1539206845909,"q":0,"from":"system.adapter.javascript.
      javascript.0	2018-10-10 23:27:25.919	info	script.js.ozw.ozwtest2: OzwSetVals called!
      javascript.0	2018-10-10 23:27:25.919	info	script.js.ozw.ozwtest2: OZW Session noch gültig
      javascript.0	2018-10-10 23:27:25.919	info	script.js.ozw.ozwtest2: ozwGetSession called
      javascript.0	2018-10-10 23:27:25.919	info	script.js.ozw.ozwtest2: Änderung!
      javascript.0	2018-10-10 23:27:25.919	info	script.js.ozw.ozwtest2: setForeignState(id=javascript.0.scriptEnabled.ozw.ozwtest2.OzwAutoSetVals.set_tww_mod, state={"val":null,"ack":true})
      javascript.0	2018-10-10 23:27:25.917	info	script.js.ozw.ozwtest2: OZW Wert erfolgreich geschrieben!
      javascript.0	2018-10-10 23:27:25.315	info	script.js.ozw.ozwtest2: EndeGelände
      javascript.0	2018-10-10 23:27:25.315	info	script.js.ozw.ozwtest2: getObject(id=javascript.0.scriptEnabled.ozw.ozwtest2.OzwAutoSetVals.set_tww_mod, enumName=undefined) => {"_id":"javascript.0.scriptEnabled.ozw.ozwtest2.OzwAutoSetVals.set_tww_m
      javascript.0	2018-10-10 23:27:25.315	info	script.js.ozw.ozwtest2: getState(id=javascript.0.scriptEnabled.ozw.ozwtest2.OzwAutoSetVals.set_tww_mod, timerId=0) => {"val":1,"ack":false,"ts":1539206844061,"q":0,"from":"system.adapter.admin.0","lc"
      javascript.0	2018-10-10 23:27:25.315	info	script.js.ozw.ozwtest2: OzwSetVals called!
      javascript.0	2018-10-10 23:27:25.312	info	script.js.ozw.ozwtest2: Session erfolgreich gestartet!
      javascript.0	2018-10-10 23:27:24.077	info	script.js.ozw.ozwtest2: OZW Session abgelaufen!
      javascript.0	2018-10-10 23:27:24.077	info	script.js.ozw.ozwtest2: ozwGetSession called
      javascript.0	2018-10-10 23:27:24.076	info	script.js.ozw.ozwtest2: Änderung!
      

      Danke schonmal vorab!

      Konrad

      Edit sagt, ich habe den Betreff angepasst

      1 Reply Last reply Reply Quote 0
      • blauholsten
        blauholsten Developer last edited by

        Hallo,

        zeig mal bitte den rest des Programms.

        Wann rufst du die Funktion:

        fOzwSetVals
        

        auf?

        Du solltest das erst tun, wenn die Callback Funktion des request aufgerufen wird.

        So in der Form…

        request('url', function(error, response, results){
                 //erst hier wieder fOzwSetVals aufrufen})
        
        1 Reply Last reply Reply Quote 0
        • K
          Konrad last edited by

          Zur gewünschten Funktion des ganzen Ablaufs:

          Wenn sich einer von mehreren Datenpunkten in einem Ordner ändert, dann:

          • soll geprüft werden ob es noch eine gültige SessionId für die Heizung gibt
          • falls nicht soll eine neue angefragt werden (bis hier fOzwGetSession)
          • dann soll der Wert des geänderten Datenpunkts an die Heizung geschickt werden (fOzwSetVals)
          • wenn das auch geklappt hat soll der Datenpunkt wieder auf ack=true gesetzt werden, und genau daran scheitert es

          fOzwGetSession ist eine eigene Funktion weil ich parallel dazu auch noch zyklisch Werte lesen möchte und dazu auch eine SessionId brauche.

          Ich habe auch noch etwas gespielt und den setState als callback einem vorhergehenden getState untergeordnet (siehe Kommentar im letzten Else Block).

          Es funktioniert wenn der Wert 0 ist, alles !=0 wird als "null" in den Datenpunkt geschrieben. Auch wenn ich im setState direkt einen Zahlenwert eintrage. :shock:

          Wird "null" geschrieben erkenne ich natürlich eine Änderung deswegen geht es von vorne los, das ist ja aber so gewünscht. Ich möchte ja nur ack=true setzen und nicht den Wert ändern.

          Hier das ganze Elend :oops: :

          const ozwUrl = "xyz";
          const username = "xyz";
          const password = "xyz";
          const maxOzwSessionAge = 600;
          
          var sessionId;
          var sessionStat;
          var sessionTimeStamp = 0;
          var resobj;
          var sessionAge;
          
          $('state[id=.OzwAutoSetVals.*]').on(function (statObj) {
          
              log("Änderung!");
              fOzwGetSession(fOzwSetVals,statObj.id);
          });
          
          let fOzwGetSession = function (callback, statName) {
              log("ozwGetSession called");
              sessionAge = (((new Date()).getTime())/1000)-sessionTimeStamp;
              if (sessionAge>maxOzwSessionAge) {
                  log("OZW Session abgelaufen!");
                  require("request")
                      (ozwUrl + '/api/auth/login.json?user=' + username + '&pwd=' + password, function (error, response, results) {
                          if(error) {
                              log("OZW Anmeldung fehlgeschlagen","Error");
                          }
                          else {
                              resobj = JSON.parse(results);
                              sessionId=resobj.SessionId;
                              sessionStat=resobj.Result.Success;
                              sessionTimeStamp=new Date().getTime()/1000;
                              if (sessionStat) {
                                  log("Session erfolgreich gestartet!");
                                  callback (statName);
                              }
                              else {
                                  log("OZW Anmeldung ungültig", "Error");
                              }
                          }
                      });
              }
              else {
                  log("OZW Session noch gültig");
                  callback (statName);
              }
          };
          
          let fOzwSetVals = function(statName) {
              log ("OzwSetVals called!");
          
              var ozwSetValue = getState(statName).val;
              var ozwId = getObject(statName).common.ozwId;
              var temp;
          
              require("request")
                  (ozwUrl + '/api/menutree/write_datapoint.json?SessionId=' + sessionId + '&Id=' + ozwId + '&Type=Enumeration' + '&Value=' + ozwSetValue + '&EnumValue=' + ozwSetValue, function (error, response, results) {
                      if(error) {
                          log("OZW Wert schreiben fehlgeschlagen! (http request)");
                      }
                      else {
                          //var statName;
                          ozwObject = JSON.parse(results);
                          switch (ozwObject.Result.Success) {
                              case 'true':
                                  log("OZW Wert erfolgreich geschrieben!","info");
                                  getState(statName, function (error, obj) {
                                      (statName,obj.val,true); //!!! das klappt nicht, es wird der Wert "Null" in den Datenpunkt geschrieben
                                  });
                                  break;
                              case 'false':
                                  log("OZW Wert schreiben fehlgeschlagen! (OZW Rückmeldung)","warn");
                                  log(JSON.stringify(results),"warn");
                                  break;
                              default:
                                  log("OZW Wert schreiben fehlgeschlagen, unbekannte OZW Rückmeldung!","warn");
                                  log(JSON.stringify(results),"warn");
                          }
                      }
                  });
              log("EndeGelände");
          };
          
          

          Danke!

          1 Reply Last reply Reply Quote 0
          • blauholsten
            blauholsten Developer last edited by

            Hi,

            Auf die schnelle…...

            Aus meiner Sicht ist das mit deiner Zeitabfrage viel zu umständlich und eigentlich nicht funktional.

            Erstelle dir eine Hilfsvariable z.b.

            let active = false;
            
            

            Wenn du dann deine Funktion aufrufst, fragst du vorher ab ob sie true ist, falls ja rufst du sie nicht auf.

            Die Hilfsvariable setzt du dann in der callback function des requests auf false, sowohl bei Error als auch bei result.

            Solltest du sehr viele Änderungen in den states haben, müsstest du eventuell mit einen Buffer arbeiten.

            Gesendet von meinem Handy

            1 Reply Last reply Reply Quote 0
            • K
              Konrad last edited by

              Mahlzeit,

              danke für den Hinweis!

              Die Zeitgeschichte habe ich gebaut da die SessionIds irgendwann ablaufen. Wann genau hab ich noch nicht herausgefunden, gibt dazu keine sinnvolle frei verfügbare Doku (Siemens).

              Ich verstehe aber immer noch nicht wie es dazu kommt, dass

              log("OZW Wert erfolgreich geschrieben!","info");

              getState(statName, function (error, obj) {

              log(obj.val);

              (statName,obj.val,true); //!!! das klappt nicht, es wird der Wert "Null" in den Datenpunkt geschrieben

              });

              den Datenpunkt "statName" mit "null" beschreibt wenn obj.val != 0 ist.

              In der vorhergehenden Logausgabe erscheint der korrekte Wert…

              javascript.0	2018-10-12 15:41:42.750	info	script.js.ozw.ozwtest2: setForeignState(id=javascript.0.scriptEnabled.ozw.ozwtest2.OzwAutoSetVals.set_tww_mod, state={"val":null,"ack":true})
              javascript.0	2018-10-12 15:41:42.745	info	script.js.ozw.ozwtest2: 1
              javascript.0	2018-10-12 15:41:42.719	info	script.js.ozw.ozwtest2: OZW Wert erfolgreich geschrieben!
              javascript.0	2018-10-12 15:41:41.955	info	script.js.ozw.ozwtest2: EndeGelände
              javascript.0	2018-10-12 15:41:41.955	info	script.js.ozw.ozwtest2: getObject(id=javascript.0.scriptEnabled.ozw.ozwtest2.OzwAutoSetVals.set_tww_mod, enumName=undefined) => {"_id":"javascript.0.scriptEnabled.ozw.ozwtest2.OzwAutoSetVals.set_tww_m
              javascript.0	2018-10-12 15:41:41.955	info	script.js.ozw.ozwtest2: getState(id=javascript.0.scriptEnabled.ozw.ozwtest2.OzwAutoSetVals.set_tww_mod, timerId=0) => {"val":1,"ack":false,"ts":1539351701726,"q":0,"from":"system.adapter.admin.0","lc"
              javascript.0	2018-10-12 15:41:41.955	info	script.js.ozw.ozwtest2: OzwSetVals called!
              javascript.0	2018-10-12 15:41:41.947	info	script.js.ozw.ozwtest2: Session erfolgreich gestartet!
              javascript.0	2018-10-12 15:41:41.753	info	script.js.ozw.ozwtest2: OZW Session abgelaufen!
              javascript.0	2018-10-12 15:41:41.751	info	script.js.ozw.ozwtest2: ozwGetSession called
              javascript.0	2018-10-12 15:41:41.746	info	script.js.ozw.ozwtest2: Änderung!
              
              1 Reply Last reply Reply Quote 0
              • K
                Konrad last edited by

                Tja… wen für den Datenpunkt

                max = null

                definiert ist macht setState das so - ganz still und heimlich :shock:

                Hat ein paar Stunden gedauert bis ich drauf gekommen bin :oops:

                1 Reply Last reply Reply Quote 0
                • blauholsten
                  blauholsten Developer last edited by

                  @Konrad:

                  Tja… wen für den Datenpunkt

                  max = null

                  definiert ist macht setState das so - ganz still und heimlich :shock:

                  Hat ein paar Stunden gedauert bis ich drauf gekommen bin :oops: `

                  Dann bitte als erledigt markieren….

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

                  Support us

                  ioBroker
                  Community Adapters
                  Donate

                  914
                  Online

                  31.7k
                  Users

                  79.9k
                  Topics

                  1.3m
                  Posts

                  2
                  7
                  889
                  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