[SOLVED] Calculating windchill

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.

1 Like

That’s a lot of math in a postUpdate.:stuck_out_tongue_winking_eye: 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.:laughing: This will be a good topic for me to follow and learn how to deal with lot’s of math.:wink:

1 Like

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
1 Like

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:

  1. no viable alternative at input ‘val’
  2. Type mismatch: cannot convert from BigDecimal to double
  3. 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
1 Like

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.

  1. The method or field temp is undefined
  2. The method or field speed is undefined
  3. The method or field temp is undefined
  4. The method or field speed is undefined
  5. The method or field temp is undefined
  6. 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'

==&gt; /var/log/openhab2/events.log &lt;==

2019-01-13 18:08:43.575 [vent.ItemStateChangedEvent] - Cell_Mobile_Online changed from OFF to ON

==&gt; /var/log/openhab2/openhab.log &lt;==

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 :wink:) 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.

Pls. have a look here and the time conversions explained by @rlkoshak
Cheers - Peter

Thanks again Peter and to everyone who helped. I can confirm that this now works. I will mark it as solved.

1 Like

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
1 Like

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.

1 Like

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. :slight_smile: 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
}