Skip to content

Commit

Permalink
Upgrade Units of Measurement dependencies (openhab#2319)
Browse files Browse the repository at this point in the history
Upgrades UoM dependencies to:

* javax.measure 2.1.2
* si-units 2.0.1
* indriya 2.1.2

An openHAB OSGi-ified si-units bundle is used as runtime dependency, because the latest si-units release is still missing proper OSGi manifest headers.

Notable changes:

* Quantity not longer implements an `equals` method, so the unit tests had to be adjusted. This should have any impact outside of the unit tests though since the rest of openHAB should be using QuantityType instead.
* RationalConverter is not package private, so instances of it much be created through the MultiplyConverter static functions.
* Quantities.getQuantity can no longer parse values without units like `100`. A workaround has been implemented.
* The unicode greek `mu` letter is now returned for unit prefixes instead of the unicode `micro` character. These characters are visually identical but the unit tests had to be adjusted. The new library seems to parse both types just fine.

Also-by: Connor Petty <mistercpp2000+gitsignoff@gmail.com>
Signed-off-by: Wouter Born <github@maindrain.net>
  • Loading branch information
wborn authored and fwolter committed May 24, 2021
1 parent f50078a commit cfbe86a
Show file tree
Hide file tree
Showing 47 changed files with 575 additions and 352 deletions.
14 changes: 7 additions & 7 deletions bom/compile/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -151,19 +151,19 @@
<dependency>
<groupId>javax.measure</groupId>
<artifactId>unit-api</artifactId>
<version>1.0</version>
<version>2.1.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>tec.uom</groupId>
<artifactId>uom-se</artifactId>
<version>1.0.10</version>
<groupId>si.uom</groupId>
<artifactId>si-units</artifactId>
<version>2.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>tec.uom.lib</groupId>
<artifactId>uom-lib-common</artifactId>
<version>1.0.3</version>
<groupId>tech.units</groupId>
<artifactId>indriya</artifactId>
<version>2.1.2</version>
<scope>compile</scope>
</dependency>

Expand Down
33 changes: 26 additions & 7 deletions bom/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -436,22 +436,41 @@
</dependency>

<!-- Measurement -->
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
<version>2.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.measure</groupId>
<artifactId>unit-api</artifactId>
<version>1.0</version>
<version>2.1.2</version>
<scope>compile</scope>
</dependency>
<!-- The si.uom:si-units manifest has no Export-Package entry. As workaround this OSGi-ify bundle is used. -->
<dependency>
<groupId>tec.uom</groupId>
<artifactId>uom-se</artifactId>
<version>1.0.10</version>
<groupId>org.openhab.osgiify</groupId>
<artifactId>si.uom.si-units</artifactId>
<version>2.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>tec.uom.lib</groupId>
<artifactId>uom-lib-common</artifactId>
<version>1.0.3</version>
<groupId>si.uom</groupId>
<artifactId>si-quantity</artifactId>
<version>2.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>tech.units</groupId>
<artifactId>indriya</artifactId>
<version>2.1.2</version>
<scope>compile</scope>
</dependency>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,22 +142,22 @@ public void testHistoricStateQuantityType() {
ZonedDateTime.of(2012, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), TestPersistenceService.ID);
assertNotNull(historicItem);
assertThat(historicItem.getState(), is(instanceOf(QuantityType.class)));
assertEquals("2012.0 °C", historicItem.getState().toString());
assertEquals("2012 °C", historicItem.getState().toString());

historicItem = PersistenceExtensions.historicState(quantityItem,
ZonedDateTime.of(2011, 12, 31, 0, 0, 0, 0, ZoneId.systemDefault()), TestPersistenceService.ID);
assertNotNull(historicItem);
assertEquals("2011.0 °C", historicItem.getState().toString());
assertEquals("2011 °C", historicItem.getState().toString());

historicItem = PersistenceExtensions.historicState(quantityItem,
ZonedDateTime.of(2011, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), TestPersistenceService.ID);
assertNotNull(historicItem);
assertEquals("2011.0 °C", historicItem.getState().toString());
assertEquals("2011 °C", historicItem.getState().toString());

historicItem = PersistenceExtensions.historicState(quantityItem,
ZonedDateTime.of(2000, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), TestPersistenceService.ID);
assertNotNull(historicItem);
assertEquals("2000.0 °C", historicItem.getState().toString());
assertEquals("2000 °C", historicItem.getState().toString());

// default persistence service
historicItem = PersistenceExtensions.historicState(quantityItem,
Expand Down Expand Up @@ -210,19 +210,19 @@ public void testMaximumSinceQuantityType() {
ZonedDateTime.of(2012, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), TestPersistenceService.ID);
assertNotNull(historicItem);
assertThat(historicItem.getState(), is(instanceOf(QuantityType.class)));
assertEquals("1.0 °C", historicItem.getState().toString());
assertEquals("1 °C", historicItem.getState().toString());

historicItem = PersistenceExtensions.maximumSince(quantityItem,
ZonedDateTime.of(2005, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), TestPersistenceService.ID);
assertNotNull(historicItem);
assertEquals("2012.0 °C", historicItem.getState().toString());
assertEquals("2012 °C", historicItem.getState().toString());
assertEquals(ZonedDateTime.of(2012, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), historicItem.getTimestamp());

// default persistence service
historicItem = PersistenceExtensions.maximumSince(quantityItem,
ZonedDateTime.of(2005, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()));
assertNotNull(historicItem);
assertEquals("1.0 °C", historicItem.getState().toString());
assertEquals("1 °C", historicItem.getState().toString());
}

@Test
Expand Down Expand Up @@ -281,19 +281,19 @@ public void testMinimumSinceQuantityType() {
ZonedDateTime.of(1940, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), TestPersistenceService.ID);
assertNotNull(historicItem);
assertThat(historicItem.getState(), is(instanceOf(QuantityType.class)));
assertEquals("5000.0 °C", historicItem.getState().toString());
assertEquals("5000 °C", historicItem.getState().toString());

historicItem = PersistenceExtensions.minimumSince(quantityItem,
ZonedDateTime.of(2005, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), TestPersistenceService.ID);
assertNotNull(historicItem);
assertEquals("2005.0 °C", historicItem.getState().toString());
assertEquals("2005 °C", historicItem.getState().toString());
assertEquals(ZonedDateTime.of(2005, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), historicItem.getTimestamp());

// default persistence service
historicItem = PersistenceExtensions.minimumSince(quantityItem,
ZonedDateTime.of(2005, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()));
assertNotNull(historicItem);
assertEquals("5000.0 °C", historicItem.getState().toString());
assertEquals("5000 °C", historicItem.getState().toString());
}

