diff --git a/bundles/org.openhab.binding.matter/src/main/java/org/openhab/binding/matter/internal/controller/devices/converter/IlluminanceMeasurementConverter.java b/bundles/org.openhab.binding.matter/src/main/java/org/openhab/binding/matter/internal/controller/devices/converter/IlluminanceMeasurementConverter.java index ec7319b0f3..a9c8ae3fca 100644 --- a/bundles/org.openhab.binding.matter/src/main/java/org/openhab/binding/matter/internal/controller/devices/converter/IlluminanceMeasurementConverter.java +++ b/bundles/org.openhab.binding.matter/src/main/java/org/openhab/binding/matter/internal/controller/devices/converter/IlluminanceMeasurementConverter.java @@ -17,15 +17,13 @@ import static org.openhab.binding.matter.internal.MatterBindingConstants.*; import java.util.Collections; import java.util.Map; -import javax.measure.quantity.Illuminance; - import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.matter.internal.client.dto.cluster.gen.IlluminanceMeasurementCluster; import org.openhab.binding.matter.internal.client.dto.ws.AttributeChangedMessage; import org.openhab.binding.matter.internal.handler.MatterBaseThingHandler; +import org.openhab.binding.matter.internal.util.ValueUtils; import org.openhab.core.library.types.QuantityType; -import org.openhab.core.library.unit.Units; import org.openhab.core.thing.Channel; import org.openhab.core.thing.ChannelGroupUID; import org.openhab.core.thing.ChannelUID; @@ -61,8 +59,8 @@ public class IlluminanceMeasurementConverter extends GenericConverter(number.intValue(), Units.LUX)); + QuantityType lux = ValueUtils.valueToIlluminance(number.intValue()); + updateState(CHANNEL_ID_ILLUMINANCEMEASURMENT_MEASUREDVALUE, lux != null ? lux : UnDefType.NULL); } break; } @@ -71,9 +69,9 @@ public class IlluminanceMeasurementConverter extends GenericConverter(initializingCluster.measuredValue, Units.LUX) - : UnDefType.NULL); + QuantityType lux = initializingCluster.measuredValue != null + ? ValueUtils.valueToIlluminance(initializingCluster.measuredValue) + : null; + updateState(CHANNEL_ID_ILLUMINANCEMEASURMENT_MEASUREDVALUE, lux != null ? lux : UnDefType.NULL); } } diff --git a/bundles/org.openhab.binding.matter/src/main/java/org/openhab/binding/matter/internal/util/ValueUtils.java b/bundles/org.openhab.binding.matter/src/main/java/org/openhab/binding/matter/internal/util/ValueUtils.java index 0568863947..b7444c6a16 100644 --- a/bundles/org.openhab.binding.matter/src/main/java/org/openhab/binding/matter/internal/util/ValueUtils.java +++ b/bundles/org.openhab.binding.matter/src/main/java/org/openhab/binding/matter/internal/util/ValueUtils.java @@ -15,6 +15,7 @@ package org.openhab.binding.matter.internal.util; import java.math.BigDecimal; import java.math.RoundingMode; +import javax.measure.quantity.Illuminance; import javax.measure.quantity.Temperature; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -23,6 +24,7 @@ import org.openhab.core.library.types.PercentType; import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.unit.ImperialUnits; import org.openhab.core.library.unit.SIUnits; +import org.openhab.core.library.unit.Units; import org.openhab.core.types.Type; /** @@ -94,4 +96,23 @@ public class ValueUtils { public static QuantityType valueToTemperature(int value) { return new QuantityType<>(BigDecimal.valueOf(value, 2), SIUnits.CELSIUS); } + + /** + * Converts a Matter illuminance measurement value to a {@link QuantityType} in lux. + * The Matter spec encodes illuminance as: MeasuredValue = 10,000 x log10(illuminance) + 1 + * A value of 0 indicates illuminance too low to be measured. + * + * @param value the Matter measured value (0 = too low, 1-0xFFFE = encoded illuminance) + * @return the {@link QuantityType} in lux + */ + public static @Nullable QuantityType valueToIlluminance(int value) { + if (value <= 0) { + return new QuantityType<>(0, Units.LUX); + } + if (value > 0xFFFE) { + return null; + } + double illuminance = Math.pow(10, (value - 1) / 10000.0); + return new QuantityType<>(illuminance, Units.LUX); + } } diff --git a/bundles/org.openhab.binding.matter/src/test/java/org/openhab/binding/matter/internal/controller/devices/converter/IlluminanceMeasurementConverterTest.java b/bundles/org.openhab.binding.matter/src/test/java/org/openhab/binding/matter/internal/controller/devices/converter/IlluminanceMeasurementConverterTest.java index 9a19d3b973..d7b068e830 100644 --- a/bundles/org.openhab.binding.matter/src/test/java/org/openhab/binding/matter/internal/controller/devices/converter/IlluminanceMeasurementConverterTest.java +++ b/bundles/org.openhab.binding.matter/src/test/java/org/openhab/binding/matter/internal/controller/devices/converter/IlluminanceMeasurementConverterTest.java @@ -72,18 +72,20 @@ class IlluminanceMeasurementConverterTest extends BaseMatterConverterTest { AttributeChangedMessage message = new AttributeChangedMessage(); message.path = new Path(); message.path.attributeName = "measuredValue"; - message.value = 100; + message.value = 10001; converter.onEvent(message); + // 10001 -> 10^((10001-1)/10000) = 10^1 = 10 lux verify(mockHandler, times(1)).updateState(eq(1), eq("illuminancemeasurement-measuredvalue"), - eq(new QuantityType(100, Units.LUX))); + eq(new QuantityType(10.0, Units.LUX))); } @Test void testInitState() { - mockCluster.measuredValue = 100; + mockCluster.measuredValue = 20001; converter.initState(); + // 20001 -> 10^((20001-1)/10000) = 10^2 = 100 lux verify(mockHandler, times(1)).updateState(eq(1), eq("illuminancemeasurement-measuredvalue"), - eq(new QuantityType(100, Units.LUX))); + eq(new QuantityType(100.0, Units.LUX))); } @Test