Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. async / await -> Muster Anleitung gesucht

    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

    async / await -> Muster Anleitung gesucht

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

      @bahnuhr vielleicht könntest du mal die einzelnen funktionen hier zeigen oder dein existierendes script posten. dann wäre es einfacher, ein muster zu erstellen. so könnte man dann jeden deiner punkte als funktion darstellen und das ganze schrittweise aufbauen - nicht jeder hat ein yamaha system und weiß, wie das zu steuern ist

      bahnuhr 1 Reply Last reply Reply Quote 0
      • Asgothian
        Asgothian Developer @bahnuhr last edited by

        @bahnuhr

        Das Await wartet nicht bis etwas fertig ist, sondern bis eine Funktion vollständig durchgelaufen ist. Was du also brauchst sind Funktionen die erst zurück kommen bis die dazu gehörige Funktion erledigt ist. Dieses ist die Schlüsselaufgabe, die mit async/await erst einmal nichts zu tun hat. Insbesondere das mp3 erstellen und kopieren muss entsprechend abgedeckt sein.

        Diese solltest du als async definieren, dann kannst du diese mit await aufrufen.

        A.

        bahnuhr 1 Reply Last reply Reply Quote 0
        • arteck
          arteck Developer Most Active @Hendrick last edited by arteck

          @hendrick nicht ganz

          // funktion aufrufen
          await test();   //  warte bis die ganze funktion fertig ist
          
          
          
          
          
          async function test() {
              try {
                  await setStateAsync('PFAD ZUM DATENPUNKT', {val:true, ack:false});   // warte bis setStateAsync meldet ist durch
                  await setStateAsync('PFAD ZUM DATENPUNKT', {val:true, ack:false});    // warte bis setStateAsync meldet ist durch
                  let res =  await setStateAsync('PFAD ZUM DATENPUNKT', {val:true, ack:false});    // warte bis setStateAsync meldet ist durch und gibt das ergebnis in die res variable
          
              } catch (error) {
                  return;
              }
          }
          

          man kann es noch mehr aufbohren und einen return wert ausgeben... und und und

          liv-in-sky 1 Reply Last reply Reply Quote 1
          • bahnuhr
            bahnuhr Forum Testing Most Active @liv-in-sky last edited by bahnuhr

            @liv-in-sky sagte in async / await -> Muster Anleitung gesucht:

            existierendes script posten

            Na klar kann ich dies machen; ist aber sehr komplex und auf mich abgestimmt.

            
            // Yamaha; Text ansagen auf Lautsprecher
            //
            // Folgender Ablauf:
            // - prüfen ob Gerät im Wlan ist (mittels ping) -> ping ist vorher einzurichten
            // - prüfen ob Gerät aus ist; wenn aus dann einschalten
            // - prüfen ob Input "Server"; wenn nein dann Umschalten auf Input "Server"
            // - Verzeichnis (wo der Lautsprecher die Dateien findet) einstellen
            // - Dateien abspielen
            //
            // Habe folgendes globales Script eingefügt:
            //    function Yamaha (IP, x, sound) {
            //       setState('javascript.0.Geräte.Yamaha.Lautsprecher_IP', IP);    // einstellen welcher Lautsprecher wiedergeben soll
            //       setState('sayit.2.tts.text', x);                               // mp3 wird erzeugt
            //       setState('javascript.0.Geräte.Yamaha.Ansage', true);           // abspielen der mp3 Datei auf dem Lautsprecher
            //       switch (sound) {
            //          case 1:     setState('javascript.0.Geräte.Yamaha.Sound', "intercom.mp3");           break;
            //          case 2:     setState('javascript.0.Geräte.Yamaha.Sound', "tos-computer-03.mp3");    break;
            //          case 3:     setState('javascript.0.Geräte.Yamaha.Sound', "tng_red_alert2.mp3");     break;
            //          default:    setState('javascript.0.Geräte.Yamaha.Sound', "intercom.mp3");           break;
            //        }
            //    }
            //
            // Aufruf erfolgt mit
            //  Yamaha ('192.168.243.201', 'Test Test', Sound-Nr.);   
            //
            //  01.2019 bahnuhr
            //
            
            
            // Variablen definieren
               var logging = true,    yamaha_IP = "",     yamaha = "";
               var OrdnerVerz = "1_Sound";         // In diesem Ordner liegen die Dateien, Verzeichnis auf c:\iobroker ; dieses Verz. wird gestreamt mit wmp
               var Ansage_Lautstaerke = 40;        // Lautstärke für das Abspielen der Dateien
               var MC_ID = "",     stand_alt_Power = "",   stand_alt_Lautstaerke = 0,      stand_alt_Input = "";
               var request = require('request'),   fs = require('fs');
            
            
            // wenn ...Ansage auf true dann mp3 kopieren und Text ansagen
               on({id: "javascript.0.Geräte.Yamaha.Ansage", change: "any", val: true}, function() {  
                   setStateDelayed('javascript.0.Geräte.Yamaha.Ansage', false, 10000);
                   yamaha_IP = getState('javascript.0.Geräte.Yamaha.Lautsprecher_IP').val;
                   yamaha = "http://" + yamaha_IP + "/YamahaExtendedControl/v1/";
                   switch (yamaha_IP) {
                       case '192.168.243.200':     MC_ID = "RX-V685_0DA87303";     Ansage_Lautstaerke = 91;    if (logging) log('MC_ID und Lautstärke - Receiver');        break;      // Wohnzimmer
                       case '192.168.243.201':     MC_ID = "WX-021_0DA87510";      Ansage_Lautstaerke = 40;    if (logging) log('MC_ID und Lautstärke - Schlafzimmer');    break;      // Schlafzimmer
                       case '192.168.243.202':     MC_ID = "WX-010_04955483";      Ansage_Lautstaerke = 40;    if (logging) log('MC_ID und Lautstärke - Philipp');          break;     // Philipp
                       case '192.168.243.203':     MC_ID = "WX-010_03B558C3";      Ansage_Lautstaerke = 30;    if (logging) log('MC_ID und Lautstärke - Büro');            break;      // Büro
                       case '192.168.243.204':     MC_ID = "WX-010_0DA87930";      Ansage_Lautstaerke = 30;    if (logging) log('MC_ID und Lautstärke - Bad-EG');            break;    // Bad EG
                       case '192.168.243.205':     MC_ID = "WX-010_01234150";      Ansage_Lautstaerke = 30;    if (logging) log('MC_ID und Lautstärke - Küche');            break;     // Küche
                       case '192.168.243.206':     MC_ID = "WX-010_0BA15680";      Ansage_Lautstaerke = 30;    if (logging) log('MC_ID und Lautstärke - Fitnessraum');     break;      // Fitnessraum
                       case '192.168.243.207':     MC_ID = "WX-030_0ABC8899";      Ansage_Lautstaerke = 30;    if (logging) log('MC_ID und Lautstärke - Hobbyraum');       break;      // Hobbyraum
                       case '192.168.243.208':     MC_ID = "WX-010_01A33445";      Ansage_Lautstaerke = 30;    if (logging) log('MC_ID und Lautstärke - Gäste-WC');           break;      // Gäste-WC
                       case '192.168.243.209':     MC_ID = "WX-010_0CDAB879";      Ansage_Lautstaerke = 30;    if (logging) log('MC_ID und Lautstärke - Sauna');           break;      // Sauna
                       case '192.168.243.210':     MC_ID = "WX-030_0ABX1237";      Ansage_Lautstaerke = 30;    if (logging) log('MC_ID und Lautstärke - Test2');           break;      // Test2
                   }
                   Beginn();
               });
            
            
            // Beginn
               function Beginn() {
                   // Ist der Lautsprecher im Netz erreichbar
                       x = yamaha_IP.replace('.', '_');    x = x.replace('.', '_');    x = x.replace('.', '_'); 
                       if (logging) log('Beginn: x = ' + x);
                       if (getState('ping.0.' + PC_Name() + '.' + x).val) {
                           // Ist power an ?
                               if (getState('musiccast.0.' + MC_ID + '.main.power').val == false) {
                                   stand_alt_Power = "aus";
                                   if (logging) log('Beginn: stand_alt_Power = ' + stand_alt_Power);
                                   power();                        // Power einschalten
                               } else {
                                   stand_alt_Power = "an";
                                   if (logging) log('Beginn: stand_alt_Power = ' + stand_alt_Power);
                               }
                           // Dateien kopieren ; Input und Lautstärke setzen ; Verzeichnis einstellen
                               setTimeout(function() {     input_lautstaerke();    }, 2000);       // Input und Lautstärke setzen
                               setTimeout(function() {     Dateien();              }, 3000);       // Dateien kopieren
                               setTimeout(function() {     pruef_Verzeichnis(0);   }, 7000);       // Verzeichnis einstellen
                       }
               }
            
            // power on 
               function power() {
                   request(yamaha + 'main/setPower?power=on', function (error, response, body) {
                       if (!error && response.statusCode == 200) { if (logging) log('power: ' + yamaha_IP + '; Power eingeschaltet');  } else {    log("power: Error: MusicCast = " + error);  }
                   });
               }
            
            // Dateien kopieren
               function Dateien() {
                   setTimeout(function() {
                       Datei_kopieren("/opt/iobroker/iobroker-data/files/vis.0/mp3/" + getState('javascript.0.Geräte.Yamaha.Sound').val,"/mnt/1_Sound.mp3");
                   }, 1000);
                   setTimeout(function(){ request('http://192.168.243.12:8082/state/sayit.2.tts.mp3', {encoding:'binary'}, function(error, response, body) {
                       fs.writeFile("/mnt/2_sayit.mp3", body, 'binary', function (err) { if(err) log('Fehler!'); }); });
                   }, 2000);
                   if (logging) log('Dateien kopiert.');
               }
            
            // Input_Lautstärke setzen
               function input_lautstaerke() {
                   stand_alt_Input = getState('musiccast.0.' + MC_ID + '.main.input').val;
                   if (logging) log('Input_Lautstärke setzen: stand_alt_Input = ' + stand_alt_Input);
                   // prüfen input
                       if (stand_alt_Input != "server") setState('musiccast.0.' + MC_ID + '.main.input', 'server');
                   // Lautstärke
                       stand_alt_Lautstaerke = getState('musiccast.0.' + MC_ID + '.main.volume').val;
                       if (logging) log('Input_Lautstärke setzen: stand_alt_Lautstaerke = ' + stand_alt_Lautstaerke);
                       setState('musiccast.0.' + MC_ID + '.main.volume', Ansage_Lautstaerke);
                       if (logging) log('Input_Lautstärke setzen: Lautstärke gesetzt auf = ' + Ansage_Lautstaerke);
               }
            
            // Verzeichnis prüfen
               function pruef_Verzeichnis(index) {
                   request(yamaha + 'netusb/getListInfo?input=server&index=' + index + '"&size=8&lang=de', function (error, response, body) {
                       if (!error && response.statusCode == 200) {
                           if (logging) log('Verzeichnis prüfen: json = ' + body);
                           var obj = JSON.parse(body);
                           var Verz = JSON.parse(JSON.stringify(obj.list_info, ['text']));
                           if (logging) log('Verzeichnis prüfen: aktueller Ordner = ' + obj.menu_name);
                           if (obj.menu_name == "SERVER"|| obj.menu_name == "Universal Media Server" || obj.menu_name == OrdnerVerz ) {
                               if (obj.menu_name == "SERVER") { var Nr = -1;       // menu_name ist Server - wechseln zu "Universal Media Server
                                   for(var i in Verz){ vtext = JSON.stringify(Verz[i]); vtext = vtext.replace('{"text":"', ''); vtext = vtext.replace('"}', ''); if (vtext == "Universal Media Server") Nr = i; log ("Nr.= " + i + ", " + vtext); }
                                   if (Nr >= 0) { if (logging) log('Verzeichnis: "Universal Media Server" vorhanden, Nr. '+ Nr + ' wird gesetzt !'); setzen_Verzeichnis(Nr); } else { if (logging) log('Verzeichnis: "Universal Media Server" ist nicht vorhanden !'); }
                               }
                               if (obj.menu_name == "Universal Media Server") { var Nr = -1;       // menu_name ist Universal Media Server - wechseln zu "1_Sound
                                   for(var i in Verz){ vtext = JSON.stringify(Verz[i]); vtext = vtext.replace('{"text":"', ''); vtext = vtext.replace('"}', ''); if (vtext == OrdnerVerz) Nr = i; log ("Nr.= " + i + ", " + vtext); }
                                   if (Nr >= 0) { if (logging) log('Verzeichnis: "' + OrdnerVerz + '" vorhanden, Nr. '+ Nr + ' wird gesetzt !'); setzen_Verzeichnis(Nr); } else { if (logging) log('Verzeichnis: "' + OrdnerVerz + '" ist nicht vorhanden !'); }
                               }
                               if (obj.menu_name == OrdnerVerz) play_Datei(); 
                           } else {
                               if (logging) log('-Abbruch- Verzeichnis "Server, UMS oder ' + OrdnerVerz + '" ist nicht vorhanden !');
                           }
                       } else {
                           log("Error: MusicCast - Prüf Verzeichnis = " + error);
                       }
                   });
               }
            
            // Verzeichnis setzen
               function setzen_Verzeichnis(index) {
                   request(yamaha + 'netusb/setListControl?list_id=main&type=select&index=' + index, function (error, response, body) {
                       if (!error && response.statusCode == 200) {
                           if (logging) log('Verzeichnis setzen: erfolgreich gesetzt !');
                           if (logging) log('Verzeichnis setzen: json = ' + body);
                           obj = JSON.parse(body);
                           if (obj.response_code == "0") {
                               if (logging) log('Verzeichnis setzen: erfolgreich gesetzt !');
                               pruef_Verzeichnis(0);
                           } else {
                               log("Error: Verzeichnis konnte nicht gesetzt werden !");
                           }
                       } else {
                           log("Error: MusicCast - setzen Verzeichnis = " + error);
                       }
                       });
               }
            
            // Datei abspielen
               function play_Datei() {
                   request(yamaha + 'netusb/setListControl?list_id=main&type=play&index=0', function (error, response, body) {
                       if (!error && response.statusCode == 200) {
                           log ("MusicCast - Datei wird abgespielt !");
                           Stand_alt_herstellen();
                           setTimeout(function() { Dateien_loeschen(); },15000);
                       } else {
                           log("Error: MusicCast - play Datei = " + error);
                       }
                       });
               }
            
            // Dateien wieder löschen
               function Dateien_loeschen() {
                   if (fs.existsSync('/mnt/1_sound.mp3')) {                                // Datei ist vorhanden
                       Datei_loeschen('/mnt/1_sound.mp3');
                   } else {                                                                                                    // Datei ist nicht vorhanden
                       if (logging) log ("Datei: -mnt/1_sound.mp3- wurde nicht gelöscht");
                   }    
                   if (fs.existsSync('/mnt/2_sayit.mp3')) {                                // Datei ist vorhanden
                       Datei_loeschen('/mnt/2_sayit.mp3');
                   } else {                                                                                                    // Datei ist nicht vorhanden
                       if (logging) log ("Datei: -mnt/2_sayit.mp3- wurde nicht gelöscht");
                   } 
               }
               
            // alte Stände wieder herstellen
               function Stand_alt_herstellen() {
                   // Input und Lautstärke
                       setTimeout(function() {
                           setState('musiccast.0.' + MC_ID + '.main.volume', stand_alt_Lautstaerke);
                           if (stand_alt_Input != "server") setState('musiccast.0.' + MC_ID + '.main.input', stand_alt_Input);
                           if (logging && stand_alt_Input != "server") log('alte Stände wieder herstellen: Input wieder auf = ' + stand_alt_Input);
                       },10000);
                   // Power
                       setTimeout(function() {
                           if (stand_alt_Power == "aus") setState('musiccast.0.' + MC_ID + '.main.power', false);
                           if (logging && stand_alt_Power == "aus") log('alte Stände wieder herstellen: Power = ' + stand_alt_Power);
                       },12000);
               }
            
            

            Erklärung:
            In den Zeilen 77-79 werden per timeout die einzelnen Funktionen aufgerufen.
            90 ff.: Hier wird die Datei kopiert
            114 ff: Hier wird geprüft ob das richtige "Verzeichnis" auf dem yamaha Lautspreche per api eingestellt ist.
            141 ff: Unterprogramm um ein Verzeichnis zu setzen
            160 ff: Hier wird die erstellte mp3 dann abgespielt
            173 ff: Dateien werden wieder gelöscht

            mfg
            Dieter

            liv-in-sky 1 Reply Last reply Reply Quote 0
            • bahnuhr
              bahnuhr Forum Testing Most Active @Asgothian last edited by

              @asgothian sagte in async / await -> Muster Anleitung gesucht:

              Diese solltest du als async definieren, dann kannst du diese mit await aufrufen.

              Danke für die Info. Aber so richtig verstanden habe ich dies nicht.

              Nach meinem Verständnis muss das System doch zurück geben: Dateien sind kopiert oder mp3 ist erstellt.
              Also so ein return "erledigt".

              Nur wie ?

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

                @bahnuhr sagte in async / await -> Muster Anleitung gesucht:

                ist aber sehr komplex und auf mich abgestimmt

                daher gibt es ja auch kein allgemeines muster - jedes script ist anders 🙂

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

                  @arteck

                  ich bin da nicht so fit wie du - ich glaube

                  • da müßte auch mit promises gearbeitet werden - was denkst du ?
                  • evtl request mit axios ersetzen

                  @bahnuhr
                  die funktion "Datei_kopieren" finde ich nicht im script - ist die unter global ?

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

                    @bahnuhr sagte in async / await -> Muster Anleitung gesucht:

                    Aber so richtig verstanden habe ich dies nicht.

                    Hilft das?
                    https://gist.github.com/AlCalzone/d14b854b69ce5e8a03718336cc650a95

                    bahnuhr 1 Reply Last reply Reply Quote 1
                    • bahnuhr
                      bahnuhr Forum Testing Most Active @AlCalzone last edited by

                      @alcalzone sagte in async / await -> Muster Anleitung gesucht:

                      @bahnuhr sagte in async / await -> Muster Anleitung gesucht:

                      Aber so richtig verstanden habe ich dies nicht.

                      Hilft das?
                      https://gist.github.com/AlCalzone/d14b854b69ce5e8a03718336cc650a95

                      Ja, kenn ich.
                      Hab ich schon mehrmals gelesen. Ist aber für mich "starker toback".

                      mfg
                      Dieter

                      1 Reply Last reply Reply Quote 0
                      • bahnuhr
                        bahnuhr Forum Testing Most Active @liv-in-sky last edited by

                        @liv-in-sky sagte in async / await -> Muster Anleitung gesucht:

                        die funktion "Datei_kopieren" finde ich nicht im script - ist die unter global ?

                        Ja, ist ein globales Script.
                        anbei:

                        function Datei_kopieren(von, nach) {
                            // Pfad immer mit / darstellen
                            // als "von" und "nach" den genauen Pfad angeben, z.B. "opt/iobroker/iobroker-data/files/vis.0/Daten/test.txt"
                            var fs = require('fs'); 
                            const datei= fs.readFileSync(von); 
                            setTimeout(function(){
                                fs.writeFileSync(nach, datei);
                            }, 500);
                        }
                        
                        1 Reply Last reply Reply Quote 0
                        • H
                          Hendrick @htrecksler last edited by Hendrick

                          @htrecksler said in async / await -> Muster Anleitung gesucht:

                          Da ist ja wieder ein Sleep-Befehl? Oder ist der in dem Fall Kosmetik?

                          Das war nur Kosmetik, aber war in diesem Fall wohl verwirrend, denn die sleep braucht es nicht.

                          @bahnuhr said in async / await -> Muster Anleitung gesucht:

                          function Datei_kopieren(von, nach)

                          Lass mal mit dieser Funktion anfangen. Diese muss auf async/await umgeschrieben werden.

                          Hier ein komplettes Beispiel:

                          const fs = require('fs');
                          
                          
                          mainAsync();
                          async function mainAsync() {
                          
                              try {
                          
                                  /**
                                   * Hier kopieren wir die Datei.
                                   */
                          
                                  log(`Trying to copy file...`);
                                  const fileSource = '/opt/iobroker/_test1/pic.png';
                                  const fileTarget = '/opt/iobroker/_test1/pic-copy.png';
                                  
                                  const fileCopied = await copyFileAsync(fileSource, fileTarget);
                                  if (!fileCopied) {
                                      // Beim Kopieren trat ein Fehler auf.
                                      log(`Datei '${fileSource}' konnte nicht nach '${fileTarget}' kopiert werden.`, 'warn');
                                      log(`Script wird beendet.`, 'warn');
                                      return false;
                                  }
                                  log(`File copied.`);
                          
                                  /**
                                   * Datei erfolgreich kopiert, hier geht's weiter
                                   */
                                  // HIER GEHT ES WEITER
                                  // ...
                                  // Setze z.B. jetzt einen Datenpunkt
                                  // await setStateAsync('0_userdata.0.test.123.Datei-ist-kopiert', {val:true, ack:false});
                          
                          
                              } catch (error) {
                                  dumpError(`[mainAsync()]`, error);
                                  return false;
                              }
                          
                          }
                          
                          
                          
                          /**
                           * Copy file async - https://stackoverflow.com/a/30405105
                           * @param {string} source     /path/to/file
                           * @param {string} target     /path/to/file
                           * @return {Promise<boolean>} true if successful, false if not
                           */
                          async function copyFileAsync(source, target) {
                          
                              const rd = fs.createReadStream(source);
                              const wr = fs.createWriteStream(target);
                          
                              try {
                          
                                  await new Promise( (resolve, reject) => {
                                      rd.on('error', reject);
                                      wr.on('error', reject);
                                      wr.on('finish', resolve);
                                      rd.pipe(wr);
                                  });
                                  return true;
                          
                              } catch (error) {
                                  rd.destroy();
                                  wr.end();
                                  dumpError(`[copyFileAsync()]`, error);
                                  return false;
                            }
                          
                          }
                          
                          
                          /**
                           * Error Message to Log. Handles error object being provided.
                           * @param {string} msg               - (intro) message of the error
                           * @param {*}      [error=undefined] - Optional: Error object or string
                           */
                          function dumpError(msg, error=undefined) {
                              if (!error) {
                                  console.error(msg);
                              } else {
                                  if (typeof error === 'object') {
                                      if (error.stack) {
                                          log(`${msg} – ${error.stack}`, 'error');
                                      } else if (error.message) {
                                          log(`${msg} – ${error.message}`, 'error');
                                      } else {
                                          log(`${msg} – ${JSON.stringify(error)}`, 'error');
                                      }
                                  } else if (typeof error === 'string') {
                                      log(`${msg} – ${error}`, 'error');
                                  } else {
                                      log(`[dumpError()] : wrong error argument: ${JSON.stringify(error)}`, 'error');
                                  }
                              }
                          }
                          

                          Zur Erklärung:
                          In der Funktion mainAsync() rufst du nach und nach all deine asynchronen Funktionen etc. auf.
                          Im Beispiel rufen wir also zunächst copyFileAsync() auf. Sobald erfolgreich kopiert, kannst du dann weitere Funktionen aufrufen, wie z.B. mit await setStateAsync() einen Datenpunkt setzen, usw.

                          bahnuhr 1 Reply Last reply Reply Quote 0
                          • H
                            Hendrick @bahnuhr last edited by

                            @bahnuhr said in async / await -> Muster Anleitung gesucht:

                            Habt ihr mal ein Muster mit diesem await, das halt wartet bis etwas erledigt ist, und dann zum nächsten await geht.

                            @htrecksler said in async / await -> Muster Anleitung gesucht:

                            Ich würde die await Funktion auch sehr gerne nutzen, habe mich aber noch nicht weiter damit beschäftigt.

                            Ich hatte auch einige Zeit gebraucht, um die async/await Logik zu verstehen 🙂
                            Oben hab ich schon mal versucht, zu erklären.
                            Weiteres Beispiel:
                            In einem Script will ich Datenpunkte anlegen, und danach diese auf Änderung überwachen. Die Überwachung auf Änderung soll aber nur stattfinden, nachdem die Datenpunkte angelegt sind, was mehrere Millisekunden dauern kann mit createState(). Daher bietet sich hier super async/await an.

                            mainAsync();
                            async function mainAsync() {
                            
                                try {
                            
                                    await createStateAsync('0_userdata.0._0_TEST.STATE_1', {name:'Test 1', type:'string', read:true, write:true, role:'state', def:'neu angelegt' });
                                    await createStateAsync('0_userdata.0._0_TEST.STATE_2', {name:'Test 2', type:'boolean', read:false, write:true, role:'button', def:false })
                            
                                    // States erstellt, jetzt machen wir Subscribe        
                                    on({id: ['0_userdata.0._0_TEST.STATE_1', '0_userdata.0._0_TEST.STATE_2'], change:'any', ack:false}, async (obj) => {
                                        log(`State '${obj.id}' changed to [${obj.state.val}]`)
                                    });        
                            
                            
                                } catch (error) {
                                    dumpError(`[mainAsync()]`, error);
                                    return false;
                                }
                            
                            }
                            
                            
                            /**
                             * Error Message to Log. Handles error object being provided.
                             * @param {string} msg               - (intro) message of the error
                             * @param {*}      [error=undefined] - Optional: Error object or string
                             */
                            function dumpError(msg, error=undefined) {
                                if (!error) {
                                    console.error(msg);
                                } else {
                                    if (typeof error === 'object') {
                                        if (error.stack) {
                                            log(`${msg} – ${error.stack}`, 'error');
                                        } else if (error.message) {
                                            log(`${msg} – ${error.message}`, 'error');
                                        } else {
                                            log(`${msg} – ${JSON.stringify(error)}`, 'error');
                                        }
                                    } else if (typeof error === 'string') {
                                        log(`${msg} – ${error}`, 'error');
                                    } else {
                                        log(`[dumpError()] : wrong error argument: ${JSON.stringify(error)}`, 'error');
                                    }
                                }
                            }
                            
                            bahnuhr 1 Reply Last reply Reply Quote 2
                            • bahnuhr
                              bahnuhr Forum Testing Most Active @Hendrick last edited by

                              @hendrick

                              Danke erst einmal von mir.
                              Ich muss mir dies mal anschauen.

                              Wenn noch jemand Beispiele hat nur her damit.

                              H 1 Reply Last reply Reply Quote 0
                              • H
                                Hendrick @bahnuhr last edited by

                                @bahnuhr said in async / await -> Muster Anleitung gesucht:

                                Wenn noch jemand Beispiele hat nur her damit.

                                Melde dich einfach, wenn du wo hängst. Ich denke das mit createStateAsync() ist ein gutes Beispiel.

                                Du kannst das auch in eine Funktion kapseln, also:

                                mainAsync();
                                async function mainAsync() {
                                
                                    try {
                                
                                        const createStateResult = await createSomeStates();
                                        if (createStateResult) {
                                            log('States erfolgreich erstellt, wir machen weiter.');
                                        } else {
                                            log('Fehler bei State-Erstellung. Wir brechen ab', 'warn');
                                            return;
                                        }
                                
                                        // States erstellt, jetzt machen wir Subscribe        
                                        on({id: ['0_userdata.0._0_TEST.STATE_1', '0_userdata.0._0_TEST.STATE_2'], change:'any', ack:false}, async (obj) => {
                                            log(`State '${obj.id}' changed to [${obj.state.val}]`)
                                        });        
                                
                                
                                    } catch (error) {
                                        dumpError(`[mainAsync()]`, error);
                                        return false;
                                    }
                                
                                }
                                
                                
                                /**
                                 * @return {Promise<boolean>}
                                 */
                                async function createSomeStates() {
                                
                                    try {
                                
                                        await createStateAsync('0_userdata.0._0_TEST.STATE_1', {name:'Test 1', type:'string', read:true, write:true, role:'state', def:'neu angelegt' });
                                        await createStateAsync('0_userdata.0._0_TEST.STATE_2', {name:'Test 2', type:'boolean', read:false, write:true, role:'button', def:false })
                                
                                        return true;
                                
                                    } catch (error) {
                                        dumpError(`[createSomeStates()]`, error);
                                        return false;
                                    }
                                
                                }
                                
                                
                                
                                
                                
                                /**
                                 * Error Message to Log. Handles error object being provided.
                                 * @param {string} msg               - (intro) message of the error
                                 * @param {*}      [error=undefined] - Optional: Error object or string
                                 */
                                function dumpError(msg, error=undefined) {
                                    if (!error) {
                                        console.error(msg);
                                    } else {
                                        if (typeof error === 'object') {
                                            if (error.stack) {
                                                log(`${msg} – ${error.stack}`, 'error');
                                            } else if (error.message) {
                                                log(`${msg} – ${error.message}`, 'error');
                                            } else {
                                                log(`${msg} – ${JSON.stringify(error)}`, 'error');
                                            }
                                        } else if (typeof error === 'string') {
                                            log(`${msg} – ${error}`, 'error');
                                        } else {
                                            log(`[dumpError()] : wrong error argument: ${JSON.stringify(error)}`, 'error');
                                        }
                                    }
                                }
                                
                                1 Reply Last reply Reply Quote 0
                                • bahnuhr
                                  bahnuhr Forum Testing Most Active @Hendrick last edited by

                                  @hendrick
                                  Hallo,
                                  habe dein Script mal probiert mit einer ts Datei, Größe 480 MB
                                  Und ein paar logs eingebaut.

                                  const fs = require('fs');
                                   
                                   
                                  log ("start");
                                  begin();
                                  
                                  function begin() {
                                      mainAsync();
                                      log ("Punkt 1")
                                  }
                                  
                                  
                                  async function mainAsync() {
                                   
                                      try {
                                   
                                          /**
                                           * Hier kopieren wir die Datei.
                                           */
                                   
                                          log(`Trying to copy file...`);
                                          const fileSource = "/opt/iobroker/iobroker-data/files/vis.0/James.ts";
                                          const fileTarget = "/mnt/Jam.ts";
                                          
                                          const fileCopied = await copyFileAsync(fileSource, fileTarget);
                                          if (!fileCopied) {
                                              // Beim Kopieren trat ein Fehler auf.
                                              log(`Datei '${fileSource}' konnte nicht nach '${fileTarget}' kopiert werden.`, 'warn');
                                              log(`Script wird beendet.`, 'warn');
                                              return false;
                                          }
                                          log(`File copied.`);
                                          await weiter();
                                  
                                          /**
                                           * Datei erfolgreich kopiert, hier geht's weiter
                                           */
                                          // HIER GEHT ES WEITER
                                          // ...
                                          // Setze z.B. jetzt einen Datenpunkt
                                          // await setStateAsync('0_userdata.0.test.123.Datei-ist-kopiert', {val:true, ack:false});
                                   
                                   
                                      } catch (error) {
                                          dumpError(`[mainAsync()]`, error);
                                          return false;
                                      }
                                   
                                  }
                                   
                                  function weiter(){
                                      log ("Punkt 2")
                                  }
                                  
                                  
                                  
                                   
                                  /**
                                   * Copy file async - https://stackoverflow.com/a/30405105
                                   * @param {string} source     /path/to/file
                                   * @param {string} target     /path/to/file
                                   * @return {Promise<boolean>} true if successful, false if not
                                   */
                                  async function copyFileAsync(source, target) {
                                   
                                      const rd = fs.createReadStream(source);
                                      const wr = fs.createWriteStream(target);
                                   
                                      try {
                                   
                                          await new Promise( (resolve, reject) => {
                                              rd.on('error', reject);
                                              wr.on('error', reject);
                                              wr.on('finish', resolve);
                                              rd.pipe(wr);
                                          });
                                          return true;
                                   
                                      } catch (error) {
                                          rd.destroy();
                                          wr.end();
                                          dumpError(`[copyFileAsync()]`, error);
                                          return false;
                                    }
                                   
                                  }
                                   
                                   
                                  /**
                                   * Error Message to Log. Handles error object being provided.
                                   * @param {string} msg               - (intro) message of the error
                                   * @param {*}      [error=undefined] - Optional: Error object or string
                                   */
                                  function dumpError(msg, error=undefined) {
                                      if (!error) {
                                          console.error(msg);
                                      } else {
                                          if (typeof error === 'object') {
                                              if (error.stack) {
                                                  log(`${msg} – ${error.stack}`, 'error');
                                              } else if (error.message) {
                                                  log(`${msg} – ${error.message}`, 'error');
                                              } else {
                                                  log(`${msg} – ${JSON.stringify(error)}`, 'error');
                                              }
                                          } else if (typeof error === 'string') {
                                              log(`${msg} – ${error}`, 'error');
                                          } else {
                                              log(`[dumpError()] : wrong error argument: ${JSON.stringify(error)}`, 'error');
                                          }
                                      }
                                  }
                                  
                                  

                                  Hiersieht man, dass "file copied" und "Punkt 2" schon nach 4 Sek. kommt.
                                  9f6519f5-0362-4623-b855-e41382df690a-image.png

                                  Wenn ich dann aber im win.Explorer nachschaue wird die Datei noch kopiert (MB zählt nach oben).

                                  Folglich scheint die Kopie doch noch nicht fertig zu sein.
                                  Oder ich versteht dies falsch und hab irgendwo einen Denkfehler.

                                  mfg
                                  Dieter

                                  H 1 Reply Last reply Reply Quote 0
                                  • H
                                    Hendrick @bahnuhr last edited by

                                    @bahnuhr

                                    Gute Frage.
                                    Die async/await-Abarbeitung im Script ist sauber.

                                    Hier nur kleine Anmerkung:
                                    Du ruft die Funktion "weiter()" per await weiter(); auf, allerdings ist diese Funktion "weiter()" nicht async definiert. Hat so jetzt keine Auswirkung im Script, aber besser machst du statt function weiter() ein async function weiter(), weil du mit await weiter(); implizierst, dass eine async Funktion aufgerufen wird, was ja so nicht der Fall ist.

                                    Jetzt aber zur Thematik:
                                    Ich habe das jetzt nicht mit einem großen File getestet. Aber so wie sich der Code in copyFileAsync() liest, wird mittels wr.on('finish', resolve); erst dann ein erfolgreiches Schreiben zurückgemeldet, wenn der Prozess abgeschlossen ist.
                                    Somit wundert es mich, dass du vorher schon die Rückmeldung bekommst.
                                    Du könntest das mal überprüfen, in dem du im Script die Dateigröße der Quelle mit der Dateigröße des Ziels vergleichst in deiner Funktion weiter() und diese als Log mal ausgibst. Dann weißt du, ob lt. Script wirklich kopiert wurde.

                                    Lange Rede, kurzer Sinn: dies hat nichts mit dem Script-Aufbau zu async/await zu tun, sondern könnte bei dir fs.createWriteStream() schon vorzeitig ein finish liefern, obwohl noch gar nicht fertig kopiert wurde.
                                    Seltsam, aber wäre es wert, näher einzusteigen.

                                    bahnuhr 2 Replies Last reply Reply Quote 0
                                    • bahnuhr
                                      bahnuhr Forum Testing Most Active @Hendrick last edited by

                                      @hendrick sagte in async / await -> Muster Anleitung gesucht:

                                      diese als Log mal ausgibst.

                                      Hast du da mal ein Scriptschnipsel.

                                      Danke, ich werds dann probieren.

                                      Fazit:
                                      Das ganze ist verdammt verwirrend und irreführend für mich.

                                      Wenn ich mir das Script so anschaue, dann sind das nur für den kopier Befehl ca. 30 Zeilen (ohne sie jetzt genau gezählt zu haben).
                                      Mein derzeitiges kopier-Script hat 3 Zeilen + timeout Zeilen.

                                      H 1 Reply Last reply Reply Quote 0
                                      • bahnuhr
                                        bahnuhr Forum Testing Most Active @Hendrick last edited by

                                        @hendrick sagte in async / await -> Muster Anleitung gesucht:

                                        Du ruft die Funktion "weiter()" per await weiter();

                                        Ja, aber nur weil du im Beispiel den:
                                        await setStateAsync('0_userdata.0.test.123.Datei-ist-kopiert', {val:true, ack:false});
                                        auch mit await aufgerufen hast.

                                        Wusste nicht, dass da ein Unterschied besteht.

                                        H 1 Reply Last reply Reply Quote 0
                                        • H
                                          Hendrick @bahnuhr last edited by

                                          @bahnuhr said in async / await -> Muster Anleitung gesucht:

                                          Fazit:
                                          Das ganze ist verdammt verwirrend und irreführend für mich.
                                          Wenn ich mir das Script so anschaue, dann sind das nur für den kopier Befehl ca. 30 Zeilen (ohne sie jetzt genau gezählt zu haben).
                                          Mein derzeitiges kopier-Script hat 3 Zeilen + timeout Zeilen.

                                          Achtung ☺

                                          Ich, und wohl jeder hier, erklären dir gerne alles. Sag weiterhin gerne Bescheid, wo du konkret Fragen hast.

                                          Viele Script-Beispiele hier im Forum sind "Quick&Dirty", aber funktionieren halt einfach 🙂

                                          Einstieg in async/await bedeutet auch, dass du DEUTLICH besseren Quellcode bekommst. Im Idealfall verifizierst da z.T. auch mehr, und wirst mehr diszipliniert, zu prüfen.

                                          Beispiel:

                                          setState('XYZ', getState('ABC').val);
                                          

                                          Hier wird einfach so ein Datenpunktwert ohne Prüfung in einen anderen Datenpunkt gesetzt. Egal, ob der DP überhaupt vorhanden ist, egal, ob der Ziel-Datenpunkt kompatibel ist zum Datentyp, etc.

                                          Im Idealfall wartet man hier erst mal ab, ob und was der getState() überhaupt zurück liefert, und reagiert dann.
                                          cf33cfef-cfd9-4e9a-8821-f59d19dd7a01-image.png

                                          Das hat jetzt nicht unbedingt mit async/await zu tun, aber Prüfungen usw. verlängeren den Quellcode, aber ersparen dir viel Ärger in der Zukunft.

                                          Auch die Nutzung von try/error wie in den obigen Beispielen.

                                          JA - Quellcode wird deutlich länger. Aber auch deutlich sicherer.

                                          1 Reply Last reply Reply Quote 0
                                          • H
                                            Hendrick @bahnuhr last edited by

                                            @bahnuhr said in async / await -> Muster Anleitung gesucht:

                                            @hendrick sagte in async / await -> Muster Anleitung gesucht:

                                            Du ruft die Funktion "weiter()" per await weiter();

                                            Ja, aber nur weil du im Beispiel den:
                                            await setStateAsync('0_userdata.0.test.123.Datei-ist-kopiert', {val:true, ack:false});
                                            auch mit await aufgerufen hast.

                                            Wusste nicht, dass da ein Unterschied besteht.

                                            setStateAsync() ist bereits eine asynchrone Funktion von ioBroker.
                                            Um async zu nutzen, rufst du diese per await setStateAsync() auf.

                                            weiter() ist deine eigene Funktion, nicht von ioBroker, und nicht von node.js oder einem Modul, hier musst du dieser Funktion selbst sagen, dass sie async ist, in dem du ein async function weiter() machst. Sonst ist sie nicht async und wird einfach so abgefeuert, und es wird auf kein Ergebnis gewartet.

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

                                            Support us

                                            ioBroker
                                            Community Adapters
                                            Donate

                                            801
                                            Online

                                            31.8k
                                            Users

                                            80.0k
                                            Topics

                                            1.3m
                                            Posts

                                            10
                                            35
                                            2243
                                            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