QuantityType<Dimensionless> with unit one wrong update to item with different unit set
Closed this issue · 2 comments
An Number<Dimensionless>
item with a unit set in metadata to something different from the default of one
will not update correctly in a postUpdate
with a QuantityType<Dimensionless>
and unit one
.
This is because the unit (one
) gets dropped here . As there is no unit, postUpdate
will assume it is a Number
item and update with the configured unit.
To test this I created an Item Test with unit % and pattern %,.2f %%.
I tested with the javascript below (result is similar with DSL). Notice I tried updating the result of the division 4 times, once straight, twice after conversion to a compatible unit (I even used dB), and once where I explicitly appended one to the result. The timeouts are there to wait for the update to happen before logging.
The postUpdate in test 1 is the one producing the wrong result.
Issue was first discussed on the community: https://community.openhab.org/t/inconsistent-percentage-behaviour/154595/20?u=mherwege
var logger = log('Test');
var bkw = Quantity('5 W')
var zwl = Quantity('5 W')
var result = bkw.divide(bkw.add(zwl)) // I want to preserve the QuantityType for logging
logger.info('Result of calculation is: {}', result.toString())
logger.info('Unit is: {}', result.unit) // I would actually expect this to show `ONE`
logger.info('Dimension is: {}', result.dimension)
logger.info('Result %: {}', result.toUnit('%').toString())
logger.info('Test 1, no unit applied: {}', result.toString())
items.Test.postUpdate(result)
setTimeout(() => {
logger.info('State: {}', items.Test.state)
logger.info('Test 2, % unit applied: {}', result.toUnit('%').toString())
items.Test.postUpdate(result.toUnit('%'))
setTimeout(() => {
logger.info('State: {}', items.Test.state)
logger.info('Test 3, dB unit applied: {}', result.toUnit('dB').toString())
items.Test.postUpdate(result.toUnit('dB'))
setTimeout(() => {
logger.info('State: {}', items.Test.state)
logger.info('Test 4, one appended: {}', result.toString() + ' one')
items.Test.postUpdate(result.toString() + ' one')
setTimeout(() => {
logger.info('State: {}', items.Test.state)
}, 1000)
}, 1000)
}, 1000)
}, 1000)
Here is the log output with the problem in test 1:
==> /var/log/openhab/openhab.log <==
2024-04-02 18:17:51.042 [INFO ] [g.openhab.automation.openhab-js.test] - Result of calculation is: 0.5
2024-04-02 18:17:51.044 [INFO ] [g.openhab.automation.openhab-js.test] - Unit is: One
2024-04-02 18:17:51.046 [INFO ] [g.openhab.automation.openhab-js.test] - Dimension is: one
2024-04-02 18:17:51.049 [INFO ] [g.openhab.automation.openhab-js.test] - Result %: 50 %
2024-04-02 18:17:51.051 [INFO ] [g.openhab.automation.openhab-js.test] - Test 1, no unit applied: 0.5
==> /var/log/openhab/events.log <==
2024-04-02 18:17:51.056 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Test' changed from 50 % to 0.5 %
==> /var/log/openhab/openhab.log <==
2024-04-02 18:17:52.056 [INFO ] [g.openhab.automation.openhab-js.test] - State: 0.5 %
2024-04-02 18:17:52.060 [INFO ] [g.openhab.automation.openhab-js.test] - Test 2, % unit applied: 50 %
==> /var/log/openhab/events.log <==
2024-04-02 18:17:52.069 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Test' changed from 0.5 % to 50 %
==> /var/log/openhab/openhab.log <==
2024-04-02 18:17:53.070 [INFO ] [g.openhab.automation.openhab-js.test] - State: 50 %
2024-04-02 18:17:53.074 [INFO ] [g.openhab.automation.openhab-js.test] - Test 3, dB unit applied: -3.01029995663981149813768617048017673474732841360630 dB
2024-04-02 18:17:54.083 [INFO ] [g.openhab.automation.openhab-js.test] - State: 50 %
2024-04-02 18:17:54.086 [INFO ] [g.openhab.automation.openhab-js.test] - Test 4, one appended: 0.5 one
2024-04-02 18:17:55.093 [INFO ] [g.openhab.automation.openhab-js.test] - State: 50 %
This issue has been mentioned on openHAB Community. There might be relevant details there:
https://community.openhab.org/t/inconsistent-percentage-behaviour/154595/36
One suggestion to solve this would be to remove the special handling for unit one
in the toFullString() method of QuantityType. That would by default show one
behind the value if not overriden with a state description. I think this is acceptable and would at least make it clearer if we see a Number or QuantityType with unit one
.