From 2bafc45cfbf9b503f209c672a3561f951fe5879e Mon Sep 17 00:00:00 2001 From: Cody Cutrer Date: Fri, 23 Dec 2022 16:00:57 -0700 Subject: [PATCH] [lifx] Handle and provide QuantityType for color-temperature-abs channel (#14025) See https://github.com/openhab/openhab-core/pull/3129 Signed-off-by: Cody Cutrer Signed-off-by: Doug Culnane --- bundles/org.openhab.binding.lifx/README.md | 42 +++++++++---------- .../internal/handler/LifxLightHandler.java | 21 ++++++---- .../lifx/internal/util/LifxMessageUtil.java | 27 ++++++++++-- 3 files changed, 58 insertions(+), 32 deletions(-) diff --git a/bundles/org.openhab.binding.lifx/README.md b/bundles/org.openhab.binding.lifx/README.md index 1a2a9dd4a71e4..105ddb8d8071a 100644 --- a/bundles/org.openhab.binding.lifx/README.md +++ b/bundles/org.openhab.binding.lifx/README.md @@ -85,19 +85,19 @@ Thing lifx:colorirlight:porch [ host="10.120.130.4", fadetime=0 ] All devices support some of the following channels: -| Channel Type ID | Item Type | Description | Thing Types | -|--------------------|-----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------| -| abstemperature | Number | This channel supports adjusting the color temperature in Kelvin. | colorlight, colorhevlight, colorirlight, colormzlight, tilelight, whitelight | -| abstemperaturezone | Number | This channel supports adjusting the zone color temperature in Kelvin. | colormzlight | -| brightness | Dimmer | This channel supports adjusting the brightness value. | whitelight | -| color | Color | This channel supports full color control with hue, saturation and brightness values. | colorlight, colorhevlight, colorirlight, colormzlight, tilelight | -| colorzone | Color | This channel supports full zone color control with hue, saturation and brightness values. | colormzlight | -| effect | String | This channel represents a type of light effect (e.g. for tile light: off, morph, flame) | tilelight | -| hevcycle | Switch | This channel supports starting and stopping the HEV clean cycle. | colorhevlight | -| infrared | Dimmer | This channel supports adjusting the infrared value. _Note:_ IR capable lights only activate their infrared LEDs when the brightness drops below a certain level. | colorirlight | -| signalstrength | Number | This channel represents signal strength with values 0, 1, 2, 3 or 4; 0 being worst strength and 4 being best strength. | colorlight, colorhevlight, colorirlight, colormzlight, tilelight, whitelight | -| temperature | Dimmer | This channel supports adjusting the color temperature from cold (0%) to warm (100%). | colorlight, colorhevlight, colorirlight, colormzlight, tilelight, whitelight | -| temperaturezone | Dimmer | This channel supports adjusting the zone color temperature from cold (0%) to warm (100%). | colormzlight | +| Channel Type ID | Item Type | Description | Thing Types | +|--------------------|--------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------| +| abstemperature | Number:Temperature | This channel supports adjusting the color temperature in Kelvin. | colorlight, colorhevlight, colorirlight, colormzlight, tilelight, whitelight | +| abstemperaturezone | Number:Temperature | This channel supports adjusting the zone color temperature in Kelvin. | colormzlight | +| brightness | Dimmer | This channel supports adjusting the brightness value. | whitelight | +| color | Color | This channel supports full color control with hue, saturation and brightness values. | colorlight, colorhevlight, colorirlight, colormzlight, tilelight | +| colorzone | Color | This channel supports full zone color control with hue, saturation and brightness values. | colormzlight | +| effect | String | This channel represents a type of light effect (e.g. for tile light: off, morph, flame) | tilelight | +| hevcycle | Switch | This channel supports starting and stopping the HEV clean cycle. | colorhevlight | +| infrared | Dimmer | This channel supports adjusting the infrared value. _Note:_ IR capable lights only activate their infrared LEDs when the brightness drops below a certain level. | colorirlight | +| signalstrength | Number | This channel represents signal strength with values 0, 1, 2, 3 or 4; 0 being worst strength and 4 being best strength. | colorlight, colorhevlight, colorirlight, colormzlight, tilelight, whitelight | +| temperature | Dimmer | This channel supports adjusting the color temperature from cold (0%) to warm (100%). | colorlight, colorhevlight, colorirlight, colormzlight, tilelight, whitelight | +| temperaturezone | Dimmer | This channel supports adjusting the zone color temperature from cold (0%) to warm (100%). | colormzlight | The _color_ and _brightness_ channels have a "Power On Brightness" configuration option that is used to determine the brightness when a light is switched on. When it is left empty, the brightness of a light remains unchanged when a light is switched on or off. @@ -175,44 +175,44 @@ Thing lifx:whitelight:kitchen [ deviceId="D073D5D4D4D4", fadetime=150 ] // Living Color Living_Color { channel="lifx:colorlight:living:color" } Dimmer Living_Temperature { channel="lifx:colorlight:living:temperature" } -Number Living_Abs_Temperature { channel="lifx:colorlight:living:abstemperature" } +Number:Temperature Living_Abs_Temperature "Living Room Lights Color Temperature [%d K]" { channel="lifx:colorlight:living:abstemperature" } // Living2 (alternative approach) Color Living2_Color { channel="lifx:colorlight:living2:color" } Switch Living2_Switch { channel="lifx:colorlight:living2:color" } Dimmer Living2_Dimmer { channel="lifx:colorlight:living2:color" } Dimmer Living2_Temperature { channel="lifx:colorlight:living2:temperature" } -Number Living2_Abs_Temperature { channel="lifx:colorlight:living2:abstemperature" } +Number:Temperature Living2_Abs_Temperature "Living Room Lights Color Temperature [%d K]" { channel="lifx:colorlight:living2:abstemperature" } // Desk Color Desk_Color { channel="lifx:colorhevlight:desk:color" } Dimmer Desk_Temperature { channel="lifx:colorhevlight:desk:temperature" } -Number Desk_Abs_Temperature { channel="lifx:colorhevlight:desk:abstemperature" } +Number:Temperature Desk_Abs_Temperature "Desk Lamp Color Temperature [%d K]" { channel="lifx:colorhevlight:desk:abstemperature" } Switch Desk_HEV_Cycle { channel="lifx:colorhevlight:desk:hevcycle" } // Porch Color Porch_Color { channel="lifx:colorirlight:porch:color" } Dimmer Porch_Infrared { channel="lifx:colorirlight:porch:infrared" } Dimmer Porch_Temperature { channel="lifx:colorirlight:porch:temperature" } -Number Porch_Abs_Temperature { channel="lifx:colorirlight:porch:abstemperature" } +Number:Temperature Porch_Abs_Temperature "Porch Light Color Temperature [%d K]" { channel="lifx:colorirlight:porch:abstemperature" } Number Porch_Signal_Strength { channel="lifx:colorirlight:porch:signalstrength" } // Ceiling Color Ceiling_Color { channel="lifx:colormzlight:ceiling:color" } Dimmer Ceiling_Temperature { channel="lifx:colormzlight:ceiling:temperature" } -Number Ceiling_Abs_Temperature { channel="lifx:colormzlight:ceiling:abstemperature" } +Number:Temperature Ceiling_Abs_Temperature "Ceiling Light Color Temperature [%d K]" { channel="lifx:colormzlight:ceiling:abstemperature" } Color Ceiling_Color_Zone_0 { channel="lifx:colormzlight:ceiling:colorzone0" } Dimmer Ceiling_Temperature_Zone_0 { channel="lifx:colormzlight:ceiling:temperaturezone0" } -Number Ceiling_Abs_Temperature_Zone_0 { channel="lifx:colormzlight:ceiling:abstemperaturezone0" } +Number:Temperature Ceiling_Abs_Temperature_Zone_0 "Ceiling Light 0 Color Temperature [%d K]" { channel="lifx:colormzlight:ceiling:abstemperaturezone0" } Color Ceiling_Color_Zone_15 { channel="lifx:colormzlight:ceiling:colorzone15" } Dimmer Ceiling_Temperature_Zone_15 { channel="lifx:colormzlight:ceiling:temperaturezone15" } -Number Ceiling_Abs_Temperature_Zone_15 { channel="lifx:colormzlight:ceiling:abstemperaturezone15" } +Number:Temperature Ceiling_Abs_Temperature_Zone_15 "Ceiling Light 15 Color Temperature [%d K]" { channel="lifx:colormzlight:ceiling:abstemperaturezone15" } // Kitchen Switch Kitchen_Toggle { channel="lifx:whitelight:kichen:brightness" } Dimmer Kitchen_Brightness { channel="lifx:whitelight:kitchen:brightness" } Dimmer Kitchen_Temperature { channel="lifx:whitelight:kitchen:temperature" } -Number Kitchen_Abs_Temperature { channel="lifx:whitelight:kitchen:abstemperature" } +Number:Temperature Kitchen_Abs_Temperature "Kitchen Light Color Temperature [%d K]" { channel="lifx:whitelight:kitchen:abstemperature" } ``` ### demo.sitemap: diff --git a/bundles/org.openhab.binding.lifx/src/main/java/org/openhab/binding/lifx/internal/handler/LifxLightHandler.java b/bundles/org.openhab.binding.lifx/src/main/java/org/openhab/binding/lifx/internal/handler/LifxLightHandler.java index 47d47787ed54f..1b0dd2df52cfb 100644 --- a/bundles/org.openhab.binding.lifx/src/main/java/org/openhab/binding/lifx/internal/handler/LifxLightHandler.java +++ b/bundles/org.openhab.binding.lifx/src/main/java/org/openhab/binding/lifx/internal/handler/LifxLightHandler.java @@ -61,7 +61,9 @@ import org.openhab.core.library.types.IncreaseDecreaseType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.PercentType; +import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.StringType; +import org.openhab.core.library.unit.Units; import org.openhab.core.thing.Channel; import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.Thing; @@ -182,7 +184,7 @@ private void updateColorChannels(@Nullable PowerState powerState, HSBK[] colors) updateStateIfChanged(CHANNEL_BRIGHTNESS, hsb.getBrightness()); updateStateIfChanged(CHANNEL_TEMPERATURE, kelvinToPercentType(updateColor.getKelvin(), features.getTemperatureRange())); - updateStateIfChanged(CHANNEL_ABS_TEMPERATURE, new DecimalType(updateColor.getKelvin())); + updateStateIfChanged(CHANNEL_ABS_TEMPERATURE, new QuantityType(updateColor.getKelvin(), Units.KELVIN)); updateZoneChannels(powerState, colors); } @@ -241,7 +243,8 @@ private void updateZoneChannels(@Nullable PowerState powerState, HSBK[] colors) updateStateIfChanged(CHANNEL_COLOR_ZONE + i, updateColor.getHSB()); updateStateIfChanged(CHANNEL_TEMPERATURE_ZONE + i, kelvinToPercentType(updateColor.getKelvin(), features.getTemperatureRange())); - updateStateIfChanged(CHANNEL_ABS_TEMPERATURE_ZONE + i, new DecimalType(updateColor.getKelvin())); + updateStateIfChanged(CHANNEL_ABS_TEMPERATURE_ZONE + i, + new QuantityType(updateColor.getKelvin(), Units.KELVIN)); } } } @@ -558,8 +561,9 @@ public void handleCommand(ChannelUID channelUID, Command command) { switch (channelUID.getId()) { case CHANNEL_ABS_TEMPERATURE: case CHANNEL_TEMPERATURE: - if (command instanceof DecimalType) { - return () -> handleTemperatureCommand((DecimalType) command); + if (command instanceof DecimalType || (command instanceof QuantityType + && ((QuantityType) command).toInvertibleUnit(Units.KELVIN) != null)) { + return () -> handleTemperatureCommand(command); } else if (command instanceof IncreaseDecreaseType) { return () -> handleIncreaseDecreaseTemperatureCommand((IncreaseDecreaseType) command); } @@ -599,8 +603,9 @@ public void handleCommand(ChannelUID channelUID, Command command) { try { if (channelUID.getId().startsWith(CHANNEL_ABS_TEMPERATURE_ZONE)) { int zoneIndex = Integer.parseInt(channelUID.getId().replace(CHANNEL_ABS_TEMPERATURE_ZONE, "")); - if (command instanceof DecimalType) { - return () -> handleTemperatureCommand((DecimalType) command, zoneIndex); + if (command instanceof DecimalType || (command instanceof QuantityType + && ((QuantityType) command).toInvertibleUnit(Units.KELVIN) != null)) { + return () -> handleTemperatureCommand(command, zoneIndex); } } else if (channelUID.getId().startsWith(CHANNEL_COLOR_ZONE)) { int zoneIndex = Integer.parseInt(channelUID.getId().replace(CHANNEL_COLOR_ZONE, "")); @@ -670,14 +675,14 @@ private void handleRefreshCommand(ChannelUID channelUID) { } } - private void handleTemperatureCommand(DecimalType temperature) { + private void handleTemperatureCommand(Command temperature) { HSBK newColor = getLightStateForCommand().getColor(); newColor.setSaturation(PercentType.ZERO); newColor.setKelvin(commandToKelvin(temperature, features.getTemperatureRange())); getLightStateForCommand().setColor(newColor); } - private void handleTemperatureCommand(DecimalType temperature, int zoneIndex) { + private void handleTemperatureCommand(Command temperature, int zoneIndex) { HSBK newColor = getLightStateForCommand().getColor(zoneIndex); newColor.setSaturation(PercentType.ZERO); newColor.setKelvin(commandToKelvin(temperature, features.getTemperatureRange())); diff --git a/bundles/org.openhab.binding.lifx/src/main/java/org/openhab/binding/lifx/internal/util/LifxMessageUtil.java b/bundles/org.openhab.binding.lifx/src/main/java/org/openhab/binding/lifx/internal/util/LifxMessageUtil.java index b250e47e008e9..928e0edc6d142 100644 --- a/bundles/org.openhab.binding.lifx/src/main/java/org/openhab/binding/lifx/internal/util/LifxMessageUtil.java +++ b/bundles/org.openhab.binding.lifx/src/main/java/org/openhab/binding/lifx/internal/util/LifxMessageUtil.java @@ -22,6 +22,9 @@ import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.IncreaseDecreaseType; 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.types.Command; /** * Utility class for sharing message utility methods between objects. @@ -102,9 +105,17 @@ public static PercentType kelvinToPercentType(int kelvin, TemperatureRange tempe return new PercentType(value); } - public static int commandToKelvin(DecimalType temperature, TemperatureRange temperatureRange) { - return temperature instanceof PercentType ? percentTypeToKelvin((PercentType) temperature, temperatureRange) - : decimalTypeToKelvin(temperature, temperatureRange); + public static int commandToKelvin(Command temperature, TemperatureRange temperatureRange) { + if (temperature instanceof PercentType) { + return percentTypeToKelvin((PercentType) temperature, temperatureRange); + } else if (temperature instanceof QuantityType) { + return quantityTypeToKelvin((QuantityType) temperature, temperatureRange); + } else if (temperature instanceof DecimalType) { + return decimalTypeToKelvin((DecimalType) temperature, temperatureRange); + } else { + throw new IllegalStateException( + "Unexpected command type " + temperature.getClass().getName() + " for color temperature command."); + } } public static int decimalTypeToKelvin(DecimalType temperature, TemperatureRange temperatureRange) { @@ -117,6 +128,16 @@ public static int percentTypeToKelvin(PercentType temperature, TemperatureRange temperatureRange.getMaximum() - (temperature.floatValue() * (temperatureRange.getRange() / 100))); } + public static int quantityTypeToKelvin(QuantityType temperature, TemperatureRange temperatureRange) { + QuantityType asKelvin = temperature.toInvertibleUnit(Units.KELVIN); + if (asKelvin == null) { + throw new IllegalStateException( + "Cannot convert color temperature " + temperature.toString() + " to Kelvin"); + } + + return asKelvin.intValue(); + } + public static PercentType infraredToPercentType(int infrared) { return intToPercentType(infrared); }