I’d first question if your rule retrieves from MySQL at all. Humidity.historicState(now)
will retrieve from whatever you have set as your system default persistence service.
In OH3, that will be rrd4j unless you have changed it.
You can be explicit in your rule - are you using via JDBC? Humidity.historicState(now, "jdbc")
Next thing to consider is Item type. Is this a Number type? Or perhapsa Number:Dimensionless? Has it been changed from one to the other in the past, perhaps?
You can get some really nasty effects involving Number:Dimensionless types (usually expressed with a percent unit “%”) if it involves numbers without a unit - these get an invisible unit “ONE” and are treated as ratios.
Just as the quantity “50 %” is not equal to numeric “50”, neither is the quantity “50 ONE”, even though it formats to “50”.
The item is indeed this, but it is stored in the database as a double. So as we can see on that logInfo, it shows exactly the number 85.
If I only output directly the item state (OutsideHumidity.state) it actually shows the % in front of the number, just as we see it in the item. But that is why I am grabbing the number that I have in my persistance.
The fact that it’s stored in the database as a double is irrelevant. All numbers are stored as a double.
Persistence does not yet support units of measurement. So what’s going on is exactly what @rossko57 described. The value is restored. There’s no unit provided so the default unit is chosen. The default unit for Number:Dimensionless is ratio which is the one unit that doesn’t actually have a visible unit. Exactly 85 in this context is exactly 85 ONE. OH doesn’t show the units for a ratio but that doesn’t mean it’s not there.
The flow is like this.
The database is queried and it returns 85
OH get’s that number and sees that the Item is a Number:Dimensionless meaning it’s a QuantityType. So it goes down that path instead of the path for plain old Numbers
OH looks at the State Description metadata to see if you have configured the desired units to use. You haven’t.
OH uses the default units based in the category (in this case Dimensionless) and your configured locale. In this case that’s ONE which doesn’t actually have a representation.
Unfortunately, OH does not have the ability to do math with QuantityTypes and non-QuantityTypes. Both operands need to be one or the other.
Humidity.historicState(now).state is a QuantityType. 90 is just a plain old number. So you either need to convert the QuantityType to a plain old number:
Or you need to convert the 90 to a QuantityType. I’m not actually sure how to do that for a ratio, maybe something like one of the following:
new QuantityType(90, '')
new QuantityType(90, 'ONE')
One of those four options ought to work.
But wait, this is a Humidity Item. It’s not a ratio, it’s a percentage. So let’s make it behave like one.
Make sure you’ve defined State Description on this Item and set the units to %.0f %%. Theoretically that should make OH use percentage instead of ratio as the units (see step 3 above).
Convert the 90 to a percentage QuantityType using 90|%.
If that doesn’t work, we may need to force it in the rule.
Yes, it is finally working and I didn’t knew, at all, these differences. I always assumed the number came straight from MySQL “as is” and not being transformed “in the background” by OH. This was very educative and it actually made light on other things that were happening on other rules.
So, in case others want to see the final result, I ended up placing this before the rule:
val Number humidity = (OutsideHumidity.historicState(now).sate as QuantityType).toUnit('%')
Then I just had to do this immediately in the start of the rule:
Just to be clear though. It’s not being transformed, per se.
historicState.state returns an org.openhab.core.types.State Object just like MyItem.state does. There are all sorts of different State types: QuantityType, OnOffType, PercentType, DateTimeType, etc.
The type of the state depends on the type of the Item. A Number:Dimensionless carries a QuantityType and no other (ignoring UnDefType which you’d never get back from persistence anyway). So when you want to get the state of an Item at some point in the past for a Number:Dimensionless, the only thing that makes sense is to get a QuantityType.
Note, I strongly recommend setting the State Description for this Item so that it’s treated as a percentage by everything in openHAB rather than keeping it as a ratio. If you already have, this might be a limitation with persistence right now and it’s worth taking note of this behavior.
By the way, have you noticed that instead of “state” I wrote “sate” by mistake? I mean, how can this be working if I got it wrong? Does it asume “0” in case there is no valid information?
Also, I’ve tried what you suggested, which actually makes total sense but I am just being very noob here. I’ve tried different combinations and I am not being able to make it work. Am I placing it in the right place here?
When units were first introduced, we had to put them as “strings” just as you show. blah > 50|"ºC"
That still works.
Since then, a DSL enhancement allows ‘naked’ units after the pipe. blah > 50|ºC
but beware - some units include characters that will upset the rules parser, the obvious one being / which the parser wants to use a maths operator. bleh > 50|km/h error, parser wants to divide 50km by variable h bleh > 50|"km/h" okay
Other rules languages have their own methods and limitations (the pipe | designator is unique to DSL)