I’m having some issues with my timer rule, hope someone can help me out.
import org.openhab.model.script.actions.Timer
rule "Nilan Humidity OFF Forseret"
when
Item Nilan_Input_RH changed
then
delayTimer = Timer.createTimer(now.plusSeconds(30))
{
sendCommand(Nilan_Control_VentSet,2)
sendCommand(Smarthouse_Motorventil, OFF)
delayTimer = null
}
end
I’m getting this error, and have been trying to search for what this means
14:20:47.551 [ERROR] [untime.internal.engine.RuleEngineImpl] - Rule 'Nilan Humidity OFF Forseret': 'createTimer' is not a member of 'java.lang.Class'; line 70, column 16, length 38
14:20:47.551 [ERROR] [untime.internal.engine.RuleEngineImpl] - Rule 'Nilan Humidity ON Forseret': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.lib.NumberExtensions.operator_plus(java.lang.Number,java.lang.Number) on instance: null
15:03:08.240 [ERROR] [untime.internal.engine.RuleEngineImpl] - Rule 'Nilan Humidity OFF Forseret': 'createTimer' is not a member of 'java.lang.Class'; line 72, column 16, length 176
Yes you are right I have, but I can’t see that createTimer is defined before.
import java.util.Random
val String logNamePresence = "presence"
var Timer presenceTimer = null
var Timer timer = null
val resList = newArrayList("640/480", "320/240", "480/360")
val urlList = newArrayList("http://www.fillmurray.com", "http://www.fillmurray.com/g",
"http://www.placecage.com", "http://www.placecage.com/c", "http://www.placecage.com/g")
val Random random = new Random()
var Timer delayTimer = null
rule "Humidity Average Nilan Inlet "
when
Item Nilan_Input_RH received update
then
Nilan_Input_RH_Avrg.postUpdate(Nilan_Input_RH.averageSince(now.minusHours(0.5)))
end
rule "Nilan Udluftning Max Speed Kl 06.00 & 18.00 hver Dag"
when
Time cron "0 00 06 * * ?"
or
Time cron "0 00 18 * * ?"
then
sendCommand(Nilan_Control_VentSet, 4)
end
rule "Nilan Udluftning Normal Speed Kl 07.30 & 20.00 hver Dag"
when
Time cron "0 30 07 * * ?"
or
Time cron "0 00 20 * * ?"
then
sendCommand(Nilan_Control_VentSet, 2)
end
rule "Nilan Humidity ON Forseret"
when
Item Nilan_Input_RH changed
then
var Number Humidity=(Nilan_Input_RH_Avrg.state)
Humidity=Humidity+0.1
Nilan_Input_RH_Trig.postUpdate (Humidity)
if(Nilan_Input_RH.state >= Nilan_Input_RH_Trig.state){
sendCommand(Nilan_Control_VentSet,4)
sendCommand(Smarthouse_Motorventil, ON)
}
end
rule "Nilan Humidity OFF Forseret"
when
Item Nilan_Input_RH changed
then
if(delayTimer == null) {
delayTimer = Timer.createTimer(now.plusSeconds(30), [|
Nilan_Control_VentSet.sendCommand(2)
Smarthouse_Motorventil.sendCommand(OFF)
delayTimer = null
])
}
else {
delayTimer.reschedule(now.plusSeconds(timeoutMinutes))
}
end
import org.openhab.model.script.actions.Timer //this import is only needed in openHAB1
var Timer delayTimer = null
val int timeoutMinutes = 30 //timeoutMinutes wasn't defined yet!
rule "Nilan Humidity OFF Forseret"
when
Item Nilan_Input_RH changed
then
if(delayTimer == null) {
delayTimer = createTimer(now.plusSeconds(30), [|
Nilan_Control_VentSet.sendCommand(2)
Smarthouse_Motorventil.sendCommand(OFF)
delayTimer = null
])
}
else {
delayTimer.reschedule(now.plusSeconds(timeoutMinutes))
}
end
should also work. In fact, it’s way better to use the methods [Item.sendCommand(value)] instead of actions [sendCommand(item,value)] (see sendCommand() Documentation and http://docs.openhab.org/configuration/rules-dsl.html#sendcommand-method-vs-action)
It’s always a good Idea to check if the timer is initialized.
I don’t understand the difference between createTimer(int) [| ] and createTimer(int,[| ]) but in the end both are ok.
The error in first place was the Timer. before createTimer, this is not allowed in the rules DSL.
When a method call’s last parameter is a lambda it can be passed right after the parameter list. For instance if you want to sort some strings by their length, you could write :
Collections.sort(someStrings) [ a, b |
a.length - b.length
]
which is just the same as writing
Collections.sort(someStrings, [ a, b |
a.length - b.length
])
Since you can leave out empty parentheses for methods which get a lambda as their only argument, you can reduce the code above further down to:
So ultimately both versions are the same. It is just a little bit of what is often called “syntactic sugar.” I personally prefer passing the lambda inside the parens as an argument rather than after because it makes it more explicit that the lambda is an argument to the function and nothing magic is going on.
Would there be a way to have a countdown timer shown on my site map?
In the below rule, I want to have the delayTimer remaining time shown - someone who can help me ?
rule "Nilan Humidity OFF Forseret"
when
Item Nilan_Control_VentSet changed from 2 to 4
then
delayTimer = createTimer(now.plusMinutes(20)) [|
sendCommand(Nilan_Control_VentSet, 2)
sendCommand(Smarthouse_Motorventil, OFF)
delayTimer = null
]
end
It’s not easy but others have posted examples on the forum.
The trick of it is you need to have a timer that only sleeps for a second, updates a Number Item with the total amount of time remaining, then gets recreated to sleep for another second.