Reuse existing BigDecimals in rules while converting types (#4198)

* Speed up calculations in rules
* Add test for NumberExtensions.numberToBigDecimal

Signed-off-by: Holger Friedrich <mail@holger-friedrich.de>
Co-authored-by: Holger Friedrich <mail@holger-friedrich.de>
This commit is contained in:
joerg1985 2024-05-04 18:59:29 +02:00 committed by GitHub
parent 97cedc46e9
commit 7efdd44197
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 44 additions and 2 deletions

View File

@ -24,7 +24,11 @@ import javax.measure.quantity.Length;
import javax.measure.quantity.Temperature;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.HSBType;
import org.openhab.core.library.types.PercentType;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.unit.Units;
import org.openhab.core.types.Type;
@ -859,4 +863,28 @@ public class NumberExtensionsTest {
assertTrue(result);
}
@ParameterizedTest
@ValueSource(strings = { "0.2", "0.1111111111111111111111111111111111111111111111111111111", "1" })
public void testNumberToBigDecimal(String value) {
DecimalType dt = new DecimalType(value);
assertEquals(value, NumberExtensions.numberToBigDecimal(dt).toString());
PercentType pt = new PercentType(value);
assertEquals(value, NumberExtensions.numberToBigDecimal(pt).toString());
// HSBTye is a subclass of DecimalType, it converts part "V" to a BigDecimal
HSBType hsb = new HSBType(dt, pt, pt);
assertEquals(value, NumberExtensions.numberToBigDecimal(hsb).toString());
int integerTestValue = (int) (Double.valueOf(value).doubleValue() * 1000);
Integer intValue = Integer.valueOf(integerTestValue);
assertEquals("" + integerTestValue, NumberExtensions.numberToBigDecimal(intValue).toString());
Long longValue = Long.valueOf(integerTestValue);
assertEquals("" + integerTestValue, NumberExtensions.numberToBigDecimal(longValue).toString());
BigDecimal bd = new BigDecimal(value);
assertEquals(value, NumberExtensions.numberToBigDecimal(bd).toString());
}
}

View File

@ -379,6 +379,20 @@ public class NumberExtensions {
}
return null;
}
if (number instanceof DecimalType dtype) {
return dtype.toBigDecimal();
}
if (number instanceof BigDecimal decimal) {
return decimal;
}
if (number instanceof Long value) {
// use valueOf to hit the internal cache
return BigDecimal.valueOf(value);
}
if (number instanceof Integer value) {
// use valueOf to hit the internal cache
return BigDecimal.valueOf(value);
}
if (number != null) {
return new BigDecimal(number.toString());
} else {

View File

@ -53,7 +53,7 @@ public class DecimalType extends Number implements PrimitiveType, State, Command
public DecimalType(Number value) {
if (value instanceof QuantityType type) {
this.value = type.toBigDecimal();
} else if (value instanceof HSBType type) {
} else if (value instanceof DecimalType type) {
this.value = type.toBigDecimal();
} else if (value instanceof BigDecimal decimal) {
this.value = decimal;

View File

@ -131,7 +131,7 @@ public class PercentType extends DecimalType {
} else if (target == HSBType.class) {
return target.cast(new HSBType(DecimalType.ZERO, PercentType.ZERO, this));
} else if (target == QuantityType.class) {
return target.cast(new QuantityType<>(toBigDecimal().doubleValue(), Units.PERCENT));
return target.cast(new QuantityType<>(toBigDecimal(), Units.PERCENT));
} else {
return defaultConversion(target);
}