From 44d906cfe0b2e7a51cb94430f98fef16cee7c65a Mon Sep 17 00:00:00 2001 From: Cody Cutrer Date: Tue, 20 Dec 2022 13:15:10 -0700 Subject: [PATCH] [dali] handle and provide QuantityType for color-temperature-abs channel (#14021) see openhab/openhab-core#3129 Signed-off-by: Cody Cutrer --- .../handler/DaliDt8DeviceHandler.java | 49 ++++++++++++------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/bundles/org.openhab.binding.dali/src/main/java/org/openhab/binding/dali/internal/handler/DaliDt8DeviceHandler.java b/bundles/org.openhab.binding.dali/src/main/java/org/openhab/binding/dali/internal/handler/DaliDt8DeviceHandler.java index 36e82641a011f..c0b17d1c4e9a0 100644 --- a/bundles/org.openhab.binding.dali/src/main/java/org/openhab/binding/dali/internal/handler/DaliDt8DeviceHandler.java +++ b/bundles/org.openhab.binding.dali/src/main/java/org/openhab/binding/dali/internal/handler/DaliDt8DeviceHandler.java @@ -28,6 +28,8 @@ 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.thing.ChannelUID; import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingStatus; @@ -62,26 +64,37 @@ public void handleCommand(ChannelUID channelUID, Command command) { } else { throw new DaliException("unknown device type"); } + int mirek; if (command instanceof DecimalType) { // Color temperature in DALI is represented in mirek ("reciprocal megakelvin") // It is one million times the reciprocal of the color temperature (in Kelvin) - final int mirek = (int) (1E6f - / (Math.min(Math.max(((DecimalType) command).intValue(), 1000), 20000))); - final byte mirekLsb = (byte) (mirek & 0xff); - final byte mirekMsb = (byte) ((mirek >> 8) & 0xff); - // Write mirek value to the DTR0+DTR1 registers - daliHandler.sendCommand(DaliStandardCommand.createSetDTR0Command(mirekLsb)); - daliHandler.sendCommand(DaliStandardCommand.createSetDTR1Command(mirekMsb)); - // Indicate that the follwing command is a DT8 (WW/CW and single-channel RGB) command - daliHandler.sendCommand(DaliStandardCommand.createSetDeviceTypeCommand(8)); - // Set the color temperature to the value in DTR0+DTR1 - daliHandler.sendCommand(DaliStandardCommand.createSetColorTemperatureCommand(address)); - // Finish the command sequence - daliHandler.sendCommand(DaliStandardCommand.createSetDeviceTypeCommand(8)); - daliHandler.sendCommand(DaliStandardCommand.createActivateCommand(address)); - + mirek = (int) (1E6f / (Math.min(Math.max(((DecimalType) command).intValue(), 1000), 20000))); + } else if (command instanceof QuantityType) { + // ensure it's in the correct units + QuantityType commandQuantity = ((QuantityType) command).toInvertibleUnit(Units.MIRED); + if (commandQuantity == null) { + logger.warn("Unable to convert command {} to mireks", command); + return; + } + mirek = commandQuantity.toBigDecimal().intValue(); + } else { + logger.warn("Unable to convert command {} to mireks", command); + return; } + final byte mirekLsb = (byte) (mirek & 0xff); + final byte mirekMsb = (byte) ((mirek >> 8) & 0xff); + // Write mirek value to the DTR0+DTR1 registers + daliHandler.sendCommand(DaliStandardCommand.createSetDTR0Command(mirekLsb)); + daliHandler.sendCommand(DaliStandardCommand.createSetDTR1Command(mirekMsb)); + // Indicate that the follwing command is a DT8 (WW/CW and single-channel RGB) command + daliHandler.sendCommand(DaliStandardCommand.createSetDeviceTypeCommand(8)); + // Set the color temperature to the value in DTR0+DTR1 + daliHandler.sendCommand(DaliStandardCommand.createSetColorTemperatureCommand(address)); + // Finish the command sequence + daliHandler.sendCommand(DaliStandardCommand.createSetDeviceTypeCommand(8)); + daliHandler.sendCommand(DaliStandardCommand.createActivateCommand(address)); + DaliAddress readAddress = address; if (readDeviceTargetId != null) { readAddress = DaliAddress.createShortAddress(readDeviceTargetId); @@ -103,9 +116,9 @@ public void handleCommand(ChannelUID channelUID, Command command) { if (msb != null && !msb.mask && lsb != null && !lsb.mask) { final int msbValue = msb.value != null ? msb.value : 0; final int lsbValue = lsb.value != null ? lsb.value : 0; - final int mirek = ((msbValue & 0xff) << 8) | (lsbValue & 0xff); - final int kelvin = (int) (1E6f / mirek); - updateState(channelUID, new DecimalType(kelvin)); + final int mirekState = ((msbValue & 0xff) << 8) | (lsbValue & 0xff); + final int kelvin = (int) (1E6f / mirekState); + updateState(channelUID, new QuantityType(kelvin, Units.KELVIN)); } }).exceptionally(e -> { logger.warn("Error querying device status: {}", e.getMessage());