Inconsistent percentage behaviour

Hi all,

I have several items that represent a percentage value. I have played around and realized that the values are randomly off by a factor of 100. The special thing is: If I do not change the code but just reboot, it might be correct value or just off by factor 100. It stays than stable for at least several hours / days.

Item definition

Number:Dimensionless        Hausstrom_Autarkiegrad                       "Haus Autarkiegrad [%,.0f %%]"                                (gBalkonkraftwerk)    ["Status","None"]           {unit="%", stateDescription=""[pattern="%,.2f %%"]}

Single rule that calculates the value

    Hausstrom_Autarkiegrad.postUpdate(((Balkonkraftwerk_ACPower.state  as QuantityType<Power>) / ((Balkonkraftwerk_ACPower.state as QuantityType<Power>) + (Stromzaehler_Wirkleistung.state as QuantityType<Power>))) * 100.0)

The unsatisfying thing is not to check by factor 100 once - it is a non reliable bevaiour!

Anything wrong on my usage or is this a bug?

Thanks

Afaik forcing PercentType should solve the problem.

Thanks for the idea. Not sure how to integrate this into the item definition!?

Use it in postUpdate:

Hausstrom_Autarkiegrad.postUpdate(((Balkonkraftwerk_ACPower.state  as QuantityType<Power>) / ((Balkonkraftwerk_ACPower.state as QuantityType<Power>) + (Stromzaehler_Wirkleistung.state as QuantityType<Power>))) as PercentType)

Does not work:

Cannot cast from QuantityType<?> to PercentType
Script execution of rule with UID 'balkonkraftwerk-1' failed: Could not cast 1.5598103574033552151714077315827865956 to org.openhab.core.library.types.PercentType; line 25, column 39, length 192 in balkonkraftwerk

Ok, maybe it’s better to split it (for readability)…

val bkw    =   Balkonkraftwerk_ACPower.state as QuantityType<Power>
val zwl    = Stromzaehler_Wirkleistung.state as QuantityType<Power>
val result = (bkw / (bkw + zwl)).floatValue

Hausstrom_Autarkiegrad.postUpdate(result * 100)
// or 
Hausstrom_Autarkiegrad.postUpdate(result as PercentType)

Does the result of the calculation match the state of the Item? You’ll need to log out the result of the calculation first.

Is the Item’s actual state off by a factor of 100 (i.e. the value you see on the Settings → Items page or in events.log) or is it just the display state?

Does the calculation result in a QuantityType<Dimensionless> or does it carry some other unit or no unit at all? Again, logging out the result of the calculation can reveal that.

Sorry to jump in. I’m also struggling with this at times.
Would you know how to output the data type of a non-strictly defined variable or calculation result (other than if there’s an error message like here) ?

I think if you just toString the result it will log out with the unit. But it occurs to me that ONE is the most likely unit that would result from this calculation and that one doesn’t have a displayed unit.

Hmmm.

QuantityType does have a getDimension() method. That should tell us something.

To copy from @Udo_Hartmann’s example:

val bkw    =   Balkonkraftwerk_ACPower.state as QuantityType<Power>
val zwl    = Stromzaehler_Wirkleistung.state as QuantityType<Power>
val result = (bkw / (bkw + zwl)) // I want to preserve the QuantityType for logging

logInfo('Test', 'Result of calculation is: ' + result)
loginfo('Test', 'Unit is: ' + result.getUnit()) // I would actually expect this to show `ONE`
logInfo('Test', 'Dimension is: ' + result.getDimension())

Hausstrom_Autarkiegrad.postUpdate(result.toUint('%'))

Note: Hausstrom_Autarkiegrad.postUpdate(result as PercentType) is unlikely to work. Neither a primitive float nor a QuantityType is a PercentType. You cannot change them to become a PercentType through casting like this. PercentType is a distinct Class that float and QuantityType do not inherit from.

But if we stay inside QuantityTypes we can ask for the unit we want.

1 Like

Hi all,

sorry for the delay.
Log Output:

2024-04-02 10:25:59.495 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Hausstrom_Autarkiegrad' changed from 7150.7991660875605 % to 7164.591977869986 %

Item definition as in my initial post unchanged.

More details:

Currently no working solution!?

Thanks all!

