[dali] handle and provide QuantityType for color-temperature-abs channel (#14021)

see openhab/openhab-core#3129

Signed-off-by: Cody Cutrer <cody@cutrer.us>
This commit is contained in:
Cody Cutrer 2022-12-20 13:15:10 -07:00 committed by GitHub
parent 4d98cca7eb
commit 324483d8e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -28,6 +28,8 @@ import org.openhab.binding.dali.internal.protocol.DaliStandardCommand;
import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.HSBType; import org.openhab.core.library.types.HSBType;
import org.openhab.core.library.types.PercentType; 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.ChannelUID;
import org.openhab.core.thing.Thing; import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus; import org.openhab.core.thing.ThingStatus;
@ -62,26 +64,37 @@ public class DaliDt8DeviceHandler extends DaliDeviceHandler {
} else { } else {
throw new DaliException("unknown device type"); throw new DaliException("unknown device type");
} }
int mirek;
if (command instanceof DecimalType) { if (command instanceof DecimalType) {
// Color temperature in DALI is represented in mirek ("reciprocal megakelvin") // Color temperature in DALI is represented in mirek ("reciprocal megakelvin")
// It is one million times the reciprocal of the color temperature (in Kelvin) // It is one million times the reciprocal of the color temperature (in Kelvin)
final int mirek = (int) (1E6f mirek = (int) (1E6f / (Math.min(Math.max(((DecimalType) command).intValue(), 1000), 20000)));
/ (Math.min(Math.max(((DecimalType) command).intValue(), 1000), 20000))); } else if (command instanceof QuantityType) {
final byte mirekLsb = (byte) (mirek & 0xff); // ensure it's in the correct units
final byte mirekMsb = (byte) ((mirek >> 8) & 0xff); QuantityType<?> commandQuantity = ((QuantityType) command).toInvertibleUnit(Units.MIRED);
// Write mirek value to the DTR0+DTR1 registers if (commandQuantity == null) {
daliHandler.sendCommand(DaliStandardCommand.createSetDTR0Command(mirekLsb)); logger.warn("Unable to convert command {} to mireks", command);
daliHandler.sendCommand(DaliStandardCommand.createSetDTR1Command(mirekMsb)); return;
// Indicate that the follwing command is a DT8 (WW/CW and single-channel RGB) command }
daliHandler.sendCommand(DaliStandardCommand.createSetDeviceTypeCommand(8)); mirek = commandQuantity.toBigDecimal().intValue();
// Set the color temperature to the value in DTR0+DTR1 } else {
daliHandler.sendCommand(DaliStandardCommand.createSetColorTemperatureCommand(address)); logger.warn("Unable to convert command {} to mireks", command);
// Finish the command sequence return;
daliHandler.sendCommand(DaliStandardCommand.createSetDeviceTypeCommand(8));
daliHandler.sendCommand(DaliStandardCommand.createActivateCommand(address));
} }
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; DaliAddress readAddress = address;
if (readDeviceTargetId != null) { if (readDeviceTargetId != null) {
readAddress = DaliAddress.createShortAddress(readDeviceTargetId); readAddress = DaliAddress.createShortAddress(readDeviceTargetId);
@ -103,9 +116,9 @@ public class DaliDt8DeviceHandler extends DaliDeviceHandler {
if (msb != null && !msb.mask && lsb != null && !lsb.mask) { if (msb != null && !msb.mask && lsb != null && !lsb.mask) {
final int msbValue = msb.value != null ? msb.value : 0; final int msbValue = msb.value != null ? msb.value : 0;
final int lsbValue = lsb.value != null ? lsb.value : 0; final int lsbValue = lsb.value != null ? lsb.value : 0;
final int mirek = ((msbValue & 0xff) << 8) | (lsbValue & 0xff); final int mirekState = ((msbValue & 0xff) << 8) | (lsbValue & 0xff);
final int kelvin = (int) (1E6f / mirek); final int kelvin = (int) (1E6f / mirekState);
updateState(channelUID, new DecimalType(kelvin)); updateState(channelUID, new QuantityType(kelvin, Units.KELVIN));
} }
}).exceptionally(e -> { }).exceptionally(e -> {
logger.warn("Error querying device status: {}", e.getMessage()); logger.warn("Error querying device status: {}", e.getMessage());