@Test
Expand Down Expand Up @@ -601,22 +601,22 @@ public void testPreviousStateQuantityTypeNoSkip() {
TestPersistenceService.ID);
assertNotNull(prevStateItem);
assertThat(prevStateItem.getState(), is(instanceOf(QuantityType.class)));
assertEquals("2012.0 °C", prevStateItem.getState().toString());
assertEquals("2012 °C", prevStateItem.getState().toString());

quantityItem.setState(QuantityType.valueOf(4321, SIUnits.CELSIUS));
prevStateItem = PersistenceExtensions.previousState(quantityItem, false, TestPersistenceService.ID);
assertNotNull(prevStateItem);
assertEquals("2012.0 °C", prevStateItem.getState().toString());
assertEquals("2012 °C", prevStateItem.getState().toString());

quantityItem.setState(QuantityType.valueOf(2012, SIUnits.CELSIUS));
prevStateItem = PersistenceExtensions.previousState(quantityItem, false, TestPersistenceService.ID);
assertNotNull(prevStateItem);
assertEquals("2012.0 °C", prevStateItem.getState().toString());
assertEquals("2012 °C", prevStateItem.getState().toString());

quantityItem.setState(QuantityType.valueOf(3025, SIUnits.CELSIUS));
prevStateItem = PersistenceExtensions.previousState(quantityItem, false, TestPersistenceService.ID);
assertNotNull(prevStateItem);
assertEquals("2012.0 °C", prevStateItem.getState().toString());
assertEquals("2012 °C", prevStateItem.getState().toString());

