Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. scriptedEnabled - Problem bei Abfrage

    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

    scriptedEnabled - Problem bei Abfrage

    This topic has been deleted. Only users with topic management privileges can see it.
    • liv-in-sky
      liv-in-sky @AlCalzone last edited by

      @AlCalzone sagte in scriptedEnabled - Problem bei Abfrage:

      Würde ich in etwa so machen (besser lesbar und mischt nicht async/await mit .then()-Ketten):
      async function doStuff() { await sammleDaten(); await writeStuff(); // ^ Hier sollten vermutlich Daten zwischen den Methoden übergeben werden, // damit keine globalen Variablen missbraucht werden // const daten = await sammleDaten(); // await writeStuff(daten) const stringified = JSON.stringify(mxJson); await setStateAsync("javascript."+instance+".CheckScript.jsonSubScript", stringified); log(stringified); }

      funktioniert - und leuchtet sogar mir ein 🙂

      vielen dank für deine unterstützung

      jetzt kann ich mich wieder auf das eigentliche script konzentrieren - das herausfiltern der trigger

      1 Reply Last reply Reply Quote 1
      • liv-in-sky
        liv-in-sky @AlCalzone last edited by

        @AlCalzone

        es muss ich dich leider nochmal bemühen:

        ich wollt auch einen datenpunkt anlegen und/oder beschreiben am anfang - habe es tatsächlich geschafft, den adapter zum neustart zu bringen

        async function doStuff() {
            // if (await !existsStateAsync("javascript."+instance+".CheckScript.jsonSubScript")) {
            //     await createStateAsync("CheckScript.jsonSubScript", '[{"dp":"noch nicht da","enabled":"","script":""}]',
            //                     {type: 'string', name: 'jsonSubScript', role: 'value', read: true , write: true} );}
            await createStateAsync("CheckScript.jsonSubScript", '[{"dp":"noch nicht da","enabled":"","script":""}]',
                                  {type: 'string', name: 'jsonSubScript', role: 'value', read: true , write: true} );
            await setStateAsync("javascript."+instance+".CheckScript.jsonSubScript",'[{"dp":"noch nicht da","enabled":"","script":""}]')  //}      
        	await sammleDaten();
        	await writeStuff();
        	// ^ Hier sollten vermutlich Daten zwischen den Methoden übergeben werden,
        	// damit keine globalen Variablen missbraucht werden
        	// const daten = await sammleDaten();
        	// await writeStuff(daten)
            //await wait(5000);
        	const stringified = JSON.stringify(mxJson);
        	await setStateAsync("javascript."+instance+".CheckScript.jsonSubScript", stringified);
        	log(stringified);
        }
        
        doStuff()
        
        

        diese version läuft einmal und beim 2ten mal, wenn der dp existiert, crasht der adapter.
        die auskommentierte version war ein versuch vorher zu abzufragen - scheitert aber auch

        1 Reply Last reply Reply Quote 0
        • liv-in-sky
          liv-in-sky @AlCalzone last edited by

          @AlCalzone

          so wird wenigstens der error abgefangen - gibt es da eine andere lösung?

               try {
              await createStateAsync("CheckScript.jsonSubScript", '[{"dp":"noch nicht da","enabled":"","script":""}]',
                                    {type: 'string', name: 'jsonSubScript', role: 'value', read: true , write: true} );
               } catch (error) {
                  log(`Unexpected error - ${error}`, 'error');
              }
              await setStateAsync("javascript."+instance+".CheckScript.jsonSubScript",'[{"dp":"noch nicht da","enabled":"","script":""}]')  //}      
          	await sammleDaten();
          	await writeStuff();
          	// ^ Hier sollten vermutlich Daten zwischen den Methoden übergeben werden,
          	// damit keine globalen Variablen missbraucht werden
          	// const daten = await sammleDaten();
          	// await writeStuff(daten)
              //await wait(5000);
          	const stringified = JSON.stringify(mxJson);
          	await setStateAsync("javascript."+instance+".CheckScript.jsonSubScript", stringified);
          	log(stringified);
          }
          
          doStuff()
          
          
          AlCalzone 1 Reply Last reply Reply Quote 0
          • AlCalzone
            AlCalzone Developer @liv-in-sky last edited by

            @liv-in-sky Bin gerade am nachvollziehen. CreateState gibt etwas zurück, das als Fehler interpretiert wird, wenn der State existiert

            liv-in-sky 1 Reply Last reply Reply Quote 0
            • liv-in-sky
              liv-in-sky @AlCalzone last edited by

              @AlCalzone

              ich dachte, dass könnte wie bei createState funktionieren - da wird auch einfach drübergegangen, wenn er existiert

              AlCalzone 2 Replies Last reply Reply Quote 0
              • AlCalzone
                AlCalzone Developer @liv-in-sky last edited by AlCalzone

                @liv-in-sky Das Problem liegt daran, dass alle ...Async Methoden intern die nicht-Async-Varianten nutzen. Das erste Argument der Callbacks wird als Fehler interpretiert. Das stimmt auch meistens, aber createState gibt sowohl bei Fehlern als auch bei existierenden States hier einen String zurück:

                getState(..., (err) => {
                    // Bei existierendem State: err === id
                    // Bei Fehler: err === Fehlertext
                });
                

                Das entspricht aber nicht der Konvention, dass bei Callbacks der erste Parameter der Fehler ist.

                Dein Workaround war fast richtig - beachte die Klammern hinter ! im if:

                if (!(await existsStateAsync("javascript." + instance + ".CheckScript.jsonSubScript"))) {
                        await createStateAsync(
                            "CheckScript.jsonSubScript",
                            '[{"dp":"noch nicht da","enabled":"","script":""}]',
                            {
                                type: "string",
                                name: "jsonSubScript",
                                role: "value",
                                read: true,
                                write: true,
                            }
                        );
                    }
                
                paul53 liv-in-sky 2 Replies Last reply Reply Quote 0
                • paul53
                  paul53 @AlCalzone last edited by

                  @AlCalzone sagte:

                  if (!(await existsStateAsync("javascript." + instance + ".CheckScript.jsonSubScript"))) {

                  Sollte man es wirklich so machen, wenn ein synchrones existsState(id) existiert ?

                  AlCalzone 1 Reply Last reply Reply Quote 0
                  • AlCalzone
                    AlCalzone Developer @paul53 last edited by

                    @paul53 Du musst nicht, aber das asynchrone vermeidet Probleme mit dem Cache

                    paul53 1 Reply Last reply Reply Quote 0
                    • AlCalzone
                      AlCalzone Developer @liv-in-sky last edited by

                      @liv-in-sky BTW, der Fix wird vermutlich ebenfalls in 4.9.5 enthalten sein:
                      https://github.com/ioBroker/ioBroker.javascript/pull/692

                      AlCalzone created this issue in ioBroker/ioBroker.javascript

                      closed createState: pass ID as the result, not the error to the callback #692

                      1 Reply Last reply Reply Quote 0
                      • liv-in-sky
                        liv-in-sky @AlCalzone last edited by

                        @AlCalzone

                        das bedeutet, wenn ich in einem script selbst datenpunkte anlege, muss ich am besten immer so vorgehen und scripte gleich so wie dieses hier aufbauen -try u. catch habe ich mit deinem beispiel ersetztu und läuft

                        zusammengefaßt:
                        lauter async funktionenen , die anschliessend in einer async. hauptfunktion mit await aufgerufen werden und am ende wird die hauptfunktion aufgerufen

                        dann sollte man doch meist auf der sicheren seite sein

                        wenn ich eine api abrufe muss ich auch noch deinen tipp von oben berücksichtigen

                        function foobar() {
                          return new Promise(async (resolve) => {
                            await irgendwas;
                            irgendwasMitCallback(() => resolve());
                          });
                        });
                        
                        AlCalzone 1 Reply Last reply Reply Quote 0
                        • paul53
                          paul53 @AlCalzone last edited by paul53

                          @AlCalzone sagte:

                          das asynchrone vermeidet Probleme mit dem Cache

                          Da gebe ich Dir recht. Mit dem States-Puffer gab es schon manchmal Probleme.

                          EDIT: Allerdings greift auch die asynchrone Version auf den Puffer zu:

                                  existsState:    function (id, callback) {
                                      if (typeof callback === 'function') {
                                          adapter.getForeignObject(id, (err, obj) =>
                                              callback(err, obj && obj.type === 'state' && states.get(id) !== undefined));
                          
                          1 Reply Last reply Reply Quote 0
                          • AlCalzone
                            AlCalzone Developer @liv-in-sky last edited by

                            @liv-in-sky sagte in scriptedEnabled - Problem bei Abfrage:

                            lauter async funktionenen , die anschliessend in einer async. hauptfunktion mit await aufgerufen werden und am ende wird die hauptfunktion aufgerufen
                            dann sollte man doch meist auf der sicheren seite sein

                            In 4.9.x kannst du sogar die Haupt-Funktion weglassen. Top-Level-Await funktioniert da!

                            // nix
                            await irgendwas;
                            // auch nix
                            

                            wenn ich eine api abrufe muss ich auch noch deinen tipp von oben berücksichtigen

                            Dann aber bitte so:

                            function asyncAPI() {
                              return new Promise((resolve) => {
                                irgendwasMitCallback(() => resolve());
                              });
                            });
                            
                            1 Reply Last reply Reply Quote 1
                            • liv-in-sky
                              liv-in-sky last edited by liv-in-sky

                              nur nebenbei gefragt - ihr habt das problem nicht, dass die suche im scripte tab die browser zum crashen bringt ?

                              https://github.com/ioBroker/ioBroker.javascript/issues/666

                              ITCrowdIOB created this issue in ioBroker/ioBroker.javascript

                              closed Suchfunktion blockiert den Browser. #666

                              AlCalzone 1 Reply Last reply Reply Quote 0
                              • AlCalzone
                                AlCalzone Developer @liv-in-sky last edited by

                                @liv-in-sky Nö

                                liv-in-sky 2 Replies Last reply Reply Quote 0
                                • liv-in-sky
                                  liv-in-sky @AlCalzone last edited by

                                  @AlCalzone

                                  du glücklicher - ist extrem nervig

                                  und nochmals danke - war sehr lehrreich für mich

                                  1 Reply Last reply Reply Quote 0
                                  • liv-in-sky
                                    liv-in-sky @AlCalzone last edited by liv-in-sky

                                    @AlCalzone

                                    hi - ich schon wieder - brauche nochmal deinen sachverstand

                                    habe jetzt den fall mit den api abfragen - zwei hintereinander - zuerst radarstelle finden - dann adresse anzeigen - (später dazu: an handy senden)

                                    ist der code ok - außer die übergabe der werte an die nächste function

                                    werte kommen richtig raus !

                                    
                                    const  BASE_URL="https://cdn2.atudo.net/api/1.0/vl.php?type=0,1,2,3,4,5,6&box="
                                    const LATITUDE_START="48.312969"
                                    const LONGITUDE_START="11.701666"
                                    const LATITUDE_DEST="48.308288"
                                    const LONGITUDE_DEST="11.720184"
                                    const APIKEY_GEOCODING="4ddxxxxxxxx910f5a7b493d192e"
                                    var myLat="xx";
                                    var myLng="yy";
                                    var myRes="myRes";
                                    
                                    async function getContent(){
                                         return new Promise(async (resolve) => {
                                        var url = BASE_URL + LATITUDE_START + "," + LONGITUDE_START + "," + LATITUDE_DEST  + "," + LONGITUDE_DEST
                                        request(url, function(err, response, json) {
                                             log(json)
                                            var myjson = JSON.parse(json).pois;
                                         
                                            log(myjson[0].lat+myjson[0].lng)
                                            myLat=myjson[0].lat
                                            myLng=myjson[0].lng
                                            resolve()
                                        });
                                        });
                                    }
                                     
                                     
                                    async function getAddress(lat, long){
                                         return new Promise(async (resolve) => {
                                        var geoCodeUrl = 'https://api.opencagedata.com/geocode/v1/json' 
                                        geoCodeUrl = geoCodeUrl + '?' + 'key=' + APIKEY_GEOCODING + '&q=' + lat + ',' + long + '&pretty=1'
                                        log(geoCodeUrl)
                                         request(geoCodeUrl, function(err, response, json) {
                                        //log("d--------"+json)
                                          log  (JSON.parse(json).results[0].formatted);
                                          myRes=JSON.parse(json).results[0].formatted
                                          resolve()
                                        });
                                        });
                                    }  
                                    
                                    async function doStuff(){
                                    await getContent()
                                    //await getAddress("48.310381","11.706523")
                                    log(myLat)
                                    log(myLng)
                                    await getAddress(myLat,myLng)
                                    log(myRes)
                                    
                                    }
                                    

                                    Image 1.png

                                    AlCalzone 1 Reply Last reply Reply Quote 0
                                    • AlCalzone
                                      AlCalzone Developer @liv-in-sky last edited by AlCalzone

                                      @liv-in-sky Ein paar Dinge:

                                      1. Wenn du direkt in der Funktion kein await nutzt, brauchst du diese nicht als async definieren, betrifft getContent, getAddress und den Promise-Executor

                                      2. Die Art die Werte zu übergeben (mit externen Variablen) ist etwas komisch. Üblicherweise würde man das "Ergebnis" einer Funktion per return zurück geben (oder im Falle von Promises an resolve übergeben)

                                      3. Ich empfehle, komplett auf let (für veränderliche Variablen) und const (für Konstanten, bzw. nur 1x beschriebene Variablenstattvar` zu setzen. Diese sind jeweils nur im enthaltenen Block definiert was einige schwer zu findende Bugs vermeidet. --> https://hackernoon.com/js-var-let-or-const-67e51dbb716f

                                      4. Ist Geschmackssache, aber in JavaScript verwendet man eigentlich Semikolons am Ende der Zeile. Man kann sie in vielen Fällen weglassen, sollte dann aber sehr genau wissen, wo man sie doch braucht.

                                      5. würde ich dir axios statt request ans Herz legen. Das arbeitet von Haus aus schon mit Promises: https://github.com/axios/axios

                                      Habe dir die Vorschläge 1-3 mal hier umgesetzt:

                                      const BASE_URL = "https://cdn2.atudo.net/api/1.0/vl.php?type=0,1,2,3,4,5,6&box="
                                      const LATITUDE_START = "48.312969"
                                      const LONGITUDE_START = "11.701666"
                                      const LATITUDE_DEST = "48.308288"
                                      const LONGITUDE_DEST = "11.720184"
                                      const APIKEY_GEOCODING = "4ddxxxxxxxx910f5a7b493d192e"
                                      
                                      function getContent() {
                                          // kein async!
                                          return new Promise((resolve) => {
                                              // kein async!
                                              const url = BASE_URL + LATITUDE_START + "," + LONGITUDE_START + "," + LATITUDE_DEST + "," + LONGITUDE_DEST
                                              request(url, function (err, response, json) {
                                                  log(json)
                                                  const myjson = JSON.parse(json).pois;
                                      
                                                  log(myjson[0].lat + myjson[0].lng)
                                                  resolve({
                                                      // Rückgabe eines Objektes, muss wieder auseinander gepflückt werden
                                                      lat: myjson[0].lat,
                                                      lng: myjson[0].lng
                                                  });
                                              });
                                          });
                                      }
                                      
                                      
                                      function getAddress(lat, long) {
                                          // kein async!
                                          return new Promise((resolve) => {
                                              // kein async!
                                              let geoCodeUrl = 'https://api.opencagedata.com/geocode/v1/json'
                                              geoCodeUrl = geoCodeUrl + '?' + 'key=' + APIKEY_GEOCODING + '&q=' + lat + ',' + long + '&pretty=1'
                                              log(geoCodeUrl)
                                              request(geoCodeUrl, function (err, response, json) {
                                                  //log("d--------"+json)
                                                  log(JSON.parse(json).results[0].formatted);
                                                  const myRes = JSON.parse(json).results[0].formatted;
                                                  // Direkte Rückgabe des Wertes:
                                                  resolve(myRes)
                                              });
                                          });
                                      }
                                      
                                      async function doStuff() {
                                          // ^ hier brauchst du wirklich async, weil du im nächsten Befehl await nutzt!
                                          // Rückgabewert in lat und lng auseinander dividieren:
                                          const {lat, lng} = await getContent();
                                          //await getAddress("48.310381","11.706523")
                                          log(lat)
                                          log(lng)
                                          const myRes = await getAddress(lat, lng);
                                          log(myRes)
                                      }
                                      

                                      Weiterhin solltest du bei jedem Request prüfen, ob die Anfrage erfolgreich war (mit dem err-Parameter). Weil nur dann ist json auch definiert. Wenns mal nicht klappt, stürzt sonst dein Skript ab!

                                      liv-in-sky 1 Reply Last reply Reply Quote 1
                                      • liv-in-sky
                                        liv-in-sky @AlCalzone last edited by liv-in-sky

                                        @AlCalzone woow, puuh und tausend dank

                                        habe jetzt umgebaut - können auch mehrere blitzer zurückkommen!

                                        • axios muss ich näher ansehen - stand schon auf liste
                                        • strichpunkte - vergeß ich immer
                                        • wann merk ich mir das mit let eigentlich 😞
                                        • fehler sollten auch abgefangen werden
                                        
                                        const  BASE_URL="https://cdn2.atudo.net/api/1.0/vl.php?type=0,1,2,3,4,5,6&box="
                                        const LATITUDE_START="45.618674"//"48.605395"//"45.618674"//"48.618674"          "48.605395"//
                                        const LONGITUDE_START="11.813714"//"11.847123"//"11.813714"                      "11.847123"//
                                        const LATITUDE_DEST="48.607892"
                                        const LONGITUDE_DEST="11.840321"
                                        const APIKEY_GEOCODING="4ddxxxxxxxxxx0f5a7b493d192e"
                                        
                                        let myRes=[];
                                        
                                        function getContent() {
                                            // kein async!
                                            return new Promise((resolve) => {
                                                // kein async!
                                                const url = BASE_URL + LATITUDE_START + "," + LONGITUDE_START + "," + LATITUDE_DEST + "," + LONGITUDE_DEST
                                                request(url, function (err, response, json) { //log(json.length);log(err)
                                                                                                                                           //    let  myjson=Testing2
                                                                                                                                           //    log("get die Blitzer  "+myjson.pois[0].lat)
                                                
                                                              if(json.length>25 && err==null) {log("hat key")
                                                                                                                                           //  if(json.length>25 && err==null) {log("hat key") 
                                                                                                                                                       
                                                             const myjson = JSON.parse(json).pois;
                                                             let myBlitzRes=[];
                                                              for(let i=0;i<myjson.length;i++){
                                                                                                                                           //  for(let i=0;i<myjson.pois.length;i++){
                                                                  myBlitzRes.push({
                                                                                  lat: myjson[0].lat,
                                                                                  lng: myjson[0].lng
                                                                                                                                           //   lat: myjson.pois[0].lat,
                                                                                                                                           // lng: myjson.pois[0].lng
                                                    });
                                                    resolve(myBlitzRes)}
                                                } else{resolve(["empty"])}
                                                });
                                            });
                                        }
                                         
                                         
                                        function getAddress(lat, long) {
                                            // kein async!
                                            return new Promise((resolve) => {
                                                // kein async!
                                                let geoCodeUrl = 'https://api.opencagedata.com/geocode/v1/json'
                                                geoCodeUrl = geoCodeUrl + '?' + 'key=' + APIKEY_GEOCODING + '&q=' + lat + ',' + long + '&pretty=1'
                                              //  log(geoCodeUrl)
                                                request(geoCodeUrl, function (err, response, json) {
                                                  //  log(JSON.parse(json).results[0].formatted);
                                                  if (err==null){
                                                    const myRes = JSON.parse(json).results[0].formatted;
                                                    // Direkte Rückgabe des Wertes:
                                                    resolve(myRes)} else {resolve("keine Adress-Auflösung möglich")}
                                                });
                                            });
                                        }
                                        
                                        async function doStuff() {
                                            const myBlitzer = await getContent();
                                            log("meine blitzer  "+JSON.stringify(myBlitzer))
                                            //await getAddress("48.310381","11.706523")
                                            if(myBlitzer[0]!="empty") {
                                                  //   log(myBlitzer[0].lat);  log(myBlitzer[0].lng)
                                                      
                                                     for(let i=0;i<myBlitzer.length;i++){
                                                         await getAddress(myBlitzer[i].lat, myBlitzer[i].lng);
                                                         myRes.push(await getAddress(myBlitzer[i].lat, myBlitzer[i].lng))
                                                     } 
                                                     //log(myRes.toString())
                                                     log( myRes.toString())
                                        } else {log("KEINE BLITZER !!!!!")}
                                        } 
                                        
                                        doStuff();
                                        
                                        
                                        
                                        const Testing= {"pois":[{"id":"8073768268","lat":"47.854144","lat_s":"47.9","lng":"11.803649","lng_s":"11.8","street":"Miesbacher Stra\u00dfe","content":"6291143405","backend":"0-14134538","type":"1","vmax":"50","counter":"3","create_date":"2020-10-29 12:29:51","confirm_date":"2020-10-29 13:08:03","gps_status":"-","info":"{\"count_180d\":\"5\"}","polyline":""},{"id":"8073768176","lat":"50.863275","lat_s":"50.9","lng":"11.850087","lng_s":"11.9","street":"L107","content":"6291097692","backend":"0-14134432","type":"1","vmax":"70","counter":"2","create_date":"2020-10-29 12:08:50","confirm_date":"2020-10-29 13:22:08","gps_status":"-","info":"{\"count_180d\":\"0\"}","polyline":""},{"id":"8073768112","lat":"48.611621","lat_s":"48.6","lng":"11.824882","lng_s":"11.8","street":"St 2049","content":"6291067255","backend":"0-14134349","type":"1","vmax":"50","counter":"3","create_date":"2020-10-29 11:55:24","confirm_date":"2020-10-29 13:21:00","gps_status":"-","info":"{\"count_180d\":\"0\"}","polyline":""},{"id":"8073767869","lat":"47.946894","lat_s":"47.9","lng":"11.791351","lng_s":"11.8","street":"St 2078","content":"6290927668","backend":"0-14134006","type":"1","vmax":"50","counter":"3","create_date":"2020-10-29 10:54:12","confirm_date":"2020-10-29 13:26:21","gps_status":"-","info":"{\"count_180d\":\"0\"}","polyline":""}],"grid":[]}
                                        const Testing2= {"pois":[],"grid":[]}
                                        
                                        
                                        AlCalzone 1 Reply Last reply Reply Quote 0
                                        • AlCalzone
                                          AlCalzone Developer @liv-in-sky last edited by

                                          @liv-in-sky sagte in scriptedEnabled - Problem bei Abfrage:

                                          json.length>25 && err==null

                                          Wenn err nicht null ist, dann ist json nicht unbedingt definiert. Die Reihenfolge müsste anders herum sein.

                                          else {resolve("keine Adress-Auflösung möglich")}

                                          Das was du da vor hast (Fehler übergeben), geht besser mit reject. Prinzipiell:

                                          function doSomething() {
                                            return new Promise((resolve, reject) => {
                                              // ... irgendwas tun, bei Fehler:
                                              reject("Etwas ist schief gelaufen");
                                            });
                                          }
                                          
                                          async function stuff() {
                                            try {
                                              await doSomething();
                                            } catch (e) {
                                              // Hier landest du, wenn oben `reject` aufgerufen wird
                                            }
                                          }
                                          
                                          1 Reply Last reply Reply Quote 1
                                          • First post
                                            Last post

                                          Support us

                                          ioBroker
                                          Community Adapters
                                          Donate

                                          489
                                          Online

                                          31.8k
                                          Users

                                          80.0k
                                          Topics

                                          1.3m
                                          Posts

                                          javascript
                                          4
                                          51
                                          2444
                                          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