Do you still have the *100 in your rule? You shouldn’t have that as the unit conversion should take care of it.

Did you try the full rule @rlkoshak provided? That would be logging out the details (result, unit, dimension) and tell you exactly where it goes wrong.

Removing the *100 might solve it temporarly - I added it as openhab just went wrong after reboot by factor 100 => not deterministic, not reliable.

The rule does not work fully:

2024-04-02 10:58:14.083 [INFO ] [org.openhab.core.model.script.Test  ] - Result of calculation is: 0.9999999999999999999999999999999999990
2024-04-02 10:58:14.085 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'test-1' failed: The name 'loginfo' cannot be resolved to an item or type; line 16, column 5, length 47 in test

Line 16 is:

    loginfo('Test', 'Unit is: ' + result.getUnit()) // I would actually expect this to show `ONE`

If I skip this, than I get:

2024-04-02 10:59:48.731 [INFO ] [org.openhab.core.model.script.Test  ] - Result of calculation is: 0.42498450092994420334779913205207686104
2024-04-02 10:59:48.732 [INFO ] [org.openhab.core.model.script.Test  ] - Dimension is: one
2024-04-02 10:59:48.733 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'test-1' failed: 'toUint' is not a member of 'org.openhab.core.library.types.QuantityType<? extends java.lang.Object>'; line 19, column 39, length 18 in test

Line 19:

    Hausstrom_Autarkiegrad.postUpdate(result.toUint('%'))

That should be logInfo (capital I).

Try adding that and see if you get a unit logged. I suspect you will not.

Most likely reason it may go wrong after reboot: restoring from persistence with the wrong unit. That happens if you change the unit, because all stored values will be assumed to be in the current configured unit.

Hi,

obvious but I have not realized:

2024-04-02 12:11:25.330 [INFO ] [org.openhab.core.model.script.Test  ] - Result of calculation is: 0.71510572743004262862448824547334660965
2024-04-02 12:11:25.332 [INFO ] [org.openhab.core.model.script.Test  ] - Unit is: one
2024-04-02 12:11:25.334 [INFO ] [org.openhab.core.model.script.Test  ] - Dimension is: one
2024-04-02 12:11:25.336 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'test-1' failed: 'toUint' is not a member of 'org.openhab.core.library.types.QuantityType<? extends java.lang.Object>'; line 19, column 39, length 18 in test

And in the last line, it needs to be result.toUnit... instead of result.toUint....

You actually don’t need the conversion in that last line, because you can just postUpdate the quantity value from the calculation as is. Because you set the unit to be % in your item definition, it will persist as %. Because of the stateDescription string it should show as % as well. You can save in any compatible unit.

Works:

2024-04-02 14:07:37.927 [INFO ] [org.openhab.core.model.script.Test  ] - Result of calculation is: 0.21371544896466172588186647157988482453
2024-04-02 14:07:37.929 [INFO ] [org.openhab.core.model.script.Test  ] - Unit is: one
2024-04-02 14:07:37.930 [INFO ] [org.openhab.core.model.script.Test  ] - Dimension is: one

Also this line works:

    Hausstrom_Autarkiegrad.postUpdate(((Balkonkraftwerk_ACPower.state  as QuantityType<Power>) / ((Balkonkraftwerk_ACPower.state as QuantityType<Power>) + (Stromzaehler_Wirkleistung.state as QuantityType<Power>))).toUnit('%'))

I just don’t know how long / reliable this is.

This should always work. The issue often stems from persisting in the wrong unit, or mixing pure Number and QuantityType.

And back to my suggestion:

Hausstrom_Autarkiegrad.postUpdate((Balkonkraftwerk_ACPower.state  as QuantityType<Power>) / ((Balkonkraftwerk_ACPower.state as QuantityType<Power>) + (Stromzaehler_Wirkleistung.state as QuantityType<Power>)))

should give exactly the same result. You do not need to explicitly convert to the % unit as long as you have the state description pattern set to show % in your item definition.

We are going in a loop… ;-).

stateDescription has NOT been changed but openhab changed by factor 100! This is my initial request: Not deterministic behavior.

Any changes I have overseen in the last few openhab updates?

I don’t think this is a valid state description, using both , and . It should only be .
Haus Autarkiegrad [%.0f %%]