Seite 1 von 1

Bitte um Hilfe für Farbwechsel programmieren.

Verfasst: 31. Jan 2025 20:35
von Frigoblue
Hallo zusammen,

ich versuche einen Timer von 10 sekunden zu schreiben, in dem ein Farbwechsel für kitchen_color (eine Gruppe von Lampen) statfinden soll. Ich dachte auch ich frage mal ChatGPT dazu. Kein Script funktioniert. Dabei möchte ich doch nur alle 10 Sekunden einen Farbwechsel bei aktivieren von Item "Kitchen_Paty_Mode".

Kann mir bitte jemand helfen, ich habe von Programmieren überhaupt keine Ahnung.

Code: Alles auswählen

var List<String> colors = newArrayList("0,100,100", "60,100,100", "120,100,100", "180,100,100", "240,100,100")
var int colorIndex = 0

// Regel für den Farbwechsel
rule "Color Change Every 10 Seconds"
when
    Item Kitchen_Party_Mode changed from OFF to ON
then
    // Aktuellen Farbwert setzen
    kitchen_color.sendCommand(colors.get(colorIndex))

    // Nächsten Index berechnen, und bei Erreichen der Liste zurücksetzen
    colorIndex = (colorIndex + 1) % colors.size
end
Danke sehr für die Hilfe. Gruß Uwe

Re: Bitte um Hilfe für Farbwechsel programmieren.

Verfasst: 31. Jan 2025 21:28
von Frigoblue
Och nö, jetzt hat ChatGPT eine JS-Script geschrieben, welches Funktioniert.

Code: Alles auswählen

rules.JSRule({
    name: "Kitchen Color Change",
    description: "Ändert die Farbe von kitchen_color alle 10 Sekunden",
    triggers: [
        triggers.GenericCronTrigger("0/10 * * * * ?")
    ],
    execute: function (event) {
        var hue = Math.floor(Math.random() * 360); // Zufälliger Farbton zwischen 0 und 360
        var saturation = 100; // Maximale Sättigung
        var lightness = 50; // Mittlere Helligkeit
        
        var hslColor = hue + "," + saturation + "," + lightness;
        items.getItem("kitchen_color").sendCommand(hslColor);
    }
});
Danke das es dich gibt. :-)

Re: Bitte um Hilfe für Farbwechsel programmieren.

Verfasst: 31. Jan 2025 22:16
von udo1toni
So schlecht sieht das schon gar nicht aus (ob es funktionieren wird, steht auf einem anderen Blatt).
Die Rule beinhaltet allerdings keinen Timer :) dafür aber die Vorbereitung dafür, eine Liste von Wertetupeln zu durchlaufen.

Code: Alles auswählen

var List<String> colors = newArrayList("0,100,100", "60,100,100", "120,100,100", "180,100,100", "240,100,100")
var Integer  colorIndex = 0                                 // Index als globales Integer Objekt
var Timer        tColor = null                              // globales Timerobjekt

rule "Color Change Every 10 Seconds"
when
    Item Kitchen_Party_Mode changed                         // Party Mode aktiviert oder deaktiviert
then
    tColor?.cancel                                          // Timer canceln, falls vorhanden
    if(newState != ON)                                      // Falls nicht ON
        return;                                             // Regel beenden

    tColor = createTimer(now, [|                            // Timer anlegen
        colorIndex += 1                                     // Index erhöhen
        if(colorIndex >= colors.size)                       // Falls Obergrenze erreicht oder überschritten
            colorIndex -= colors.size                       // Obergrenze abziehen
        kitchen_color.sendCommand(colors.get(colorIndex))   // Farbwert an Color Item senden
        tColor.reschedule(now.plusSeconds(10))              // Timer erneut ausführen in 10 Sekunden
    ])
