eclipse-archived / smarthome

Eclipse SmartHome™ project
https://www.eclipse.org/smarthome/
Eclipse Public License 2.0
861 stars 784 forks source link

UoM: Unit "One" does not support metric prefixes #5930

Open alexf2015 opened 6 years ago

alexf2015 commented 6 years ago

E.g. if you define the unit MetricPrefix.DECI(SmartHomeUnits.ONE) it will result in the unit-string "done" which is not known. An exception is thrown:


at org.eclipse.smarthome.core.items.events.ItemEventFactory.parseSimpleClassName(ItemEventFactory.java:178)
at org.eclipse.smarthome.core.items.events.ItemEventFactory.parseType(ItemEventFactory.java:146)
at org.eclipse.smarthome.core.items.events.ItemEventFactory.getState(ItemEventFactory.java:124)
at org.eclipse.smarthome.core.items.events.ItemEventFactory.createStateEvent(ItemEventFactory.java:111)
at org.eclipse.smarthome.core.items.events.ItemEventFactory.createEventByType(ItemEventFactory.java:77)
at org.eclipse.smarthome.core.events.AbstractEventFactory.createEvent(AbstractEventFactory.java:50)
at org.eclipse.smarthome.core.internal.events.EventHandler.createESHEvent(EventHandler.java:121)
at org.eclipse.smarthome.core.internal.events.EventHandler.handleEvent(EventHandler.java:95)
at org.eclipse.smarthome.core.internal.events.EventHandler.handleEvent(EventHandler.java:72)
at org.eclipse.smarthome.core.internal.events.ThreadedEventHandler.lambda$0(ThreadedEventHandler.java:67)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.reflect.InvocationTargetException: null
at sun.reflect.GeneratedMethodAccessor79.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.eclipse.smarthome.core.items.events.ItemEventFactory.parseSimpleClassName(ItemEventFactory.java:169)
at org.eclipse.smarthome.core.items.events.ItemEventFactory.parseType(ItemEventFactory.java:146)
at org.eclipse.smarthome.core.items.events.ItemEventFactory.getState(ItemEventFactory.java:124)
at org.eclipse.smarthome.core.items.events.ItemEventFactory.createStateEvent(ItemEventFactory.java:111)
at org.eclipse.smarthome.core.items.events.ItemEventFactory.createEventByType(ItemEventFactory.java:77)
at org.eclipse.smarthome.core.events.AbstractEventFactory.createEvent(AbstractEventFactory.java:50)
at org.eclipse.smarthome.core.internal.events.EventHandler.createESHEvent(EventHandler.java:121)
at org.eclipse.smarthome.core.internal.events.EventHandler.handleEvent(EventHandler.java:95)
Caused by: java.lang.IllegalArgumentException: done not recognized (in 384.0 done at index 6)
at tec.uom.se.quantity.Quantities.getQuantity(Quantities.java:80)
at org.eclipse.smarthome.core.library.types.QuantityType.(QuantityType.java:91)
at org.eclipse.smarthome.core.library.types.QuantityType.valueOf(QuantityType.java:134)
at sun.reflect.GeneratedMethodAccessor79.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.eclipse.smarthome.core.items.events.ItemEventFactory.parseSimpleClassName(ItemEventFactory.java:169)
at org.eclipse.smarthome.core.items.events.ItemEventFactory.parseType(ItemEventFactory.java:146)
at org.eclipse.smarthome.core.items.events.ItemEventFactory.getState(ItemEventFactory.java:124)
at org.eclipse.smarthome.core.items.events.ItemEventFactory.createStateEvent(ItemEventFactory.java:111)
at org.eclipse.smarthome.core.items.events.ItemEventFactory.createEventByType(ItemEventFactory.java:77)
triller-telekom commented 6 years ago

I do not understand what you mean by this issue.

The Exception that you posted is about that the QuantityType is unable to parse 384.0 done. This is correct, because "done" is not a correct unit.

In the topic of the issue you say that the unit "ONE" does not support prefixes. "ONE" is just a placeholder for a number without any unit, that is why it cannot be converted to other units, it simply does not have a unit.

By "does not support prefixes" I understand that you wanted to have "mONE", like "milli ONE" or "kONE" like "kilo ONE", but what do you want to express with that?

BTW: Could you please format the pasted exceptions in `````` (3 ticks before and 3 after) so the code is more readable?

alexf2015 commented 6 years ago

Ok maybe I missed some details. I did not append the "done" that was done by openhab when I created the Quantity Type like this:

double value = 384
new QuantityType<>(value, MetricPrefix.DECI(SIUnits.SmartHomeUnits.ONE));

The channel is defined like this:

    <channel-type id="base-type-43005">
        <item-type>Number:Dimensionless</item-type>
        <label>Degree Minutes (16 bit)</label>
        <description>Degree minutes, 16bit value (-32768 &lt; x &lt; 32767). Values outside valid values are rounded to the closest valid value.</description>
        <state min="-30000" max="30000" step="1" pattern="%d" readOnly="false">
        </state>
    </channel-type>

In general this works fine until I link an item to the channel which is defined like this:

Number:Dimensionless    NIBE_GM                "Gradminuten"                            <pressure>                    (gNibe_General, PersistHistory)                                { channel="nibeuplink:vvm320:mynibe:base#43005" }

In that case the unknown unit "done" is appearing by some magic.

triller-telekom commented 6 years ago

Thanks for providing some more details.

So your use-case is that instead of sending 384, you want to send 38.4, right?

Is that within a binding or within a rule? Within a binding I would expect the binding to send "38.4" directly, without the need for converting it with "DECI".

alexf2015 commented 6 years ago

Well I am gathering values from an API which provides raw data which is always integer. E.g. 22.7°C is provided as 227. Or another example: 174,5kWh is provided as 1745. There are channels which have a scaling factor of 1, 10 or 100. So, in the first place I had my own number scaling logic implemented. But when I switched to UoM I decided to use the metric prefixes instead because it does the same. In the above examples it works fine, I use

MetricPrefix.DECI(SIUnits.CELSIUS)

and

MetricPrefix.HECTO(SmartHomeUnits.WATT_HOUR)

to get the numbers scaled correctly. Just in case of MetricPrefix.DECI(SmartHomeUnits.ONE) it does not work because it generates the unit "one" which is not recognized when prefixed with a metrix prefix such as "d" which results in "done".

htreu commented 5 years ago

Please read the discussion on https://github.com/eclipse/smarthome/pull/6132. We came to the conclusion that for scalar values a conversion by multiplying the scale should happen in the binding, not using ONE with metric prefixes.