diff --git a/bundles/org.openhab.core.thing/schema/thing/thing-description-1.0.0.xsd b/bundles/org.openhab.core.thing/schema/thing/thing-description-1.0.0.xsd index 438e67927..2140c8cf6 100644 --- a/bundles/org.openhab.core.thing/schema/thing/thing-description-1.0.0.xsd +++ b/bundles/org.openhab.core.thing/schema/thing/thing-description-1.0.0.xsd @@ -193,6 +193,7 @@ + diff --git a/bundles/org.openhab.core/src/main/java/org/openhab/core/internal/i18n/I18nProviderImpl.java b/bundles/org.openhab.core/src/main/java/org/openhab/core/internal/i18n/I18nProviderImpl.java index 693f47366..3c314cd16 100644 --- a/bundles/org.openhab.core/src/main/java/org/openhab/core/internal/i18n/I18nProviderImpl.java +++ b/bundles/org.openhab.core/src/main/java/org/openhab/core/internal/i18n/I18nProviderImpl.java @@ -79,6 +79,7 @@ import org.openhab.core.library.dimension.EmissionIntensity; import org.openhab.core.library.dimension.EnergyPrice; import org.openhab.core.library.dimension.Intensity; import org.openhab.core.library.dimension.RadiantExposure; +import org.openhab.core.library.dimension.RadiationDoseRate; import org.openhab.core.library.dimension.RadiationSpecificActivity; import org.openhab.core.library.dimension.VolumePrice; import org.openhab.core.library.dimension.VolumetricFlowRate; @@ -431,6 +432,7 @@ public class I18nProviderImpl addDefaultUnit(dimensionMap, Mass.class, SIUnits.KILOGRAM, ImperialUnits.POUND); addDefaultUnit(dimensionMap, Power.class, Units.WATT); addDefaultUnit(dimensionMap, Pressure.class, HECTO(SIUnits.PASCAL), ImperialUnits.INCH_OF_MERCURY); + addDefaultUnit(dimensionMap, RadiationDoseRate.class, Units.SIEVERT_PER_HOUR); addDefaultUnit(dimensionMap, RadiationDoseAbsorbed.class, Units.GRAY); addDefaultUnit(dimensionMap, RadiationDoseEffective.class, Units.SIEVERT); addDefaultUnit(dimensionMap, RadiationSpecificActivity.class, Units.BECQUEREL_PER_CUBIC_METRE); diff --git a/bundles/org.openhab.core/src/main/java/org/openhab/core/library/dimension/RadiationDoseRate.java b/bundles/org.openhab.core/src/main/java/org/openhab/core/library/dimension/RadiationDoseRate.java new file mode 100644 index 000000000..4927c7cc6 --- /dev/null +++ b/bundles/org.openhab.core/src/main/java/org/openhab/core/library/dimension/RadiationDoseRate.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2010-2026 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.openhab.core.library.dimension; + +import javax.measure.Quantity; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * Radiation dose per time (basic unit is Sv/h) + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public interface RadiationDoseRate extends Quantity { +} diff --git a/bundles/org.openhab.core/src/main/java/org/openhab/core/library/unit/Units.java b/bundles/org.openhab.core/src/main/java/org/openhab/core/library/unit/Units.java index 94c7c8455..166b87b26 100644 --- a/bundles/org.openhab.core/src/main/java/org/openhab/core/library/unit/Units.java +++ b/bundles/org.openhab.core/src/main/java/org/openhab/core/library/unit/Units.java @@ -60,6 +60,7 @@ import org.openhab.core.library.dimension.ElectricConductivity; import org.openhab.core.library.dimension.EmissionIntensity; import org.openhab.core.library.dimension.Intensity; import org.openhab.core.library.dimension.RadiantExposure; +import org.openhab.core.library.dimension.RadiationDoseRate; import org.openhab.core.library.dimension.RadiationSpecificActivity; import org.openhab.core.library.dimension.VolumetricFlowRate; @@ -193,6 +194,8 @@ public final class Units extends CustomUnits { public static final Unit GRAY = addUnit(tech.units.indriya.unit.Units.GRAY); public static final Unit SIEVERT = addUnit(tech.units.indriya.unit.Units.SIEVERT); + public static final Unit SIEVERT_PER_HOUR = addUnit( + new ProductUnit<>(tech.units.indriya.unit.Units.SIEVERT.divide(tech.units.indriya.unit.Units.HOUR))); public static final Unit MILLIMETRE_PER_HOUR = addUnit( new TransformedUnit<>("mm/h", tech.units.indriya.unit.Units.KILOMETRE_PER_HOUR, MultiplyConverter.ofRational(BigInteger.ONE, BigInteger.valueOf(1000000)))); diff --git a/bundles/org.openhab.core/src/test/java/org/openhab/core/library/dimension/RadiationDoseRateTest.java b/bundles/org.openhab.core/src/test/java/org/openhab/core/library/dimension/RadiationDoseRateTest.java new file mode 100644 index 000000000..e0496825d --- /dev/null +++ b/bundles/org.openhab.core/src/test/java/org/openhab/core/library/dimension/RadiationDoseRateTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2010-2026 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.openhab.core.library.dimension; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.stream.Stream; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.openhab.core.library.types.QuantityType; +import org.openhab.core.types.util.UnitUtils; + +/** + * Test {@link RadiationDoseRate} dimension. + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class RadiationDoseRateTest { + + public static Stream arguments() { + return Stream.of(// + Arguments.of(QuantityType.valueOf(60.0 + " Sv/h"), "Sv/d", 24.0), // + Arguments.of(QuantityType.valueOf(60.0 + " Sv/h"), "Sv/yr", 8760.0), // + Arguments.of(QuantityType.valueOf(60.0 + " Sv/h"), "Sv/min", 1.0 / 60.0), // + Arguments.of(QuantityType.valueOf(60.0 + " Sv/h"), "Sv/s", 1.0 / 3600.0), // + Arguments.of(QuantityType.valueOf(1.23 + " Sv/h"), "mSv/h", 1000.0), // + Arguments.of(QuantityType.valueOf(1.23 + " Sv/h"), "μSv/h", 1000000.0) // + ); + } + + /** + * Test conversion of radiation dose rate quantities to various target units. + * + * @param observable QuantityType representing the original radiation dose rate quantity + * @param targetUnitSymbol String representing the target unit symbol to convert to + * @param factor Double representing the expected conversion factor from the original unit to the target unit + */ + @ParameterizedTest + @MethodSource("arguments") + public void testConversion(QuantityType observable, String targetUnitSymbol, Double factor) { + QuantityType test = observable.toUnit(targetUnitSymbol); + assertNotNull(test, "Conversion to target unit failed"); + assertEquals(observable.getDimension(), test.getDimension(), "Dimension mismatch after conversion"); + assertEquals(UnitUtils.parseUnit(targetUnitSymbol), test.getUnit(), "Unit symbol mismatch after conversion"); + assertEquals(observable.doubleValue() * factor, test.doubleValue(), 1 * factor, "Converted value mismatch"); + } +}