rules.JSRule({
name: "Switch TV automated off",
description: "Switch TV automated off",
triggers: [triggers.ItemStateChangeTrigger("switch_tvlivingroom_debouncedpresence"), triggers.ItemStateChangeTrigger("Z_way_number_WallPlug10_actualpower")],
execute: (event) => {
if (items.Z_way_number_WallPlug10_actualpower.numericState < 14){
console.log("Switch TV automated off, start timer");
actions.ScriptExecution.createTimer('timertvautomation', time.toZDT().plusSeconds(300), () => {
if (items.Z_way_number_WallPlug10_actualpower.numericState < 14){
console.log("Switch TV automated off", "off");
items.getItem("Z_way_switch_WallPlug10").sendCommand("OFF");
console.log("Switch TV automated off", items.Z_way_switch_WallPlug10.state);
}
});
}
},
tags: ["Automation", "TV"],
id: "Switch TV automated off"
});
But the rule gets triggered everytime the power value is changed…How can I simply reset the timer and not creating a new timer everytime?
This is the way how I do it in another DSL rule
var Timer MovementTimer = null
rule “BI Motion FC”
when
Item BI_FC_Motion changed from OFF to ON
then
....
if (MovementLightsOn == true) {
MovementTimer?.cancel
MovementTimer = createTimer(now.plusSeconds(20), [| LS_FrontOutside.sendCommand(OFF)])
...
}
end
But there is no cancel function in the js automation documentations…or at least I haven’t seen it
The return value is an openhab Timer object, so you can call cancel on it.
FYI jruby makes this easier using reentrant timer (timer with an ID automatically resets / reschedules when re-entered)
# This is a file-based JRuby rule. It can be implemented as a UI rule too
rule "Switch TV automated off" do
description "Switch TV automated off"
tags "Automation", "TV"
# triggers:
changed switch_tvlivingroom_debouncedpresence
changed Z_way_number_WallPlug10_actualpower
# condition:
only_if { Z_way_number_WallPlug10_actualpower.state < 14 }
# execution:
run do
logger.info "Switch TV automated off, (re)start timer"
after 5.minutes, id: Z_way_number_WallPlug10_actualpower do
next unless Z_way_number_WallPlug10_actualpower.state < 14
logger.info "Switch TV automated off, switching off"
Z_way_switch_WallPlug10.off
end
end
end
Note: JRuby’s after method returns an openhab Timer object too, but there’s no need to do anything special with it because the reset is already handled for you when id is specified. For more info see after
var tvautomatedofftimer = null;
rules.JSRule({
name: "Switch TV automated off",
description: "Switch TV automated off",
triggers: [triggers.ItemStateChangeTrigger("switch_tvlivingroom_debouncedpresence"), triggers.ItemStateChangeTrigger("Z_way_number_WallPlug10_actualpower")],
execute: (event) => {
if (items.switch_automation.state.toString() == "ON") {
if (items.Z_way_number_WallPlug10_actualpower.numericState < 14) {
console.log("Switch TV automated off, start timer");
tvautomatedofftimer.cancel();
tvautomatedofftimer = actions.ScriptExecution.createTimer(time.toZDT().plusSeconds(300), () => {
if (items.Z_way_number_WallPlug10_actualpower.numericState < 14){
console.log("Switch TV automated off", "off");
items.getItem("Z_way_switch_WallPlug10").sendCommand("OFF");
console.log("Switch TV automated off", items.Z_way_switch_WallPlug10.state);
}
});
}
} else {
console.log("Switch TV automated off", "Master automation switch is off");
}
},
tags: ["Automation", "TV"],
id: "Switch TV automated off"
});
I also tried this version
var tvautomatedofftimer = null;
rules.JSRule({
name: "Switch TV automated off",
description: "Switch TV automated off",
triggers: [triggers.ItemStateChangeTrigger("switch_tvlivingroom_debouncedpresence"), triggers.ItemStateChangeTrigger("Z_way_number_WallPlug10_actualpower")],
execute: (event) => {
if (items.switch_automation.state.toString() == "ON") {
if (items.Z_way_number_WallPlug10_actualpower.numericState < 14) {
console.log("Switch TV automated off, start timer");
tvautomatedofftimer.cancel();
actions.ScriptExecution.createTimer('tvautomatedofftimer', time.toZDT().plusSeconds(300), () => {
if (items.Z_way_number_WallPlug10_actualpower.numericState < 14){
console.log("Switch TV automated off", "off");
items.getItem("Z_way_switch_WallPlug10").sendCommand("OFF");
console.log("Switch TV automated off", items.Z_way_switch_WallPlug10.state);
}
});
}
} else {
console.log("Switch TV automated off", "Master automation switch is off");
}
},
tags: ["Automation", "TV"],
id: "Switch TV automated off"
});
Failed to execute action: 1(Error: Failed to execute rule Switch TV automated off: TypeError: null has no such function "cancel": TypeError: null has no such function "cancel"
Are you asking where the cancel method is documented, or why you need to check for null prior to using the cancel method? Below has the timer documentation which does show a check for null as an example (in DSL, but the same concept applies to JS). Other useful methods are also documented there.
ScriptExecution.createTimer is an openhab core’s method that returns an openhab core Timer object. It doesn’t matter whether it’s called from jsscripting, jruby, rulesdsl, it will return the same core timer object.