Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. [gelöst]Skript als Alternative zum Scenenadapter

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

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

    • ioBroker goes Matter ... Matter Adapter in Stable

    [gelöst]Skript als Alternative zum Scenenadapter

    This topic has been deleted. Only users with topic management privileges can see it.
    • paul53
      paul53 @Dominik F. last edited by

      @Dominik-F sagte:

      diese 'Änderung vorzunehmen?

      Zusätzlich zu logging muss der neue Status sich vom im Datenpunkt enthalten Wert unterscheiden, damit log() ausgeführt wird.

      Dominik F. 1 Reply Last reply Reply Quote 0
      • Dominik F.
        Dominik F. @paul53 last edited by

        @paul53

        Ich danke dir für deine Erklärung. Ich habe nun den Datenpunkt Button durch einen State ersetzt und versucht alle Datenpunkte damit zu schalten. Das funktioniert soweit auch nur habe ich jetzt noch 2 Probleme.
        Das logging zeigt für aktiv richtig an, für false wird 4x inaktiv angezeigt bei 4 states die auf false gesetzt werden.
        2tes Problem ist, das ich ja grundsätzlich möchte, dass wenn wenn ich den aktivieren state auf true setze, die szene aktiviert wird und alle states auf true gesetzt werden und andersherum eben auf false. Die states werden nun aber unabhängig davon geschaltet. Sind alle states auf true und ich schalte den Datenpunkt aktivieren auf true, sollte eigentlich nichts passieren, es wird jedoch alles auf false gesetzt. Hast du da noch eine Idee?

        
        //Grundeinstellungen
        const logging = true; // Logs ausgeben
        const praefix = "javascript.0.Szenen."; //Grundpfad für Script DPs - Muß innerhalb javascript.x sein.
        
        const SzeneData = [];
        const SzeneID = [];
        
        //Name der Szenen eingeben
        const SzenenName = "Chillen";
        
        //Hier die IDs eingeben
        SzeneID[0] = "zigbee.0.f0d1b8000010bb79.state";  //Stehlampe
        SzeneID[1] = "zigbee.0.7cb03eaa0a068b8d.state";  //Laterne
        SzeneID[2] = "zigbee.0.7cb03eaa00b1b716.state";  //Sideboard
        SzeneID[3] = "zigbee.0.7cb03eaa0a06f6b0.state";  //Vitrine
        
        //Schleife durch die ID's und Werte
        for (let x = 0; x < SzeneID.length; x++) {
            SzeneData[x] = getState(SzeneID[x]).val;
        };
        
        //Datenpunkte erstellen
        createState(praefix + SzenenName + ".activate", false, { name: "Szene aktivieren/deaktivieren", role: "state" });
        createState(praefix + SzenenName + ".is_activ", { name: "is acitv?", role: "indicator" });
        
        //Ab hier eigentliches Skript
        function Szene() {
            let Status = true;
            for (let x = 0; x < SzeneData.length; x++) {
                if (!SzeneData[x]) Status = false;
            }
            if (logging && Status != getState(praefix + SzenenName + ".is_activ").val) {
                if (Status) log("Szene " + SzenenName + " aktiv");
                else log("Szene " + SzenenName + " inaktiv");
            }
            setState(praefix + SzenenName + ".is_activ", Status);
        
            // Szene einschalten/ausschalten
            on({ id: praefix + SzenenName + ".activate", change: "any" }, function (obj) {
                for (let x = 0; x < SzeneID.length; x++) {
                    if (obj.newState.val && praefix + SzenenName + ".is_activ") { setState(SzeneID[x], false); }
                    else { setState(SzeneID[x], true); }
                }
            });
        };
        Szene();
        for (let x = 0; x < SzeneID.length; x++) { //Trigger in Schleife erstellen
            on(SzeneID[x], function (dp) { // triggert bei Wertänderung
                SzeneData[x] = dp.state.val;
                Szene();
            });
        };
        
        
        paul53 1 Reply Last reply Reply Quote 0
        • paul53
          paul53 @Dominik F. last edited by paul53

          @Dominik-F sagte:

          wenn wenn ich den aktivieren state auf true setze, die szene aktiviert wird und alle states auf true gesetzt werden und andersherum eben auf false.

          Einen Trigger darf man nicht innerhalb einer Funktion definieren, weil dann bei jedem Aufruf der Funktion eine weiterer Trigger mit der gleichen Funktionalität erzeugt und so das System irgendwann überlastet wird. Außerhalb der Funktion (z.B. am Ende des Scripts):

          // Szene einschalten/ausschalten
          on(praefix + SzenenName + ".activate", function (obj) { // triggert bei Wertänderung
              for (let x = 0; x < SzeneID.length; x++) {
                  setState(SzeneID[x], obj.state.val);
              }
          });
          
          Dominik F. 1 Reply Last reply Reply Quote 1
          • Dominik F.
            Dominik F. @paul53 last edited by

            @paul53

            Es funktioniert 🙂 Vielen Dank mal wieder. Ich glaube ich muss mir das Thema Trigger nochmal genauer anschauen
            Hast du auch noch eine Idee zu den Logs?

            paul53 1 Reply Last reply Reply Quote 0
            • paul53
              paul53 @Dominik F. last edited by

              @Dominik-F sagte:

              Hast du auch noch eine Idee zu den Logs?

              Bei Szenenwechsel werden 4 Trigger ausgelöst und somit 4 mal die Funktion aufgerufen. Um den Funktionsaufruf bei gewolltem Szenenwechsel zu vermeiden, kann man die Quelle auswerten. Versuche mal

              for (let x = 0; x < SzeneID.length; x++) { //Trigger in Schleife erstellen
                  on(SzeneID[x], function (dp) { // triggert bei Wertänderung
                      SzeneData[x] = dp.state.val;
                      if(dp.state.from != 'system.adapter.javascript.' + instance) Szene();
                  });
              };
              
              Dominik F. 1 Reply Last reply Reply Quote 0
              • Dominik F.
                Dominik F. @paul53 last edited by

                @paul53

                Bevor ich das versuche hab ich noch eine Frage. Wieso passiert das ganze nur beim ausschalten der Szene? Beim einschalten wird nur ein Log ausgelöst.

                paul53 1 Reply Last reply Reply Quote 0
                • paul53
                  paul53 @Dominik F. last edited by

                  @Dominik-F sagte:

                  Wieso passiert das ganze nur beim ausschalten der Szene?

                  Gute Frage. Ich vermute, dass

                      setState(praefix + SzenenName + ".is_activ", Status);
                  

                  unterschiedlich lange benötigt, bis der richtige Wert bei der Abfrage

                      if (logging && Status != getState(praefix + SzenenName + ".is_activ").val) {
                  

                  zurück geliefert wird. Oder die Trigger reagieren unterschiedlich schnell auf den Wechsel ?

                  Dominik F. 1 Reply Last reply Reply Quote 0
                  • Dominik F.
                    Dominik F. @paul53 last edited by

                    @paul53

                    ja, Gefühlt schalten alle states gleichzeitig ein, aber unterschiedlich aus bzw. mit leichter Verzögerung.

                    paul53 1 Reply Last reply Reply Quote 0
                    • paul53
                      paul53 @Dominik F. last edited by

                      @Dominik-F sagte:

                      unterschiedlich aus bzw. mit leichter Verzögerung.

                      Um Laufzeitprobleme bei Verwendung von getState() zu vermeiden, sollte man besser eine Variable verwenden.

                      //Ab hier eigentliches Skript
                      var lastState = getState(praefix + SzenenName + ".is_activ").val;
                      function Szene() {
                          let Status = true;
                          for (let x = 0; x < SzeneData.length; x++) {
                              if (!SzeneData[x]) Status = false;
                          }
                          if (Status != lastState) {
                              if(logging) {
                                  if (Status) log("Szene " + SzenenName + " aktiv");
                                  else log("Szene " + SzenenName + " inaktiv");
                              }
                              setState(praefix + SzenenName + ".is_activ", Status, true);
                          }
                          lastState = Status;
                      }
                      
                      1 Reply Last reply Reply Quote 1
                      • Dominik F.
                        Dominik F. last edited by

                        Super, jetzt funktioniert wirklich alles 🙂 Ich vermute das liegt daran, dass die states den Befehl mit leichter Verzögerung untereinander erhalten?

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

                        Support us

                        ioBroker
                        Community Adapters
                        Donate

                        776
                        Online

                        31.8k
                        Users

                        80.0k
                        Topics

                        1.3m
                        Posts

                        javascript
                        2
                        17
                        533
                        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