I am trying to control a Bionaire Fan with Openhab. To change the speed, I’m using this rule, which basically calculates how many times to send the IR code to get to the correct speed.
rule "Bionaire Speed"
when
Item BionaireSpeed changed
then
val prevstate=(BionaireSpeed.previousState.state as DecimalType)
val currentstate=(BionaireSpeed.state as DecimalType)
val reqclicks=currentstate-prevstate
if (reqclicks < 0)
{
reqclicks=6+reqclicks
}
val i=1
var boolean flag = true
while(flag)
{
Bionaire_TransmitCommand.sendCommand("Speed")
Thread::sleep(1000)
if (i=>reqclicks)
{
flag=false
}
end
It sends the code once, and then the log shows this:
19:03:26.085 [ERROR] [untime.internal.engine.RuleEngineImpl] - Rule 'Bionaire Speed': An error occurred during the script execution: Could not invoke method: org.eclipse.xtext.xbase.lib.ObjectExtensions.operator_doubleArrow(T,org.eclipse.xtext.xbase.lib.Procedures$Procedure1) on instance: null
Any ideas on how to do this properly, without the weird flag thing?
I tried using the tutorial here. Which doesn’t work, presumably because I have casted the wrong type.
There is a “}” missing at the end. I reformat it, then it is clear.
rule "Bionaire Speed"
when
Item BionaireSpeed changed
then
val prevstate=(BionaireSpeed.previousState.state as DecimalType)
val currentstate=(BionaireSpeed.state as DecimalType)
val reqclicks=currentstate-prevstate
if (reqclicks < 0)
{
reqclicks=6+reqclicks
}
val i=1
var boolean flag = true
while(flag)
{
Bionaire_TransmitCommand.sendCommand("Speed")
Thread::sleep(1000)
if (i=>reqclicks)
{
flag=false
}
} <==this one is missing!
end
Another hint. Maybe break; can end the while without the need of the flag check.
Yeah, i had fixed the } after i posted; sorry. Also, this wasn’t the first try. I also used the openhab tutorial here, but it didn’t work for my variable, only when i put a number.
Also, you might want to try previousState(true). And be aware of this issue. I’m also not sure how the DSL reacts to the primitve boolean… you may want to use Boolean instead.
But if the rule was working, would it be retriggering itself? Does BionaireSpeed change after sending this?
If you don’t increment the i in the loop, you will never get out of it!!
while(flag) {
Bionaire_TransmitCommand.sendCommand("Speed")
Thread::sleep(1000)
if (i=>reqclicks) {
flag=false
}
i = i + 1 // <== YOU NEED THIS !!
} // <==this one was missing!
22:20:10.611 [INFO ] [del.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'Climate2.rules', using it anyway:
Assignment to final variable
To all: Is there another way than using the flag variable to exit the loop?
I.e. using a while loop like this (this doesn’t work either)
rule "Bionaire Speed"
when
Item BionaireSpeed changed
then
val int prevstate=(BionaireSpeed.previousState.state as DecimalType).$
val int currentstate=(BionaireSpeed.state as DecimalType).intValue
val int reqclicks=currentstate-prevstate
if (reqclicks < 0)
{
reqclicks=6+reqclicks
}
val i=0
while(i<reqclicks)
{
Bionaire_TransmitCommand.sendCommand("Speed")
Thread::sleep(500)
i=i+1
}
end
The log shows this after using this code:
22:25:11.568 [INFO ] [del.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'Climate.rules', using it anyway:
Assignment to final variable
Assignment to final variable
22:25:11.568 [INFO ] [del.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'Climate.rules', using it anyway:
Assignment to final variable
rule "Bionaire Speed"
when
Item BionaireSpeed changed
then
val prevstate = BionaireSpeed.previousState.state as DecimalType
val currentstate = BionaireSpeed.state as DecimalType
var reqclicks = currentstate - prevstate
if (reqclicks < 0) {
reqclicks=6+reqclicks
}
var i = 1
var boolean flag = true
while(flag) {
Bionaire_TransmitCommand.sendCommand("Speed")
Thread::sleep(1000)
if (i >= reqclicks) {
flag=false
}
i = i + 1
}
end
But now that it’s working, is it retriggering itself? Does BionaireSpeed change after sending this…
Bionaire_TransmitCommand.sendCommand(“Speed”)
… which would then trigger the rule again? If you’re not sure, you might want to add some logging. You could have 6 while loops running over themselves.