Hi everyone,
I’ve written a rule in JS Scripting that simulates a sunrise by gradually increasing the brightness of a group of lights. The animation runs in multiple steps using a timer that gets rescheduled after each step:
let duration = items.Time_GF_Bedroom_DurationSunriseSimulation.numericState;
let delay = Math.round(duration / steps);
and
timerItem.reschedule(time.toZDT().plusSeconds(delay));
Problem
- Before editing the rule, the animation ran way too fast (steps executed almost instantly).
- After editing the rule, it now runs with the correct delay.
Example logs (before, too fast):
2025-03-12 14:48:36.229 [INFO ] [.model.script.start Sunset Animation] - Animation progress: Step 0/50
2025-03-12 14:48:39.622 [INFO ] [.model.script.start Sunset Animation] - Animation progress: Step 0/50
2025-03-12 14:48:40.944 [INFO ] [.model.script.start Sunset Animation] - Animation progress: Step 10/50
After editing the rule (correct delay):
2025-03-12 14:52:59.947 [INFO ] [.model.script.start Sunset Animation] - Animation progress: Step 0/50
2025-03-12 14:53:20.015 [INFO ] [.model.script.start Sunset Animation] - Animation progress: Step 10/50
Why could this be happening? Could delay
have been calculated incorrectly, or was the timer not properly initialized? Has anyone experienced something similar?
Thanks for your help!
here is the complete rule
rules.JSRule({
name: "start Sunset Animation",
description: "Simuliert einen Sonnenaufgang durch Farb- und Helligkeitsänderung.",
triggers: [
triggers.ItemCommandTrigger("Switch_GF_Bedroom_SunriseSimulation", "ON") // Item to start the animation
],
execute: (event) => {
try{
const triggerItem = event.itemName;
/*const timerMap = {
Switch_GF_Bedroom_SunriseSimulation: timerSunriseBedroom
};*/
const lightColorMap = {
Switch_GF_Bedroom_SunriseSimulation: "Group_GF_Bedroom_ColorLight",
};
if (!lightColorMap[triggerItem]) {
actions.Log.logWarn("start Sunset Animation", "Unknown trigger item: ${triggerItem}");
}else if (items.Switch_House_SmartHomeAutomation.state.toString() == "ON") {
//const sceneValue = items.getItem(triggerItem).numericState;
let timerItem = null;
/*if ( triggerItem == "Switch_GF_Bedroom_SunriseSimulation" ) {
actions.Log.logWarn("activate deConz Scene", "Uf: ${triggerItem}");
timerItem = timerSunriseBedroom;
}*/
//let timerItem = timerMap[triggerItem];
//actions.Log.logWarn("start Sunset Animation", `U: ${timerItem}`);
let lightColorGroupItem = items.getItem(lightColorMap[triggerItem]);
// Configurable Parameters
//const lightItem = "Group_GF_Bedroom_ColorLight"; // Name of the Hue Color Item
const steps = 50; // Number of steps in the simulation
let duration = items.Time_GF_Bedroom_DurationSunriseSimulation.numericState; // Duration in milliseconds
let delay = Math.round(duration / steps); // Time per step
// actions.Log.logInfo("start Sunset Animation",`Sonnenaufgangs-Animation uu ${delay}`);
// Starting values
const startHue = 0; // Initial Hue (Red)
const startSaturation = 100; // Maximum saturation
const startBrightness = 0; // Initial brightness
// Target values
const endHue = 188; // Target Hue
const endSaturation = 4; // Target saturation
const endBrightness = 100; // Target brightness
// Timer-based animation
let step = 0; // Start at step 0
timerItem = actions.ScriptExecution.createTimer(time.toZDT().plusSeconds(delay), () => {
if (step > steps) {
timerItem.cancel();
items.getItem('Switch_GF_Bedroom_SunriseSimulation').sendCommand('OFF');
actions.Log.logInfo("start Sunset Animation","Sonnenaufgangs-Animation abgeschlossen.");
return;
}
// Calculate interpolated values
let currentHue = Math.round(startHue + (step / steps) * (endHue - startHue));
let currentSaturation = Math.round(startSaturation + (step / steps) * (endSaturation - startSaturation));
let currentBrightness = Math.round(startBrightness + (step / steps) * (endBrightness - startBrightness));
// Apply the calculated settings
lightColorGroupItem.sendCommand(`${currentHue},${currentSaturation},${currentBrightness}`);
actions.Log.logInfo("start Sunset Animation",`Set light to: Hue=${currentHue}, Saturation=${currentSaturation}, Brightness=${currentBrightness}`);
// Log progress at certain steps (optional)
if (step % 10 === 0) {
actions.Log.logInfo("start Sunset Animation",`Animation progress: Step ${step}/${steps}`);
}
// Increment the step and reschedule the timer
step++;
timerItem.reschedule(time.toZDT().plusSeconds(delay));
});
// actions.Log.logWarn("start Sunset Animation", `U: ${timerSunriseBedroom}`);
if ( triggerItem == "Switch_GF_Bedroom_SunriseSimulation" ) {
//actions.Log.logWarn("activate deConz Scene", "Uf: ${triggerItem}");
timerSunriseBedroom = timerItem;
}
//actions.Log.logWarn("start Sunset Animation", `U: ${timerSunriseBedroom}`);
actions.Log.logInfo("start Sunset Animation","Sonnenaufgangs-Animation gestartet.");
} else {
actions.Log.logInfo("start Sunset Animation", "Master automation switch is off");
}
}
catch(error) {
actions.Log.logError("start Sunrise Animation", "Some bad stuff happened in \"start Sunrise Animation\": " +error.toString());
}
finally {
}
},
tags: ["start Sunriseanimation"],
id: "start Sunriseanimation"
});