From c6a9085a74e05ebfdf63d215fb52d28c712f693c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20L=27hopital?= Date: Sat, 30 Mar 2019 21:43:15 +0100 Subject: [PATCH] Adding DataAmount (bit and derivatives) and DataTransferRates (bits per second) (#681) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adding DataAmount (bit and derivatives) and DataTransferRates (bits per second) to UoM Signed-off-by: Gaël L'hopital --- .../core/library/dimension/DataAmount.java | 28 +++ .../library/dimension/DataTransferRate.java | 27 +++ .../core/library/unit/BinaryPrefix.java | 178 ++++++++++++++++++ .../core/library/unit/SmartHomeUnits.java | 34 ++++ .../core/library/types/QuantityTypeTest.java | 27 +++ 5 files changed, 294 insertions(+) create mode 100644 bundles/org.openhab.core/src/main/java/org/eclipse/smarthome/core/library/dimension/DataAmount.java create mode 100644 bundles/org.openhab.core/src/main/java/org/eclipse/smarthome/core/library/dimension/DataTransferRate.java create mode 100644 bundles/org.openhab.core/src/main/java/org/eclipse/smarthome/core/library/unit/BinaryPrefix.java diff --git a/bundles/org.openhab.core/src/main/java/org/eclipse/smarthome/core/library/dimension/DataAmount.java b/bundles/org.openhab.core/src/main/java/org/eclipse/smarthome/core/library/dimension/DataAmount.java new file mode 100644 index 000000000..842ecdc16 --- /dev/null +++ b/bundles/org.openhab.core/src/main/java/org/eclipse/smarthome/core/library/dimension/DataAmount.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2010-2019 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.smarthome.core.library.dimension; + +import javax.measure.Quantity; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * Represents a measure of data amount. + * The metric system unit for this quantity is "bit". + * + * @author Gaël L'hopital - Initial contribution + * + */ +@NonNullByDefault +public interface DataAmount extends Quantity { +} diff --git a/bundles/org.openhab.core/src/main/java/org/eclipse/smarthome/core/library/dimension/DataTransferRate.java b/bundles/org.openhab.core/src/main/java/org/eclipse/smarthome/core/library/dimension/DataTransferRate.java new file mode 100644 index 000000000..6f0ee31ea --- /dev/null +++ b/bundles/org.openhab.core/src/main/java/org/eclipse/smarthome/core/library/dimension/DataTransferRate.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2010-2019 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.smarthome.core.library.dimension; + +import javax.measure.Quantity; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * Represents a measure of data or data blocks per unit time passing through a communication link + * + * @author Gaël L'hopital - Initial contribution + * + */ +@NonNullByDefault +public interface DataTransferRate extends Quantity { +} diff --git a/bundles/org.openhab.core/src/main/java/org/eclipse/smarthome/core/library/unit/BinaryPrefix.java b/bundles/org.openhab.core/src/main/java/org/eclipse/smarthome/core/library/unit/BinaryPrefix.java new file mode 100644 index 000000000..fb08a078b --- /dev/null +++ b/bundles/org.openhab.core/src/main/java/org/eclipse/smarthome/core/library/unit/BinaryPrefix.java @@ -0,0 +1,178 @@ +/** + * Copyright (c) 2010-2019 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.smarthome.core.library.unit; + +import java.math.BigInteger; + +import javax.measure.Quantity; +import javax.measure.Unit; +import javax.measure.UnitConverter; + +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; + +/** + * The binary prefixes used to derive units by specific powers of 2. + * + * @author Gaël L'hopital - Initial contribution + * + */ +@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)); + + /** + * The symbol of this prefix, as returned by {@link #getSymbol}. + * + * @see #getSymbol() + */ + private final String symbol; + + /** + * The UnitConverter of this prefix, as returned by {@link #getConverter}. + * + * @see #getConverter() + * @see {@link UnitConverter} + */ + private final UnitConverter converter; + + /** + * Creates a new prefix. + * + * @param symbol the symbol of this prefix. + * @param converter the associated unit converter. + */ + BinaryPrefix(String symbol, RationalConverter converter) { + this.symbol = symbol; + this.converter = converter; + } + + /** + * Returns the symbol of this prefix. + * + * @return this prefix symbol, not {@code null}. + */ + @Override + public String getSymbol() { + return symbol; + } + + /** + * Returns the corresponding unit converter. + * + * @return the unit converter. + */ + @Override + public UnitConverter getConverter() { + return converter; + } + + /** + * Returns the specified unit multiplied by the factor 280 + * + * @param The type of the quantity measured by the unit. + * @param unit any unit. + * @return unit.times(2e80). + */ + public static > Unit YOBI(Unit unit) { + return unit.transform(YOBI.getConverter()); + } + + /** + * Returns the specified unit multiplied by the factor 270 + * + * @param The type of the quantity measured by the unit. + * @param unit any unit. + * @return unit.times(2e70). + */ + public static > Unit ZEBI(Unit unit) { + return unit.transform(ZEBI.getConverter()); + } + + /** + * Returns the specified unit multiplied by the factor 260 + * + * @param The type of the quantity measured by the unit. + * @param unit any unit. + * @return unit.times(2e60). + */ + public static > Unit EXBI(Unit unit) { + return unit.transform(EXBI.getConverter()); + } + + /** + * Returns the specified unit multiplied by the factor 250 + * + * @param The type of the quantity measured by the unit. + * @param unit any unit. + * @return unit.times(2e50). + */ + public static > Unit PEBI(Unit unit) { + return unit.transform(PEBI.getConverter()); + } + + /** + * Returns the specified unit multiplied by the factor 240 + * + * @param The type of the quantity measured by the unit. + * @param unit any unit. + * @return unit.times(2e40). + */ + public static > Unit TEBI(Unit unit) { + return unit.transform(TEBI.getConverter()); + } + + /** + * Returns the specified unit multiplied by the factor 230 + * + * @param The type of the quantity measured by the unit. + * @param unit any unit. + * @return unit.times(2e30). + */ + public static > Unit GIBI(Unit unit) { + return unit.transform(GIBI.getConverter()); + } + + /** + * Returns the specified unit multiplied by the factor 220 + * + * @param The type of the quantity measured by the unit. + * @param unit any unit. + * @return unit.times(2e20). + */ + public static > Unit MEBI(Unit unit) { + return unit.transform(MEBI.getConverter()); + } + + /** + * Returns the specified unit multiplied by the factor 210 + * + * @param The type of the quantity measured by the unit. + * @param unit any unit. + * @return unit.times(2e10). + */ + public static > Unit KIBI(Unit unit) { + return unit.transform(KIBI.getConverter()); + } + +} diff --git a/bundles/org.openhab.core/src/main/java/org/eclipse/smarthome/core/library/unit/SmartHomeUnits.java b/bundles/org.openhab.core/src/main/java/org/eclipse/smarthome/core/library/unit/SmartHomeUnits.java index d674403e2..d6130b612 100644 --- a/bundles/org.openhab.core/src/main/java/org/eclipse/smarthome/core/library/unit/SmartHomeUnits.java +++ b/bundles/org.openhab.core/src/main/java/org/eclipse/smarthome/core/library/unit/SmartHomeUnits.java @@ -49,6 +49,8 @@ import javax.measure.spi.SystemOfUnits; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.smarthome.core.library.dimension.ArealDensity; +import org.eclipse.smarthome.core.library.dimension.DataAmount; +import org.eclipse.smarthome.core.library.dimension.DataTransferRate; import org.eclipse.smarthome.core.library.dimension.Density; import org.eclipse.smarthome.core.library.dimension.Intensity; import org.eclipse.smarthome.core.library.dimension.VolumetricFlowRate; @@ -162,6 +164,24 @@ public final class SmartHomeUnits extends CustomUnits { new ProductUnit(Units.CUBIC_METRE.divide(Units.HOUR))); public static final Unit CUBICMETRE_PER_DAY = addUnit( new ProductUnit(Units.CUBIC_METRE.divide(Units.DAY))); + public static final Unit BIT = addUnit(new AlternateUnit(ONE, "bit")); + public static final Unit MEGABIT = addUnit(MetricPrefix.MEGA(BIT)); + public static final Unit KILOBIT = addUnit(MetricPrefix.KILO(BIT)); + public static final Unit GIGABIT = addUnit(MetricPrefix.GIGA(BIT)); + public static final Unit TERABIT = addUnit(MetricPrefix.TERA(BIT)); + + public static final Unit BYTE = addUnit(BIT.multiply(8)); + public static final Unit OCTET = BYTE; + public static final Unit KIBIOCTET = addUnit(BinaryPrefix.KIBI(OCTET)); + public static final Unit MEBIOCTET = addUnit(BinaryPrefix.MEBI(OCTET)); + public static final Unit GIBIOCTET = addUnit(BinaryPrefix.GIBI(OCTET)); + + public static final Unit BIT_PER_SECOND = addUnit( + new ProductUnit(BIT.divide(Units.SECOND))); + public static final Unit KILOBIT_PER_SECOND = addUnit(MetricPrefix.KILO(BIT_PER_SECOND)); + public static final Unit MEGABIT_PER_SECOND = addUnit(MetricPrefix.MEGA(BIT_PER_SECOND)); + public static final Unit GIGABIT_PER_SECOND = addUnit(MetricPrefix.GIGA(BIT_PER_SECOND)); + public static final Unit TERABIT_PER_SECOND = addUnit(MetricPrefix.TERA(BIT_PER_SECOND)); /** * Add unit symbols for custom openHAB units. @@ -169,6 +189,9 @@ public final class SmartHomeUnits extends CustomUnits { static { // Ordered alphabetical by name SimpleUnitFormat.getInstance().label(BAR, BAR.getSymbol()); + SimpleUnitFormat.getInstance().label(BIT, BIT.getSymbol()); + SimpleUnitFormat.getInstance().label(BIT_PER_SECOND, "bit/s"); + SimpleUnitFormat.getInstance().label(BYTE, "o"); SimpleUnitFormat.getInstance().label(CUBICMETRE_PER_DAY, "m³/d"); SimpleUnitFormat.getInstance().label(CUBICMETRE_PER_HOUR, "m³/h"); SimpleUnitFormat.getInstance().label(CUBICMETRE_PER_MINUTE, "m³/min"); @@ -178,10 +201,19 @@ public final class SmartHomeUnits extends CustomUnits { SimpleUnitFormat.getInstance().label(DEGREE_ANGLE, "°"); SimpleUnitFormat.getInstance().label(DEUTSCHE_HAERTE, "°dH"); SimpleUnitFormat.getInstance().label(DOBSON_UNIT, "DU"); + SimpleUnitFormat.getInstance().label(GIBIOCTET, "Gio"); + SimpleUnitFormat.getInstance().label(GIGABIT, "Gbit"); + SimpleUnitFormat.getInstance().label(GIGABIT_PER_SECOND, "Gbit/s"); SimpleUnitFormat.getInstance().label(IRRADIANCE, "W/m²"); + SimpleUnitFormat.getInstance().label(KIBIOCTET, "Kio"); + SimpleUnitFormat.getInstance().label(KILOBIT, "kbit"); + SimpleUnitFormat.getInstance().label(KILOBIT_PER_SECOND, "kbit/s"); SimpleUnitFormat.getInstance().label(KILOWATT_HOUR, "kWh"); SimpleUnitFormat.getInstance().label(KNOT, KNOT.getSymbol()); SimpleUnitFormat.getInstance().label(LITRE_PER_MINUTE, "l/min"); + SimpleUnitFormat.getInstance().label(MEBIOCTET, "Mio"); + SimpleUnitFormat.getInstance().label(MEGABIT, "Mbit"); + SimpleUnitFormat.getInstance().label(MEGABIT_PER_SECOND, "Mbit/s"); SimpleUnitFormat.getInstance().label(MEGAWATT_HOUR, "MWh"); SimpleUnitFormat.getInstance().label(MICROGRAM_PER_CUBICMETRE, "µg/m³"); SimpleUnitFormat.getInstance().label(MICROWATT_PER_SQUARE_CENTIMETRE, "µW/cm²"); @@ -189,6 +221,8 @@ public final class SmartHomeUnits extends CustomUnits { SimpleUnitFormat.getInstance().label(MILLIMETRE_OF_MERCURY, MILLIMETRE_OF_MERCURY.getSymbol()); SimpleUnitFormat.getInstance().label(PARTS_PER_MILLION, "ppm"); SimpleUnitFormat.getInstance().label(STANDARD_GRAVITY, "gₙ"); + SimpleUnitFormat.getInstance().label(TERABIT, "Tbit"); + SimpleUnitFormat.getInstance().label(TERABIT_PER_SECOND, "Tbit/s"); SimpleUnitFormat.getInstance().label(WATT_HOUR, "Wh"); SimpleUnitFormat.getInstance().label(WATT_SECOND, "Ws"); } diff --git a/itests/org.openhab.core.tests/src/main/java/org/eclipse/smarthome/core/library/types/QuantityTypeTest.java b/itests/org.openhab.core.tests/src/main/java/org/eclipse/smarthome/core/library/types/QuantityTypeTest.java index be4322628..f297c086b 100644 --- a/itests/org.openhab.core.tests/src/main/java/org/eclipse/smarthome/core/library/types/QuantityTypeTest.java +++ b/itests/org.openhab.core.tests/src/main/java/org/eclipse/smarthome/core/library/types/QuantityTypeTest.java @@ -25,6 +25,8 @@ import javax.measure.quantity.Pressure; import javax.measure.quantity.Speed; import javax.measure.quantity.Temperature; +import org.eclipse.smarthome.core.library.dimension.DataAmount; +import org.eclipse.smarthome.core.library.dimension.DataTransferRate; import org.eclipse.smarthome.core.library.dimension.Density; import org.eclipse.smarthome.core.library.dimension.Intensity; import org.eclipse.smarthome.core.library.unit.MetricPrefix; @@ -33,6 +35,7 @@ import org.eclipse.smarthome.core.library.unit.SmartHomeUnits; import org.junit.Test; import tec.uom.se.quantity.QuantityDimension; +import tec.uom.se.unit.Units; /** * @author Gaël L'hopital - initial contribution @@ -293,4 +296,28 @@ public class QuantityTypeTest { QuantityType rate = new QuantityType<>("3 mm/h"); assertEquals("0.1181102362204724409448818897637795 in/h", rate.toUnit("in/h").toString()); } + + @Test + public void testDataAmount() { + QuantityType amount = new QuantityType<>("8 bit"); + QuantityType octet = amount.toUnit(SmartHomeUnits.BYTE); + assertEquals(1, octet.byteValue()); + QuantityType bigAmount = new QuantityType<>("1 Kio"); + QuantityType octets = bigAmount.toUnit(SmartHomeUnits.OCTET); + assertEquals(1024, octets.intValue()); + QuantityType hugeAmount = new QuantityType<>("1024Gio"); + QuantityType lotOfOctets = hugeAmount.toUnit(SmartHomeUnits.OCTET); + assertEquals("1099511627776 o", lotOfOctets.toString()); + } + + @Test + public void testDataTransferRate() { + QuantityType speed = new QuantityType<>("1024 bit/s"); + QuantityType octet = speed.toUnit(SmartHomeUnits.OCTET.divide(Units.SECOND)); + assertEquals(128, octet.intValue()); + QuantityType gsm2G = new QuantityType<>("115 Mbit/s"); + QuantityType octets = gsm2G + .toUnit(MetricPrefix.KILO(SmartHomeUnits.OCTET).divide(Units.SECOND)); + assertEquals(14375, octets.intValue()); + } }