The rule would help
Also you need to use the UoM:
Number:Temperature OWM_Current_Temperature "Current Temperature [%.1f °C]" <temperature> (Weather) { channel="openweathermap:weather-and-forecast:86b42b76:local:current#temperature" }
Number:Speed OWM_Current_Windspeed "Current Wind Speed [%.1f m/s]" <wind> (Weather) { channel="openweathermap:weather-and-forecast:86b42b76:local:current#wind-speed" }
Thanks. Please see my very first post at the top for the entire rule. Also I updated my items to include the UOM. Nothing changed after that update. Still getting the same errors.
BTW, my reasoning for not including the UOM in the item definitions was that including the UOM would make the item a ‘quantity’ object instead of a decimal (due to the presence of the unit). Maybe that doesn’t matter. I actually had the UOM there before but removed it as part of my troubleshooting.
If you would please edit the rule and use code fences, this makes it easier to read and understand. Its the paper icon beside the smile face.
Thanks
Done. Please see the first post which has been updated.
That’s a lot of math in a postUpdate. I wish I could easily solve this like @vzorglub, @rlkoshak, @Udo_Hartmann and several other’s but I know when I’m in over my head. This will be a good topic for me to follow and learn how to deal with lot’s of math.
Please consider to do some val setting plus logging:
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) * 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 Udo. I’ve substitued your rule in place of mine. The variables speed and temp make the equation a bit simpler. Here’s what I’m getting now in VS Code:
- no viable alternative at input ‘val’
- Type mismatch: cannot convert from BigDecimal to double
- no viable alternative at input ‘val’
Message 1 refers to the following line (error col referred to is the very start of the line pointing to the v in val):
val speed = Math.pow(((OWM_Current_Windspeed.state as Number) * 3.6), 0.16)
Message 2 refers to the same line as above but to the second open bracket after Math.pow
Message 3 refers to following line (error col referred to is the very start of the line pointing to the v in val):
val temp = OWM_Current_Temperature.state as Number
There are no warnings in the log about temperature or windspeed not of type number.
As soon as I saved the rule I got the following output in the log (17,9 and 29,9 both point to the beginning of each of your ‘val’ lines:
2019-01-13 17:46:20.985 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'default.rules' has errors, therefore ignoring it: [17,9]: no viable alternative at input 'val'
[23,9]: no viable alternative at input 'val'
Let me know if there is anything other info you’d like…
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
Well, you shouldn’t need the curly brackets, as this is only one command.
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.
Also I’m not seeing anything in my log now…
Also my windchill value is still appearing as
- °C in my sitemap
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)
thx again.
Cheers - Peter
Thanks Peter. I’ll give it a try.
Thanks again Peter and to everyone who helped. I can confirm that this now works. I will mark it as solved.
There’s something fishy going on…
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…
True. And fun fact, that’s exactly why it makes sense that else if()
works the way it does:
if (a == ON){
// do something
// do something more
} else {
if (a == OFF){
// do something alternative
} else {
// do something else
}
}
So you can see that the second if - else
structure is one inseparable block, so you can remove the curly braces for the else statement, resulting in:
if (a == ON){
// do something
// do something more
} else if (a == OFF){
// do something alternative
} else {
// do something else
}