end
Wichtig: Die Rule ist sowohl für das Ein- wie auch das Ausschalten des Party Mode zuständig.
Wie auch immer ein Timer gesteuert wird, man muss sicherstellen, dass der Timer nur einmal läuft. Die einfachste Variante ist also, eventuell laufende Timer zu beseitigen, bevor man einen neuen Timer erstellt. Da dieses Beseitigen auch beim Ausschalten gebraucht wird, bietet es sich an, diese beiden Funktionen in einer Rule zu erledigen.
Gleich nach dem Beseitigen eventuell laufender Timer prüft die Rule den neuen Zustand des Schalters, falls dieser nicht ON ist, kann die Rule beendet werden. Warum So rum und nicht andersrum? Weil damit die Schachtelungstiefe nicht erhöht wird :)
Ab der ersten Leerzeile ist also sichergestellt, dass der Timer gestartet werden muss, was auch umgehend passiert. Es wird also ein Timer angelegt und damit ist die Rule beendet. (unmittelbar!)

Im Anschluss(!) daran läuft der Timer zum ersten mal ab (weil die Startzeit des Timers now ist).

Nun wird also der Timer Code ausgeführt, und der entspricht größtenteils der bereits vorhandenen Rule, der Index colorIndex wird um eins erhöht. Anschließend wird geprüft, ob der Index die Grenze der Liste erreicht hat. Ist das der Fall, wird dieser Grenzwert abgezogen.
Warum nicht %? (% -> Modulo Operator), Modulo steht nur für int zur Verfügung, nicht jedoch für Integer. int (das Primitive) ist allerdings miserabel im Zusammenhang mit DSL Rules. Integer als Objekt ist wesentlich besser geeignet und verbraucht weniger Ressourcen.
Da Modulo nicht zur Verfügung steht, muss man den Grenzwert "manuell" abziehen, was aber (siehe Code) nicht sooo schlimm ist.
Nachdem der Index sich im erlaubten Bereich befindet (0 bis Listengröße - 1), kann aus der Liste ein wert entnommen werden und ins Item geschrieben werden. Anschließend wird der Timer erneu geplant, diesmal 10 Sekunden in der Zukunft.
Der Timer wird nun also so lange erneut aufgerufen, bis er über die Ursprungsrule gecancelt wird.

Re: Bitte um Hilfe für Farbwechsel programmieren.

Verfasst: 31. Jan 2025 23:14
von Frigoblue
Hallo guten Abend udo1toni,

ich bin mächtig überwältigt. Besser als die KI Dein Script funktioniert. Ich habe eine Bitte: Könntest du noch eine Funktion einbauen, wenn der Status des Items "Kitchen_Party_Mode" OFF geschaltet wird, das dann der Befehl: kitchen_color.sendCommand(0.0.100) = Alle LED wirden weiße Farbe.

Vielen vielen dank. Gruß Uwe

Re: Bitte um Hilfe für Farbwechsel programmieren.

Verfasst: 1. Feb 2025 01:12
von udo1toni
Ja, das ist kein Problem :)
Ich spare mir hier die Zeilen drum herum... Die erste und letzte Zeile des Codes hier sind die letzte bzw. erste unveränderte Zeile im Originalcode ;)

Code: Alles auswählen

    tColor?.cancel                                          // Timer canceln, falls vorhanden
    if(newState != ON) {                                    // Falls nicht ON
        kitchen_color.sendCommand("0,0,100")                // OFF-Befehl und Farbe auf weiß
        return;                                             // Regel beenden
    }
    tColor = createTimer(now, [|                            // Timer anlegen
Beim OFF-Befehl wird ja die Rule vorzeitig beendet. Nun fügen wir einfach noch den zusätzlichen Ausschaltbefehl ein. Allerdings haben wir nun im if-Block zwei Befehle, weshalb die Befehle gruppiert werden müssen, das geschieht mit den geschwungenen Klammern. Letztlic hist es also nur eine zusätzliche Zeile Code, plus die beiden Klammern.

Re: Bitte um Hilfe für Farbwechsel programmieren.

Verfasst: 1. Feb 2025 15:51
von Frigoblue
Hallo guten Tag udo1toni,

auch hier ein ganz großes Dankeschön und Respekt für die sehr gute Arbeit.