// default persistence service
prevStateItem = PersistenceExtensions.previousState(quantityItem, false);
Expand All @@ -640,7 +640,7 @@ public void testPreviousStateQuantityTypeSkip() {
quantityItem.setState(QuantityType.valueOf(2012, SIUnits.CELSIUS));
HistoricItem prevStateItem = PersistenceExtensions.previousState(quantityItem, true, TestPersistenceService.ID);
assertNotNull(prevStateItem);
assertEquals("2011.0 °C", prevStateItem.getState().toString());
assertEquals("2011 °C", prevStateItem.getState().toString());

// default persistence service
prevStateItem = PersistenceExtensions.previousState(quantityItem, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import tec.uom.se.AbstractUnit;
import tech.units.indriya.AbstractUnit;

/***
* This is the default implementation for a {@link SystemHysteresisStateProfile}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import tec.uom.se.AbstractUnit;
import tech.units.indriya.AbstractUnit;

/***
* This is the default implementation for a {@link SystemRangeStateProfile}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import javax.measure.Dimension;
import javax.measure.IncommensurableException;
import javax.measure.Quantity;
import javax.measure.Quantity.Scale;
import javax.measure.UnconvertibleException;
import javax.measure.Unit;
import javax.measure.UnitConverter;
Expand All @@ -41,9 +42,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import tec.uom.se.AbstractUnit;
import tec.uom.se.function.QuantityFunctions;
import tec.uom.se.quantity.Quantities;
import tech.units.indriya.AbstractUnit;
import tech.units.indriya.quantity.Quantities;
import tech.uom.lib.common.function.QuantityFunctions;

/**
* The measure type extends DecimalType to handle physical unit measurement
Expand Down Expand Up @@ -97,7 +98,13 @@ public QuantityType(String value) {

// getQuantity needs a space between numeric value and unit
String formatted = String.join(" ", constituents);
quantity = (Quantity<T>) Quantities.getQuantity(formatted);
if (!formatted.contains(" ")) {
BigDecimal bd = new BigDecimal(value);
quantity = (Quantity<T>) Quantities.getQuantity(bd, AbstractUnit.ONE, Scale.RELATIVE);
} else {
Quantity<T> absoluteQuantity = (Quantity<T>) Quantities.getQuantity(formatted);
quantity = Quantities.getQuantity(absoluteQuantity.getValue(), absoluteQuantity.getUnit(), Scale.RELATIVE);
}
}

/**
Expand All @@ -111,7 +118,7 @@ public QuantityType(String value) {
public QuantityType(Number value, Unit<T> unit) {
// Avoid scientific notation for double
BigDecimal bd = new BigDecimal(value.toString());
quantity = (Quantity<T>) Quantities.getQuantity(bd, unit);
quantity = (Quantity<T>) Quantities.getQuantity(bd, unit, Scale.RELATIVE);
}

/**
Expand Down Expand Up @@ -156,7 +163,7 @@ public boolean equals(@Nullable Object obj) {
return false;
}
QuantityType<?> other = (QuantityType<?>) obj;
if (!quantity.getUnit().getDimension().equals(other.quantity.getUnit().getDimension())) {
if (!quantity.getUnit().isCompatible(other.quantity.getUnit())) {
return false;
} else if (compareTo((QuantityType<T>) other) != 0) {
return false;
Expand Down Expand Up @@ -363,7 +370,7 @@ public QuantityType<T> add(QuantityType<T> state) {
* @return the negated value of this QuantityType.
*/
public QuantityType<T> negate() {
return new QuantityType<>(quantity.multiply(-1));
return new QuantityType<>(quantity.negate());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,11 @@ public State calculate(@Nullable Set<Item> items) {
sum = itemState; // initialise the sum from the first item
count++;
} else {
sum = sum.add(itemState);
count++;
itemState = itemState.toUnit(sum.getUnit());
if (itemState != null) {
sum = sum.add(itemState);
count++;
}
}
}
}
Expand Down Expand Up @@ -131,8 +134,11 @@ public State calculate(@Nullable Set<Item> items) {
if (itemState != null) {
if (sum == null) {
sum = itemState; // initialise the sum from the first item
} else if (sum.getUnit().isCompatible(itemState.getUnit())) {
sum = sum.add(itemState);
} else {
itemState = itemState.toUnit(sum.getUnit());
if (itemState != null) {
sum = sum.add(itemState);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@

import org.eclipse.jdt.annotation.NonNullByDefault;

import tec.uom.lib.common.function.SymbolSupplier;
import tec.uom.lib.common.function.UnitConverterSupplier;
import tec.uom.se.function.RationalConverter;
import tech.units.indriya.function.MultiplyConverter;
import tech.uom.lib.common.function.SymbolSupplier;
import tech.uom.lib.common.function.UnitConverterSupplier;

/**
* The binary prefixes used to derive units by specific powers of 2.
Expand All @@ -31,14 +31,14 @@
*/
@NonNullByDefault
public enum BinaryPrefix implements SymbolSupplier, UnitConverterSupplier {
YOBI("Yi", new RationalConverter(BigInteger.valueOf(2).pow(80), BigInteger.ONE)),
ZEBI("Zi", new RationalConverter(BigInteger.valueOf(2).pow(70), BigInteger.ONE)),
EXBI("Ei", new RationalConverter(BigInteger.valueOf(2).pow(60), BigInteger.ONE)),
PEBI("Pi", new RationalConverter(BigInteger.valueOf(2).pow(50), BigInteger.ONE)),
TEBI("Ti", new RationalConverter(BigInteger.valueOf(2).pow(40), BigInteger.ONE)),
GIBI("Gi", new RationalConverter(BigInteger.valueOf(2).pow(30), BigInteger.ONE)),
MEBI("Mi", new RationalConverter(BigInteger.valueOf(2).pow(20), BigInteger.ONE)),
KIBI("Ki", new RationalConverter(BigInteger.valueOf(2).pow(10), BigInteger.ONE));
YOBI("Yi", MultiplyConverter.ofRational(BigInteger.valueOf(2).pow(80), BigInteger.ONE)),
ZEBI("Zi", MultiplyConverter.ofRational(BigInteger.valueOf(2).pow(70), BigInteger.ONE)),
EXBI("Ei", MultiplyConverter.ofRational(BigInteger.valueOf(2).pow(60), BigInteger.ONE)),
PEBI("Pi", MultiplyConverter.ofRational(BigInteger.valueOf(2).pow(50), BigInteger.ONE)),
TEBI("Ti", MultiplyConverter.ofRational(BigInteger.valueOf(2).pow(40), BigInteger.ONE)),
GIBI("Gi", MultiplyConverter.ofRational(BigInteger.valueOf(2).pow(30), BigInteger.ONE)),
MEBI("Mi", MultiplyConverter.ofRational(BigInteger.valueOf(2).pow(20), BigInteger.ONE)),
KIBI("Ki", MultiplyConverter.ofRational(BigInteger.valueOf(2).pow(10), BigInteger.ONE));

/**
* The symbol of this prefix, as returned by {@link #getSymbol}.
Expand All @@ -61,7 +61,7 @@ public enum BinaryPrefix implements SymbolSupplier, UnitConverterSupplier {
* @param symbol the symbol of this prefix.
* @param converter the associated unit converter.
*/
BinaryPrefix(String symbol, RationalConverter converter) {
BinaryPrefix(String symbol, MultiplyConverter converter) {
this.symbol = symbol;
this.converter = converter;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*/
package org.openhab.core.library.unit;

import tec.uom.se.AbstractSystemOfUnits;
import tech.units.indriya.AbstractSystemOfUnits;

/**
* Base class for all custom unit classes added in openHAB.
Expand Down
Loading

0 comments on commit cfbe86a

Please sign in to comment.