You were missing {} for the else conditions
The conversion should be solved by adding .doubleValue
Try that:
rule "Windchill_Calculate"
when
Item OWM_Current_Temperature received update
then
if(!(OWM_Current_Windspeed.state instanceof Number)) {
logWarn("windchill","Windspeed not of Type Number!")
return;
} else {
val speed = Math.pow(((OWM_Current_Windspeed.state as Number).doubleValue * 3.6), 0.16)
}
if(!(OWM_Current_Temperature.state instanceof Number)) {
logWarn("windchill","Temperature not of Type Number!")
return;
} else {
val temp = OWM_Current_Temperature.state as Number
}
logInfo("windchill","Temp: {} Speed: {}",temp,speed)
OWM_Current_Windchill.postUpdate(13.12 + 0.6215 * temp - 11.37 * speed + 0.3965 * temp * speed )
end
Ok, now I’m getting a whole bunch of messages that field temp and field speed are not defined.
The method or field temp is undefined
The method or field speed is undefined
The method or field temp is undefined
The method or field speed is undefined
The method or field temp is undefined
The method or field speed is undefined
error 1 refers to the variable temp in the logInfo line
error 1 refers to the variable speed in the logInfo line
errors 3,4,5,6 refer to varaiables speed and temp in the last line before end
I’ll paste below the messages from the log:
2019-01-13 18:07:34.842 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'default.rules', using it anyway:
The value of the local variable speed is not used
The value of the local variable temp is not used
2019-01-13 18:07:34.868 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'default.rules'
2019-01-13 18:08:14.101 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'default.rules', using it anyway:
The value of the local variable speed is not used
The value of the local variable temp is not used
2019-01-13 18:08:14.207 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'default.rules'
==> /var/log/openhab2/events.log <==
2019-01-13 18:08:43.575 [vent.ItemStateChangedEvent] - Cell_Mobile_Online changed from OFF to ON
==> /var/log/openhab2/openhab.log <==
2019-01-13 18:12:32.539 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Windchill_Calculate': The name 'temp' cannot be resolved to an item or type; line 25, column 46, length 4
2019-01-13 18:17:39.061 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'default.rules', using it anyway:
The value of the local variable speed is not used
The value of the local variable temp is not used
I’m wondering about the semicolons after the return statements. Why are they not required at the end of all lines…?
I think Udo is right about not needing the curly brackets after the else. It’s only a single statement and generally (at least in C for instance) they’re only required if the block consists of more than one statement. I’ve combined both suggestions. I lost the curly brackets but added the doubleValue:
rule "Windchill_Calculate"
when
Item OWM_Current_Temperature received update
then
if(!(OWM_Current_Windspeed.state instanceof Number)) {
logWarn("windchill","Windspeed not of Type Number!")
return;
}
else
val speed = Math.pow(((OWM_Current_Windspeed.state as Number).doubleValue * 3.6), 0.16)
if(!(OWM_Current_Temperature.state instanceof Number)) {
logWarn("windchill","Temperature not of Type Number!")
return;
}
else
val temp = OWM_Current_Temperature.state as Number
logInfo("windchill","Temp: {} Speed: {}",temp,speed)
OWM_Current_Windchill.postUpdate(13.12 + 0.6215 * temp - 11.37 * speed + 0.3965 * temp * speed )
end
Now I’m just getting:
no viable alternative at input ‘val’
no viable alternative at input ‘val’
where each message refers to each of the ‘val’ lines.
Hi, as I saw your Post with your Rule, great, and i just want to have it. But i came into trouble with the “else”-Statement too. So at first i tried the curly brackets and the failure was gone. But i also got that “TypeMismatch”.
While tinkering and testing with the rule i found a post of @ThomDietrich about changing an item to a floating value, as changing it to a Number it still has the measurement sign (UOM) in it.
I changed the Rule a bit and this works. But at the very end i still have the problems with the rule-values “temp” and “speed”.
While thinking a bit (…drinking a tea - Hopfen-Tee ) i found the solution for me: I don’t need this else-Statement at all.
So here is my adaption of your rule, and it works:
rule "Windchill_Calculate" // thx to @Udo_Hartmann for this Rule
when
Item Dummy3 received command ON or
Item localCurrentTemperature received update
then
//var speed = 0
//var temp = 0
if(!(localCurrentWindSpeed.state instanceof Number)) {
logWarn("windchill","Windspeed not of Type Number!")
return;
}
var speed = Math.pow((((localCurrentWindSpeed.state as Number).floatValue) * 3.6), 0.16)
logInfo("windchill","Speed: " + speed)
if(!(localCurrentTemperature.state instanceof Number)) {
logWarn("windchill","Temperature not of Type Number!")
return;
}
var temp = (localCurrentTemperature.state as Number).floatValue
logInfo("windchill","Temp: " + temp)
logInfo("windchill","Temp: {} Speed: {}",temp,speed)
owm_localCurrentWindchill.postUpdate(13.12 + 0.6215 * temp - 11.37 * speed + 0.3965 * temp * speed )
end
I changed the Item-names as i use them.
Although i do not know exactly what the if’s and calculations do exactly, i have to say good job.
(the only thing i understand a bit, is: point before line, but this was 50 years ago)
I did an update to OH2.5.0 #1499 and got very strange behavior.
But at least I can confirm the strange misbehavior about constant values.
So one thing is to use var instead of val (variable vs. ‘fixed’ value)
The other thing is the doubleValue when using Math.pow openHAB should do a type casting itself, as Number has the .doubleValue method.
My last version (with reduced logging) is:
rule "Windchill Calculate"
when
Item OWM_Current_Temperature received update
then
if(!(OWM_Current_Temperature.state instanceof Number)) {
logWarn("windchill","Temperature not of Type Number!")
return;
}
var Number temp = OWM_Current_Temperature.state as Number
if(!(OWM_Current_Windspeed.state instanceof Number)) {
logWarn("windchill","Windspeed not of Type Number!")
return;
}
var Number speed = Math.pow((OWM_Current_Windspeed.state as Number).doubleValue * 3.6, 0.16)
var Number chill = 13.12 + 0.6215 * temp - 11.37 * speed + 0.3965 * temp * speed
logInfo("windchill","Temp: {} Speed: {} Chill: {}",temp,OWM_Current_Windspeed.state,chill)
OWM_Current_Windchill.postUpdate(chill)
end
I’m 99% positive that even when you leave out the curly brackets for a single line else statement it still creates a separate context for the else. In other words:
else
some statement
is exactly equivalent to
else {
some statement
}
Why is this important? Because you are defining val speed and val temp inside the else clause’s context. Thus neither variable exists when you get down to the postUpdate.
So that’s the point, I had to define the var on top context. Of course, as I omitted the if in the last version, this is no problem anymore… I was totally unaware of that fact. No wonder it didn’t work…