Rule stops working after upgrade: QuantityType and HistoricalItem

  • Platform information:
    • Hardware: Raspberrypi
    • OS: PiOs 4.19
    • Java Runtime Environment: OpenJDK 11.0
    • openHAB version: 3.4.1-1

I upgraded Openhab to 3.4.1-1 over the weekend. One of my rules started giving an error, but was previously running successfully and had been running successfully for months (perhaps even years). It runs roughly every minute, so I would have noticed if it had stopped working - it started giving an error on every invocation.

The purpose of this rule is to evaluate if my hot water cylinder has dropped in temperature sufficiently to turn on the hot water boiler. Because it’s a diesel boiler I don’t like it to short cycle (causes it to soot up), so I wait until both the top and bottom of the hot water cylinder have cooled down sufficiently for a decent run time. Typically this means the diesel boiler fires only twice a day in summer (in winter it fires much more frequently to run the heating). With the temperature at the top of the hot water cylinder I tend to get a brief drop in water temperature when I run a tap - cold water comes in and can cause a transient drop. So I look both for the temperature to be below threshold, but also to have stayed below threshold for at least 3 minutes, so that I know it isn’t just a transient drop.

To do this, I use the historicState call to get the temperature 3 minutes ago, and store it in a QuantityType<Temperature>.

The relevant code is:

    var QuantityType<Temperature> oldUpperTemp
    oldUpperTemp = 100|°C
    oldUpperTemp = numberDHWUpperCylinderTemp.historicState(ZonedDateTime.now().minusMinutes(3)).state as QuantityType<Temperature>

As noted, this has been running successfully for months. After the upgrade I started getting a new error:

2023-02-12 10:14:34.078 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'boiler_timers-3' failed: Could not cast 47.3 to org.openhab.core.library.types.QuantityType; line 428, column 22, length 112 in boiler_timers

I can’t ascertain the data type of the HistoricItem that is returned, but it looks to be a Number of some sort. Perhaps a BigDecimal. It could be a string. The underlying item that the history is being stored for is defined as:

Number:Temperature numberDHWUpperCylinderTemp "Current Upper Cylinder Temp [%.1f %unit%]" <temperature> (InternalFlags, RestoreGroup, TempSensors) { channel="mqtt:topic:pi2:heating:DHWUpperTemp" }

This item is listening to an mqtt topic, which in turn is published data from a perl script that reads the pi temperature sensors over the oneWire protocol. Which shouldn’t really matter, because either way it’s a Number type that holds a temperature.

The data is clearly a number, and I can cast it to a Number, but I cannot from there cast it to a QuantityType. It gives an error that BigDecimal cannot be cast to a QuantityType. This seems unusual, as a Number seems to me to be exactly what I should be able to cast to a QuantityType.

I’ve tried a few variations on ways to force the cast, or to calculate it. These include:

  • Converting the historical value toa string, appending °C to that string, then trying to create a QuantityTypefrom that string. I can’t work out the constructor format for a QuantityType though, other than trying to cast the string to a QuantityType, which doesn’t work
    (numberDHWUpperCylinderTemp.historicState(ZonedDateTime.now().minusMinutes(3)).state as String) + “ °C”) as QuantityType<Temperature>
  • Casting to a number, then from the number to the QuantityType. It doesn’t like casting from BigDecimal to QuantityType, so I can’t do that
  • A variety of flavours of adding it to 0|°C, or permutations of maths that all seem to end up with BigDecimal, which won’t cast to a QuantityType.
    ((0|°C) as QuantityType<Temperature> + numberDHWUpperCylinderTemp.historicState(ZonedDateTime.now().minusMinutes(3)).state as Number) as QuantityType<Temperature>

I use QuantityTypes all through the logic for temperature, and this is the only one that appears to be failing, so I presume it’s something to do with it starting as a HistoricItem, but I’m not sure what about it is causing the issue.

Is there any known change in the handling of QuantityTypes in recent versions, or something that was working for me that wasn’t supposed to work, and that therefore I should change in how I’m obtaining data from the rrd history?

Thanks in advance for any assistance.

Problem is, persistence does not store UoM units.

Of course not because it does not know the unit to apply - that’s the core of your issues.

Basically something like

QTItem = new QuantityType<Energy>(xxx + "kWh")

with xxx = <NumberItem>.state.floatValue or <NumberItem>.state.toString or a HistoricItem state.

OK, excellent information. Weird that it was working for so long and stopped with the upgrade, but I guess it was an undocumented feature that wasn’t supposed to work.

oldUpperTemp = new QuantityType<Temperature>((numberDHWUpperCylinderTemp.historicState(ZonedDateTime.now().minusMinutes(3)).state as String) + “ °C”) 

Should work? I’ll try tomorrow.

Slightly different syntax, you can’t cast to a string, you have to use toString. Why, who knows. Seems if there’s a toString method that requires no parameters, then a cast should also have been provided.

oldUpperTemp = new QuantityType<Temperature> ( numberDHWUpperCylinderTemp.historicState(ZonedDateTime.now().minusMinutes(3)).state.toString + " °C")