[SOLVED] Debug Rules: How to find out the cause in rule for "Can not compare incompatible units."

Hi community,
with my migration from 3.4.2 to 4.1.0-RC1 I ran into the problem that two rules have trouble with inconsistent units. I kindly like to ask how I can debug a rule to find out which if loop with an item comparison causes this trouble. I think I found some of it but not all hence I would like to know how to get more details of this error message:

...
15:27:02.528 [ERROR] [.internal.handler.ScriptActionHandler] - Script execution of rule with UID 'Global_Heizung-1' failed: Can not compare incompatible units. in Global_Heizung
...
15:27:02.534 [ERROR] [.internal.handler.ScriptActionHandler] - Script execution of rule with UID 'Global_Heizung-2' failed: Can not compare incompatible units. in Global_Heizung
...

THANK YOU and HAPPY NEW YEAR!!!
Cheers
Justus

Log out the states of these Items when the rule runs and see what the states are when it fails.

The first error comes from the first rule in the file Globasl_Heizung.rules and the second error comes from the second rule in that file.

Thanks Rich!!!

I already found out that my temperature sensors passes unitless values via MQTT hence the item state is always just a number even though I have configured it to be a temperature:

Number:Temperature ESP8266R1temp "Room 1: Temperature [%.1f %unit%]" (gESP) { channel="mqtt:topic:mySecureBroker:room1:temperature" [profile="system:offset", offset=-1.5] }

This is also the reason why I have the offset without unit …

And I compare this value with other temperatures and they have units :thinking:
I can not manipulate the MQTT sending device.

Is there a way to add the unit in openhab (remember that the channel always sends without units)

And this will also affect my persistence as it stored the value as number … but what habppens if I add the unit “manually” to the item? Will it still store a number or will it become a string then?

Ok, it seems that I have an unsolvable conflict in my rules:

  1. I have a temperature number that I can not change back to a dimensionless number
  2. I have a dimensionless number that I cannot transform into a temperature number

And with version 4.1.0 openHAB does not tolerate this anymore and to get my rules back working I need to change the if statement to be working again.

In the longer run I need to clean up my setup to reflect every item correctly but this is not done so quickly as I need to check all dependencies first …

So I need to change my if statement from:

if ( ESP8266R1temp.state > sollEGGRUPPEtemp.state )

where ESP8266R1temp.state is dimensionless
and sollEGGRUPPEtemp is a temperature

need to figure out the right syntax now …

tl;dr: If you have a Number:Temperature that Item’s state is always going to have a unit. In OH 4 the only way to have a state without a unit is if it’s a Number or the state is NULL or UNDEF.

There is a unit property on the MQTT Channel where you can supply the unit.

Since you’ve not defined unit metadata on the Item, what ever unit MQTT supplies ill be converted to that unit if it’s not already (e.g. is °F is published as the state update, that value will be converted to °C when the Item is updated if the default for your locale is SI units).

If there is no unit published in the state update, the system default unit is assumed.

Setting the label in your .items file does nothing to define the unit carried by the Item.

This is irrelevant to any unit related error coming from a rule.

You can configure the MQTT Channel to supply units.

[rant] If you are using .things files and didn’t know this property existed, well that’s why I don’t support people with text based config problems any more. All that time you think you are saving gets lost fighting problems like these because the text files are not self documenting. [/rant]

But even if the Channel doesn’t post update with a unit, your Item is going to have a unit no matter what because it’s a Number:Temperature. Either it’s going to be the system default or it’s going to be what you’ve set the unit metadata to.

A unit is already being added even with your current config. Right now you are depending on the system default. But you can fix it by setting the unit metadata on the Item. You should also set it in the MQTT Channel so that OH doesn’t just assume the unit matches the Item’s unit.

If the unit of the number matches the unit of the Item, nothing will change for persistence. If it’s different you probably would have noticed before now. But that is a problem when working with units in OH 4+. Since the unit is not stored in persistence, if you change the unit of the Item it will not convert the old values already stored in persistence to match the new unit.

Nothing, the unit is not stored in persistence, only the number is. Where you run into trouble is if you were using °F before and change the unit to °C later, all those previous values stored in persistence will be treated as if they were always °C. They don’t get converted.

