NEWS

[gelöst]Skript als Alternative zum Scenenadapter


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


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

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

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


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

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


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


  • @paul53

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


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

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

Suggested Topics

  • 6
  • 11
  • 10
  • 21
  • 46
  • 4
  • 23
  • 13

1.3k
Online

36.7k
Users

42.4k
Topics

587.4k
Posts