Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. Script Formulierung

    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

    Script Formulierung

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

      @ticaki sagte in Script Formulierung:

      @senior1418
      ist doch ganz gut. Da das Json die Eigenschaft length hat könnte man das weg lassen, das async müsste auch unnötig sein.

      while ( jsonObj.length > 13) {
         jsonObj.splice(a,1);
      }
      
      createState(id, JSON.stringify([])...
      

      OK, verstehe - habe in der Hierarchie zu hoch angesetzt ..
      Aber wie wird das "a" abgeleitet ? ```

       jsonObj.splice(a,1);
      
      T 1 Reply Last reply Reply Quote 0
      • T
        ticaki Developer @senior1418 last edited by

        @senior1418
        Ups... das a ist 0. Ich hatte vorher ne for schleife, aber die war überflüssig groß, hab das a vergessen zu ändern.

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

          @ticaki sagte in Script Formulierung:

          Ups... das a ist 0. Ich hatte vorher ne for schleife, ....

          alles klar.

          Mich stört bei meiner Vorgehensweise, dass das Skript zweimal ausgeführt werden muss wenn der Datenpunkt nicht vorhanden ist. Beim ersten Start bei nicht Vorhandensein des Datenpunktes ein wird ein Fehler erzeugt.

          T BananaJoe 2 Replies Last reply Reply Quote 0
          • T
            ticaki Developer @senior1418 last edited by ticaki

            @senior1418

            Ein Teil aus einem meiner Skripte (nur kopiert nicht bearbeitet) der dein Problem löst:

            createThisStates();
            async function createThisStates()
            {
                objJson = getValuePerRoom({}, $(cHeater),'cHeater', false);
                objJson = getValuePerRoom(objJson, $(cSensorTemp), 'cSensorTemp');
                objJson = getValuePerRoom(objJson, $(cWindows), 'cWindows');
                objJson = getValuePerRoom(objJson, $(cNewTemp), 'cNewTemp');
                for (let room in objJson) {
                        let currentDir = mainDir+DOT+room+DOT;
                        let roomId = getEnumIDbyName(room);
                        try {
                            if (!await existsStateAsync(currentDir + tHeater)) {
                                await createStateAsync(currentDir + tHeater,false, true, {read:true, write:false, def:false, name:"Stellantrieb", type:"boolean" },);
                                if (roomId != '') await addToEnum(roomId, currentDir + tHeater);
                            }
                            if ((!await existsStateAsync(currentDir + tSensorTemp))) {
                                await createStateAsync(currentDir + tSensorTemp, {read:true, write:false, def:0, name:"Ist-Temperatur", type:"number", }, );
                                if (roomId != '') await addToEnum(roomId, currentDir + tSensorTemp);
                            }
                            if (!await existsStateAsync(currentDir + tWindows)) {
                                await createStateAsync(currentDir + tWindows, {read:true, write:false, def:false, name:"Fenster offen", type:"boolean", }, );
                                if (roomId != '') await addToEnum(roomId, currentDir + tWindows);
                            }
                            if (!await existsStateAsync(currentDir + tTargetTemp)) {
                                await createStateAsync(currentDir + tTargetTemp, {read:true, write:true, def:18, name:"Soll-Temperatur", type:"number", }, );
                                if (roomId != '') await addToEnum(roomId, currentDir + tTargetTemp);
                            }
                        }
                        catch(error) {
                            log(error);
                        }
            // hier die nächste Funktion/Code aufrufen 
            

            EDIT: ah das ist ja noch das false, true im ersten Aufruf, kann weg ist noch vom Fehler suchen drin. getValuePerRoom sowie addToEnum sind eigene Funktionen

            1 Reply Last reply Reply Quote 0
            • BananaJoe
              BananaJoe Most Active @senior1418 last edited by

              @senior1418 ich hatte die Frage auch schon mal gestellt:

              https://forum.iobroker.net/topic/44190/datenpunkt-erstellen-und-im-anschluss-sofort-nutzen/11?_=1635937166549

              T 1 Reply Last reply Reply Quote 0
              • T
                ticaki Developer @BananaJoe last edited by

                @bananajoe sagte in Script Formulierung:

                @senior1418 ich hatte die Frage auch schon mal gestellt:

                https://forum.iobroker.net/topic/44190/datenpunkt-erstellen-und-im-anschluss-sofort-nutzen/11?_=1635937166549

                So hab ich das vorher auch gemacht.

                BananaJoe 1 Reply Last reply Reply Quote 0
                • BananaJoe
                  BananaJoe Most Active @ticaki last edited by

                  @ticaki sind auch ein paar einfache antworten dabei 🙂

                  T 1 Reply Last reply Reply Quote 0
                  • T
                    ticaki Developer @BananaJoe last edited by ticaki

                    @bananajoe
                    Ok dann überarbeite ich meine Antwort mal auf einfach 🙂 (hast ja recht)

                    createThisStates('bla.blu.ding.dong');
                    async function createThisStates(id)
                    {
                        try {
                            if (!await existsStateAsync(id)) {
                                await createStateAsync(id, {read:true, write:false, def:false, name:"Hier steht was verständliches", type:"boolean" },);
                            }
                        }
                        catch(error) {
                            log(error);
                        }
                        states_erstellt_mache_was()
                        // man kann natürlich auch einfach den Code hier einfügen, ich mache es halt häufig mit Funktionen
                    }
                    
                    function states_erstellt_mache_was(){
                        log('sinnvolles');
                    };
                    

                    das try ist nötig, weil sonst im Fehlerfall der Adapter neustartet.

                    1 Reply Last reply Reply Quote 0
                    • BananaJoe
                      BananaJoe Most Active last edited by BananaJoe

                      @ticaki mal ganz dumm nachgefragt:

                      Wenn ich mir eine async Funktion baue um darin createStateAsync nutzen zu können und diese dann aufrufe ... dann läuft mein Script weiter?

                      // Global
                      var s_DeviceName = "K58-Buero-Steckdose-oben";
                      var s_state_rootpath = "0_userdata.0.tasmota.";
                      
                      // Funktionen
                      async function CreateMyStates(){
                          // POWER
                          await createStateAsync(s_state_rootpath + s_DeviceName + ".POWER", false, {
                              type: 'boolean',
                              read: true, 
                              write: true, 
                              name: s_DeviceName + ': AN (=true) oder AUS (=false)'
                              });
                      }
                      
                      //Hauptprogramm
                      CreateMyStates();
                      setState(s_state_rootpath + s_DeviceName + ".POWER", true, true);
                      

                      Würde beim ersten mal auf einen Fehler laufen weil es nach CreateMyStates(); sofort weiter geht?
                      Deshalb muss ich die Erstbefüllung mit in die Funktion packen, richtig?

                      T 1 Reply Last reply Reply Quote 0
                      • T
                        ticaki Developer @BananaJoe last edited by ticaki

                        @BananaJoe
                        Ja, jedoch kannst du auch alles in die Funktion packen.

                        so würde ich das machen

                        vorher

                        // Global
                        var s_DeviceName = "K58-Buero-Steckdose-oben";
                        var s_state_rootpath = "0_userdata.0.tasmota.";
                         
                        // Funktionen
                        createState(s_state_rootpath + s_DeviceName + ".POWER", false, {
                                type: 'boolean',
                                read: true, 
                                write: true, 
                                name: s_DeviceName + ': AN (=true) oder AUS (=false)'
                                });
                        }
                         
                        //Hauptprogramm
                        setState(s_state_rootpath + s_DeviceName + ".POWER", true, true);
                        

                        zwischen Schritt der ist auch lauffähig wir packen alles außer den Variablen in einen Block der aus 2 * { besteht und fügen noch zusätzlich ein try und catch ein. Das fängt Fehler auf und ist zumindest um die Awaits zwingend nötig. Hab der Einfachheit halber alles in den Block gesetzt.

                        // Global
                        var s_DeviceName = "K58-Buero-Steckdose-oben";
                        var s_state_rootpath = "0_userdata.0.tasmota.";
                        
                        {
                            try {
                            // Funktionen
                                createState(s_state_rootpath + s_DeviceName + ".POWER", false, {
                                    type: 'boolean',
                                    read: true, 
                                    write: true, 
                                    name: s_DeviceName + ': AN (=true) oder AUS (=false)'
                                });    
                            //Hauptprogramm
                                setState(s_state_rootpath + s_DeviceName + ".POWER", true, true);
                            }
                            catch(error) {
                                log(error);
                            }
                        }
                        

                        im letzten Schritt bauen wir Async und Await ein. Dazu setzten wir vor die erste { die Funktionsdefinition und benutzen die async Funktionen sowie await.

                        var s_DeviceName = "K58-Buero-Steckdose-oben";
                        var s_state_rootpath = "0_userdata.0.tasmota.";
                        
                        async function createMyStates(){
                            try {
                            // Funktionen
                                await createStateAsync(s_state_rootpath + s_DeviceName + ".POWER", false, {
                                    type: 'boolean',
                                    read: true, 
                                    write: true, 
                                    name: s_DeviceName + ': AN (=true) oder AUS (=false)'
                                });    
                            //Hauptprogramm
                                setState(s_state_rootpath + s_DeviceName + ".POWER", true, true);
                            }
                            catch(error) {
                                log(error);
                            }
                        }
                        createMyStates();
                        

                        EDIT: wobei man hier auch await setStateAsync() benutzen könnte.
                        EDIT2: ---
                        EDIT3: Edit 2 hat sich erledigt, man sollte halt in weiterführenden Funktionen nicht auf States zugreifen die tatsächlich noch nicht erstellt worden sind. 🙂

                        BananaJoe 1 Reply Last reply Reply Quote 0
                        • BananaJoe
                          BananaJoe Most Active @ticaki last edited by

                          @ticaki ok, ich hab mein Skript nun so geändert das die Erstellung und die Erstbefüllung in einer async function stattfindet. Sieht auch gut aus, beim ersten Start werden die Datenpunkte erstellt und es gibt keine Fehlermeldungen mehr.

                          Der Rest des Skriptes besteht aus on() Subscriptions, unter anderem auf einen der Datenpunkte die ggf. zuvor erst erstellt wurden:

                          // unsere JavaScript-Instanz um zu prüfen ob die Änderung durch MQTT oder durch VIS ausgelöst wurde
                          const js = 'system.adapter.javascript.' + instance;
                          
                          // Datenpunkt POWER überwachen:
                          on({ id: s_state_rootpath + s_DeviceName + ".POWER", change: "ne", fromNe: js }, function (obj) {
                              var b_value_POWER = obj.state.val;
                              ...
                              ...
                          }
                          

                          Sollte ich da auch etwas beachten? Oder klappt das mit dem on auch wenn es den Datenpunkt noch nicht gibt?

                          T 1 Reply Last reply Reply Quote 0
                          • T
                            ticaki Developer @BananaJoe last edited by ticaki

                            @bananajoe
                            Das weiß ich nicht. bei mir sieht das so aus:

                            ein kleiner ausschnitt

                                        if (!await existsStateAsync(currentDir + endOfState)) {
                                            await createStateAsync(currentDir + endOfState, {read:true, write:true, def:18, name:"Soll-Temperatur niedrig H/K", type:"number", }, );
                                        }
                                        endOfState = tTargetHeatingCoolingState;
                                        if (!await existsStateAsync(currentDir + endOfState)) {
                                            await createStateAsync(currentDir + endOfState, {read:true, write:true, def:0, name:"Zielstatus der Heizung/Kühlung", type:"number", }, );
                                        }
                                        
                                        on({id:currentDir + tHeatingThresholdTemperature, change:'ne'}, setAckSetStell);
                                        on({id:currentDir + tCoolingThresholdTemperature, change:'ne'}, setAckSetStell);
                            
                            // hier fehlt viel
                            
                            function setAckSetStell(obj){   
                                setStell();
                                setState(obj.id, obj.state.val, true);
                            }
                            

                            Ich versuche das alles zusammen zu halten damit ich die on() besser finde.

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

                            Support us

                            ioBroker
                            Community Adapters
                            Donate

                            809
                            Online

                            31.8k
                            Users

                            80.0k
                            Topics

                            1.3m
                            Posts

                            3
                            14
                            628
                            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