Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. JavaScript
  5. [gelöst]Skript als Alternative zum Scenenadapter

NEWS

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    8.8k

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    13
    1
    2.2k

  • Neues Video "KI im Smart Home" - ioBroker plus n8n
    BluefoxB
    Bluefox
    16
    1
    3.2k

[gelöst]Skript als Alternative zum Scenenadapter

Geplant Angeheftet Gesperrt Verschoben JavaScript
javascript
17 Beiträge 2 Kommentatoren 596 Aufrufe 4 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • paul53P paul53

    @Dominik-F sagte:

    Zeile 28

    Auf deutsch: Wenn nicht Element x im Array, dann Status = false (ein Element ist nicht true, also false)

    @Dominik-F sagte in Skript als Alternative zum Scenenadapter:

    Änderungen ab Zeile 39 erklären?

    • Einem Trigger (on) muss die ID übergeben werden. Wenn nur die ID als String übergeben wird, wird nur bei Wertänderung getriggert.
    • Der Wert des Trigger-Datenpunktes wird in die passende Position des Daten-Arrays geschrieben und anschließend wird der Inhalt des Daten-Arrays durch Aufruf der Funktion Szene() ausgewertet.

    @Dominik-F sagte in Skript als Alternative zum Scenenadapter:

    Ich bekomme das logging im Moment doppelt. hast du da noch eine idee?

    ? Habe mal die geschweifte Klammern gegen Semikolon ausgetauscht.

    Dominik F.D Offline
    Dominik F.D Offline
    Dominik F.
    schrieb am zuletzt editiert von
    #5

    @paul53

    Vielen Dank für deine Erklärung, wieder was dazu gelernt :)

    Das Logging ist immer noch nicht so wie es sein soll. Sobald sich einer der Werte ändert, wird das logging ausgelöst. Mache ich nur einen der beiden Datenpunkte auf true, dann wird szene inaktiv geloggt. Das überschwemmt ja total den log. Es reicht ja, wenn das log ausgelöst wird, wenn der Datenpunkt is_active sich ändert.

    paul53P 1 Antwort Letzte Antwort
    0
    • Dominik F.D Dominik F.

      @paul53

      Vielen Dank für deine Erklärung, wieder was dazu gelernt :)

      Das Logging ist immer noch nicht so wie es sein soll. Sobald sich einer der Werte ändert, wird das logging ausgelöst. Mache ich nur einen der beiden Datenpunkte auf true, dann wird szene inaktiv geloggt. Das überschwemmt ja total den log. Es reicht ja, wenn das log ausgelöst wird, wenn der Datenpunkt is_active sich ändert.

      paul53P Offline
      paul53P Offline
      paul53
      schrieb am zuletzt editiert von
      #6

      @Dominik-F sagte:

      Es reicht ja, wenn das log ausgelöst wird, wenn der Datenpunkt is_active sich ändert.

      Dann erweitere Zeile 30.

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

      Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
      Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

      Dominik F.D 1 Antwort Letzte Antwort
      1
      • paul53P paul53

        @Dominik-F sagte:

        Es reicht ja, wenn das log ausgelöst wird, wenn der Datenpunkt is_active sich ändert.

        Dann erweitere Zeile 30.

            if (logging && Status != getState(praefix + SzenenName + ".is_activ").val) {
        
        Dominik F.D Offline
        Dominik F.D Offline
        Dominik F.
        schrieb am zuletzt editiert von
        #7

        @paul53

        Super, jetzt funktioniert es.
        Könntest du mir kurz erklären wie du darauf gekommen bist diese 'Änderung vorzunehmen?
        Sorry wenn ich so viel frage, ich möchte das verstehen damit ich in Zukunft selber Lösungen finden kann.

        paul53P 1 Antwort Letzte Antwort
        0
        • Dominik F.D Dominik F.

          @paul53

          Super, jetzt funktioniert es.
          Könntest du mir kurz erklären wie du darauf gekommen bist diese 'Änderung vorzunehmen?
          Sorry wenn ich so viel frage, ich möchte das verstehen damit ich in Zukunft selber Lösungen finden kann.

          paul53P Offline
          paul53P Offline
          paul53
          schrieb am zuletzt editiert von
          #8

          @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.

          Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
          Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

          Dominik F.D 1 Antwort Letzte Antwort
          0
          • paul53P paul53

            @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.D Offline
            Dominik F.D Offline
            Dominik F.
            schrieb am zuletzt editiert von
            #9

            @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();
                });
            };
            
            
            paul53P 1 Antwort Letzte Antwort
            0
            • Dominik F.D Dominik F.

              @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();
                  });
              };
              
              
              paul53P Offline
              paul53P Offline
              paul53
              schrieb am zuletzt editiert von paul53
              #10

              @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);
                  }
              });
              

              Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
              Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

              Dominik F.D 1 Antwort Letzte Antwort
              1
              • paul53P 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.D Offline
                Dominik F.D Offline
                Dominik F.
                schrieb am zuletzt editiert von
                #11

                @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?

                paul53P 1 Antwort Letzte Antwort
                0
                • Dominik F.D Dominik F.

                  @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?

                  paul53P Offline
                  paul53P Offline
                  paul53
                  schrieb am zuletzt editiert von
                  #12

                  @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();
                      });
                  };
                  

                  Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
                  Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

                  Dominik F.D 1 Antwort Letzte Antwort
                  0
                  • paul53P paul53

                    @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.D Offline
                    Dominik F.D Offline
                    Dominik F.
                    schrieb am zuletzt editiert von
                    #13

                    @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.

                    paul53P 1 Antwort Letzte Antwort
                    0
                    • Dominik F.D Dominik F.

                      @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.

                      paul53P Offline
                      paul53P Offline
                      paul53
                      schrieb am zuletzt editiert von
                      #14

                      @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 ?

                      Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
                      Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

                      Dominik F.D 1 Antwort Letzte Antwort
                      0
                      • paul53P paul53

                        @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.D Offline
                        Dominik F.D Offline
                        Dominik F.
                        schrieb am zuletzt editiert von
                        #15

                        @paul53

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

                        paul53P 1 Antwort Letzte Antwort
                        0
                        • Dominik F.D Dominik F.

                          @paul53

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

                          paul53P Offline
                          paul53P Offline
                          paul53
                          schrieb am zuletzt editiert von
                          #16

                          @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;
                          }
                          

                          Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
                          Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

                          1 Antwort Letzte Antwort
                          1
                          • Dominik F.D Offline
                            Dominik F.D Offline
                            Dominik F.
                            schrieb am zuletzt editiert von
                            #17

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

                            1 Antwort Letzte Antwort
                            0
                            Antworten
                            • In einem neuen Thema antworten
                            Anmelden zum Antworten
                            • Älteste zuerst
                            • Neuste zuerst
                            • Meiste Stimmen


                            Support us

                            ioBroker
                            Community Adapters
                            Donate

                            914

                            Online

                            32.4k

                            Benutzer

                            81.5k

                            Themen

                            1.3m

                            Beiträge
                            Community
                            Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                            ioBroker Community 2014-2025
                            logo
                            • Anmelden

                            • Du hast noch kein Konto? Registrieren

                            • Anmelden oder registrieren, um zu suchen
                            • Erster Beitrag
                              Letzter Beitrag
                            0
                            • Home
                            • Aktuell
                            • Tags
                            • Ungelesen 0
                            • Kategorien
                            • Unreplied
                            • Beliebt
                            • GitHub
                            • Docu
                            • Hilfe