openhab / openhab-core

Core framework of openHAB
https://www.openhab.org/
Eclipse Public License 2.0
922 stars 423 forks source link

UoM, using %unit% in the label of an item causes an incorrect interpretation of a QuantityType #1419

Closed miwok72 closed 2 years ago

miwok72 commented 4 years ago

A more detailed description of the problem can be found at: OH community

Item definition:

Number:Dimensionless  LaCrosseTemperatureSensor1_Luftfeuchtigkeit  "Luftfeuchte Kellerraum groß [%.1f %unit%]"  <humidity>  (gLaCrosseHum, gGrenzwertUeberwachung)  {channel="jeelink:lacrosse:18:humidity"}

Jython Rule:

maxHumidity = u"63 %"
minHumidity = u"55 %"

@rule("Entfeuchter schalten")
@when("Item LaCrosseTemperatureSensor1_Luftfeuchtigkeit changed") 
def Entfeuchter_schalten(event):
    LOG = logging.getLogger("{}.Jython_Andi".format(LOG_PREFIX))
    #sensor1Hum = items["LaCrosseTemperatureSensor1_Luftfeuchtigkeit"]  # makes no difference
    sensor1Hum = event.itemState

    LOG.info("itenname {}: {}".format(event.itemName,type(items["LaCrosseTemperatureSensor1_Luftfeuchtigkeit"])))  # for test purposes only
    LOG.info("sensor1Hum: {}".format(type(sensor1Hum)))                                                            # for test purposes only

    if sensor1Hum > QuantityType(maxHumidity):
        LOG.info("Entfeuchter muss eingeschaltet werden {} > {}".format(sensor1Hum, maxHumidity))
        if(items["ZWaveNode2_Switch_greenWAVE"] != ON):
            events.sendCommand("ZWaveNode2_Switch_greenWAVE", "ON")
            send_info_telegram("Entfeuchter ein bei {}".format(sensor1Hum))

    elif sensor1Hum < QuantityType(minHumidity):  
        LOG.info("Entfeuchter muss ausgeschaltet werden {} < {}".format(sensor1Hum, minHumidity))
        if(items["ZWaveNode2_Switch_greenWAVE"] != OFF):
            events.sendCommand("ZWaveNode2_Switch_greenWAVE", "OFF")
            send_info_telegram("Entfeuchter aus bei {}".format(sensor1Hum))

openhab.log extract

2020-04-09 16:02:16.095 [INFO ] [.smarthome.model.core.internal.ModelRepositoryImpl] - Refreshing model 'meinHaus.items'
2020-04-09 16:02:16.130 [INFO ] [jsr223.jython.Jython_Andi                         ] - itenname LaCrosseTemperatureSensor1_Luftfeuchtigkeit: <type 'org.eclipse.smarthome.core.library.types.QuantityType'>
2020-04-09 16:02:16.132 [INFO ] [jsr223.jython.Jython_Andi                         ] - sensor1Hum: <type 'org.eclipse.smarthome.core.library.types.QuantityType'>
2020-04-09 16:02:16.133 [INFO ] [jsr223.jython.Jython_Andi                         ] - Entfeuchter muss eingeschaltet werden 53.0 > 63 %
2020-04-09 16:02:16.134 [INFO ] [jsr223.jython.Jython_Andi                         ] - Entfeuchter ein bei 53.0

OH 2.5.3, Jython 2.7.2, OpenJDK Runtime Environment (Zulu 8.44.0.11-CA-linux64) (build 1.8.0_242-b20)

image

5iver commented 4 years ago

This appears to only affect QuantityType. Steps to reproduce:

1) Create an Item using %unit% in the label:

Number:Dimensionless  Test_Item  "Test Item [%.1f %unit%]"

2) Post a value to the Item through the console:

smarthome:update Test_Item 5

3) Note the state of the Item does not include the unit:

smarthome:status Test_Item

4) Change the Item to not use %unit%:

Number:Dimensionless  Test_Item  "Test Item [%.1f %%]"

5) Update the Item and check the state:

smarthome:update Test_Item 55
smarthome:status Test_Item
cweitkamp commented 4 years ago

Seems to be related to https://github.com/openhab/openhab-core/issues/986#issuecomment-536337499.

I guess the root cause is when one updates the state of an Item having a dimension by a DecimalType (or sends a non quantized command) - even if it expects a QuantityType.

// Edit: The DecimalType will not be converted internally to a QuantityType ...

J-N-K commented 2 years ago

It is correct that when comparing 50 to 55 % (which is 0.55) the result is "50 is bigger". The confusion comes from the fact that the ItemStateEvent does not reflect the internal state of the item but is used to update the item's state. In most cases, this is the same, but not always.

If no unit is given (%unit%) IMO the unit should be considered to be ONE, so again the comparison is correct. This is also reflected by the item state which shows no unit in this case.

In the second case where the unit is fixed to %, the item's state is internally 50 % while the ItemStateEvent carries 50 as state.

The solution here is to either query the item's state from the registry or introduce a proper event like proposed in #2956.