Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The "equals" condition does not work for the items storing dimensionless number values #2624

Closed
mak-42 opened this issue Dec 18, 2021 · 7 comments · Fixed by #2653
Closed

Comments

@mak-42
Copy link

mak-42 commented Dec 18, 2021

I created the channel like this and linked it to the item "AqaraSmartHomeCube001_Side".

  - id: side
    channelTypeUID: mqtt:number
    label: Side
    description: null
    configuration:
      min: 0
      stateTopic: zigbee2mqtt/AqaraSmartHomeCube001
      transformationPattern: JSONPATH:$.side
      max: 6

I added the "But only if" condition to the rule like this:

conditions:
  - inputs: {}
    id: "4"
    configuration:
      itemName: AqaraSmartHomeCube001_Side
      state: "0"
      operator: "="
    type: core.ItemStateCondition

This condition always returns "false" even state of "AqaraSmartHomeCube001_Side" is equal to 0.

The problem is in the "org.openhab.core.automation.internal.module.handler.ItemStateConditionHandler". Look at the code (version 3.1.x, but i bet the version 3.2 has the same issue):

            Item item = itemRegistry.getItem(itemName);
            State compareState = TypeParser.parseState(item.getAcceptedDataTypes(), state);
            State itemState = item.getState();
            DecimalType decimalState = itemState.as(DecimalType.class);
            logger.debug("ItemStateCondition '{}'checking if {} (State={}) {} {}", module.getId(), itemName, itemState,
                    operator, compareState);
            switch (operator) {
                case "=":
                    logger.debug("ConditionSatisfied --> {}", itemState.equals(compareState));
                    return itemState.equals(compareState);

The "item.getAcceptedDataTypes()" returns "[class org.openhab.core.library.types.DecimalType, class org.openhab.core.library.types.QuantityType, class org.openhab.core.types.UnDefType]". It means the "TypeParser.parseState(item.getAcceptedDataTypes(), state)" returns object of "DecimalType" creating as "DecimalType.valueOf("0")". But the "item.getState()" returns the object of "QuantityType". The "compareState" and "itemState" have different types. and the equation "temState.equals(compareState)" never returns "true".

The safest way to solve it to rewrite the equation like this:

return (null != decimalState && compareState instanceof DecimalType && decimalState .equals((DecimalType)compareState)) ||  itemState.equals(compareState);

But I think the right path to fix it is to convert the "itemState" to the class of "compareState" before comparing.

I have found a workaround. The condition can be replaced by this couple which works well:

conditions:
  - inputs: {}
    id: "5"
    configuration:
      itemName: AqaraSmartHomeCube001_Side
      state: "0"
      operator: ">="
    type: core.ItemStateCondition
  - inputs: {}
    id: "4"
    configuration:
      itemName: AqaraSmartHomeCube001_Side
      state: "0"
      operator: <=
    type: core.ItemStateCondition
@cweitkamp
Copy link
Contributor

I submitted #2653 to solve this. I will allow equals comparison between DecimalTypes and QuantityTypes but will log a warning to use QuantityType in the condition too if the state is a QuantityType.

@cweitkamp
Copy link
Contributor

I will allow equals comparison between DecimalTypes and QuantityTypes but will log a warning to use QuantityType in the condition too if the state is a QuantityType.

I have to revoke this. We decided in #2653 that we cannot set a DecimalType value of 5 equals to a QuantityType of 5 °C or 5 °F. In the future there will be a warning if the item state has a unit but the comparison value is specified without a unit.

@mak-42
Copy link
Author

mak-42 commented Dec 30, 2021

But what is the solution for the described situation? The item's status is a dimensionless number (a current side number of the cube). What should I write in conditions section instead of "0"?

@cweitkamp
Copy link
Contributor

cweitkamp commented Dec 31, 2021

Just to make sure - your item state is a dimensionless QuantityType without a unit (internally AbstractUnit.ONE)?

For the books - even a dimensionless QuantityType can have a unit e.g. percent "%" or parts per million "ppm".

@mak-42
Copy link
Author

mak-42 commented Dec 31, 2021

It is defined as dimensionless number.
image
did I define something wrong?

@cweitkamp
Copy link
Contributor

cweitkamp commented Dec 31, 2021

No, I would not say you did something wrong. You did something which is possible but not considered in all details. Despite this I would recommend you to use item type Number instead of item type Number:Dimensionless if you really expect a state without a unit.

@mak-42
Copy link
Author

mak-42 commented Jan 1, 2022

@cweitkamp, thanks a lot. I changed the item type to Number and the conditions started work as expected.

@mak-42 mak-42 closed this as completed Jan 1, 2022
@cweitkamp cweitkamp removed PR pending bug An unexpected problem or unintended behavior of the Core labels Jan 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants