UOM strings and Rules

I’m running openHAB 2.4.0 Release Build, and am having trouble with a rule to concatenate a few sensor values.

The issue is that I’m using the built-in Units of Measure to convert from mph to km/h… in the process, the value gets precision to about 20+ decimal points, despite the item declaration being only one. If I ditch the “:Speed” from the item declaration, it works… but in mph and doesn’t convert despite having “km/h” inside the brackets.

I’d really like to have this:
5.47177397741568 km/h SSE w/ 7.885785599999999565937 km/h gusts
read:
5.4 km/h SSE w/ 7.8 km/h gusts

Here’s my item declaration:

Number:Speed AWWindSpeed "Wind Speed [%.1f km/h]" {channel="ambientweather:ws1400ip:AmbientWS1002:weatherDataWs1400ip#windSpeed"}

Here’s my rule:

rule "update WindReading"
when
    Time cron "0 * * ? * *"
then
    WindReading.postUpdate(AWWindSpeed.state.toString + " " + AWWindDir.state.toString + " w/ " + AWWindGust.state.toString + " gusts" )
end

Any thoughts as to what I might be doing wrong?

The [%.1f] part in your Item label only affects how it is displayed, not the actual content in the Item state.
So item.state 5.47177397741568 will appear in the UI as 5.5
But .toString ignores that format and gives you the whole show.

This is then complicated by the Speed dimension.
As I understand it, now the [km/h] part gets taken into account outside of display only.
I believe - but not entirely convinced on this - that the weather binding can see that and will convert incoming mph data to km/h as it updates the Item.
You want that to happen, so you need to keep both :Speed type and [.. km/h] parts.
But doing .toString on an Item state does add on the units from the .

So, to extract and format the number in a rule is a bit of a marathon

   // this should get the numeric value without unit in default km/h
val Number interwind = (AWWindSpeed.state as Number).decimalValue
   // now we can format
WindReading.postUpdate(String::format( "Windspeed: %1s km/h Direction %s",
          interwind, AWWindDir.state.toString ))

I think this will come in km/h as per your Item default.

Thanks – I think I’m going to be able to work with this, though for reference, it’s logging this error (and not working quite right):

[ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'update WindReading': 'decimalValue' is not a member of 'java.lang.Number'; line 13, column 28, length 42

The String::format should be enough to get me where I need to be, though – thanks!

alright - got it all fixed up…

  1. instead of “.decimalValue”, “.floatValue” works
  2. using “%.1f” instead of “%1s” leads to the formatting I was hoping for in the output

Thanks again!

Here’s my code:

rule "update WindReading"
when
    Time cron "0 * * ? * *"
then
    val Number interwind = (AWWindSpeed.state as Number).floatValue
    val Number intergust = (AWWindGust.state as Number).floatValue
    WindReading.postUpdate(String::format("%.1f km/h %s w/ %.1f km/h gusts", interwind, AWWindDir.state.toString, intergust ))
end

1 Like

I suppose it’s complaining about fitting the decimalValue into a Number. I thought I’d tried that out, but I guess letting it default should work.
val interwind =