Why can’t you change it?

Why can’t you change it?

Indeed if they don’t both have units, you need to change the if statement to either add a unit to the one lacking or remove the unit from the one that has units. But better would be the fix the Item to carry units in the first place.

Are you sure you don’t have an Item that’s NULL or UNDEF or something because this would have always been a problem, even as far back as OH 2.5.

Better to set ESP82661temp to carry units. And in fact, based on that line from the .items file, it already is carrying units. Are you sure it’s not NULL?

Back to my original reply,

Log out the states of these Items when the rule runs and see what the states are when it fails.

2 Likes

Please be aware that dimensionless has a specific meaning in Unit context, i.e. percentType.

Some additional points:

That’s not sufficient. You have to set the mqtt channel to send a unit (advanced options - unit)
And in openHAB4 you also have to set a unit as metadata within the Item.
Thing:

Thing topic room1 {
    Channels:
    Type number : temperature [ stateTopic="...", unit="°C" ]
}

Item:

Number:Temperature ESP8266R1temp "Room 1: Temperature [%.1f %unit%]" (gESP) { channel="mqtt:topic:mySecureBroker:room1:temperature" [profile="system:offset", offset=-1.5], unit="°C" }

To get rid of units in rules, just cast to number and use floatValue:

if (ESP8266R1temp.state as Number).floatValue > (sollEGGRUPPEtemp.state as Number).floatValue)
1 Like

Thanks @Udo_Hartmann for these helptful insights. I must admit that I got a bit rusty regarding the the file syntax as the past version of OH have been lazy in considering the units.

But I fully support and appreciate that the configuration has been corrected to be consistent and that it is my task to align appropriately to the correct syntax!!!

I have started using your last hint to set all items in the if comparisons to numbers and I will take your other advice to get my things & items straight.

THANK YOU!!!

Hi Rich,
if I use the API explorer from the UI to get the item state it returns a value without unit:

That’s not the same Item as above. The Item from above is ESP8266R1temp, not ESP8266WZtemp. Without seeing the definition of that Item :man_shrugging:

1 Like

If I change it I get the message:

2024-01-04 17:33:48.361 [WARN ] [penhab.core.library.items.NumberItem] - Failed to update item 'ESP8266WZtemp' because '21.27 °C' could not be converted to the item unit 'one'

What you’ve shown does not match that message.

Number:Dimensionless is used to store ratios. Valid units include %, ONE, db, etc.
Number:Temperature is used to store temperatures. Valid units include °C, °F, K.

That error message indicates that ESP8266WZtemp is defined as a Number:Dimensionless. As @Udo_Hartmann said above, Number:Dimensionless does not mean “no units”. It is a unit unto itself.

You’ve not shown the definition of ESP8266WZtemp

1 Like

@rlkoshak You finally got me :smiley:

I am working with VS Code and stupidly I had the directories of both OH versions open

  • 3.4.2/conf
  • 4.1.0/conf

And I edited the rules in the 4.1.0 path but the items in 3.4.2 path

Hence the changes to the items did not get updated in the 4.1.0 configuration.

:man_facepalming: :man_facepalming: :man_facepalming: Stupid me :bangbang: :bangbang: :bangbang:

Need to go back to “Start” and clean up my mess …

Thank you for your guidance and your patience!!!

Actually R1 = WZ …
I changed it for confidentiality reasons … and now when I have the correct item definition it sends values with units:

item definition:

Number:Temperature ESP8266WZtemp "Room1: Temperatur [%.1f %unit%]" (gESP) { channel="mqtt:topic:mySecureBroker:Room1:temperature" [profile="system:offset", offset=-1.5] }

@rlkoshak may I finally kindly ask how I define an item without a unit?

Would this be simply:

Number  JInTheHouse  "J.R. is in the house [%.0f]" (gGeoFence)

???

Yes. If a state is published to that with units, the unit will get stripped.

1 Like

Thanks, I need this simple item to get the state of my geofence status which is either “0” or “1”.
And creating the sum of all family members gives a number between 1 and 6 against which I test how many people are in the house :slight_smile:
So, all are online numbers :slight_smile:

Thank you for learning again something!!!