diff --git a/bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/LightThingHandler.java b/bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/LightThingHandler.java
index 0f9b0bf2678..3cd2a1aab7e 100644
--- a/bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/LightThingHandler.java
+++ b/bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/LightThingHandler.java
@@ -54,6 +54,7 @@ import org.openhab.core.types.CommandOption;
import org.openhab.core.types.RefreshType;
import org.openhab.core.types.StateDescriptionFragment;
import org.openhab.core.types.StateDescriptionFragmentBuilder;
+import org.openhab.core.types.UnDefType;
import org.openhab.core.util.ColorUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -255,6 +256,11 @@ public class LightThingHandler extends DeconzBaseThingHandler {
if (miredQuantity != null) {
newLightState.ct = constrainToRange(miredQuantity.intValue(), ctMin, ctMax);
newLightState.on = true;
+ Double transitiontime = config.transitiontime;
+ if (transitiontime != null) {
+ // value is in 1/10 seconds
+ newLightState.transitiontime = (int) Math.round(10 * transitiontime);
+ }
}
}
case CHANNEL_POSITION -> {
@@ -396,18 +402,8 @@ public class LightThingHandler extends DeconzBaseThingHandler {
case CHANNEL_SWITCH, CHANNEL_LOCK -> updateSwitchChannel(channelUID, on);
case CHANNEL_COLOR -> updateColorChannel(channelUID, newState);
case CHANNEL_BRIGHTNESS -> updatePercentTypeChannel(channelUID, newState.bri, newState.on);
- case CHANNEL_COLOR_TEMPERATURE -> {
- Integer ct = newState.ct;
- if (ct != null && ct >= ctMin && ct <= ctMax) {
- updateState(channelUID, new DecimalType(miredToKelvin(ct)));
- }
- }
- case CHANNEL_POSITION -> {
- Integer lift = newState.lift;
- if (lift != null) {
- updateState(channelUID, new PercentType(lift));
- }
- }
+ case CHANNEL_COLOR_TEMPERATURE -> updateColorTemperatureChannel(channelUID, newState);
+ case CHANNEL_POSITION -> updatePosition(channelUID, newState);
case CHANNEL_EFFECT -> updateStringChannel(channelUID, newState.effect);
case CHANNEL_EFFECT_SPEED -> updateDecimalTypeChannel(channelUID, newState.effectSpeed);
}
@@ -443,26 +439,85 @@ public class LightThingHandler extends DeconzBaseThingHandler {
}
}
+ /**
+ * Update the given {@link ChannelUID} depending on the given {@link LightState}. If the 'colorMode' is "xy"
+ * then update the channel with an {@link HSBType} built from the given CIE XY co-ordinates and brightness,
+ * otherwise if the 'colorMode' is not "ct" then update the channel with an {@link HSBType} from the given hue,
+ * saturation and brightness. In either case if the 'on' field is false then the brightness is set to zero.
+ * Furthermore if the color channel has been updated then cross-update the color temperature channel (if any)
+ * to {@link UnDefType.UNDEF} as well.
+ *
+ * @param channelUID the UID of the channel being updated.
+ * @param newState the new {@link LightState}
+ */
private void updateColorChannel(ChannelUID channelUID, LightState newState) {
Boolean on = newState.on;
Integer bri = newState.bri;
Integer hue = newState.hue;
Integer sat = newState.sat;
+ boolean ctChannelUpdate = false;
if (on != null && !on) {
- updateState(channelUID, OnOffType.OFF);
- } else if (bri != null && "xy".equals(newState.colormode)) {
+ bri = 0;
+ }
+
+ if (bri != null && "xy".equals(newState.colormode)) {
final double @Nullable [] xy = newState.xy;
if (xy != null && xy.length == 2) {
- double[] xyY = new double[3];
- xyY[0] = xy[0];
- xyY[1] = xy[1];
- xyY[2] = ((double) bri) / BRIGHTNESS_MAX;
- updateState(channelUID, ColorUtil.xyToHsb(xyY));
+ HSBType hsX = ColorUtil.xyToHsb(xy);
+ HSBType hsb = new HSBType(hsX.getHue(), hsX.getSaturation(), toPercentType(bri));
+ logger.trace("updateColorChannel(xy) channelUID:{}, hsb:{}", channelUID, hsb);
+ updateState(channelUID, hsb);
+ ctChannelUpdate = true;
}
- } else if (bri != null && hue != null && sat != null) {
- updateState(channelUID,
- new HSBType(new DecimalType(hue / HUE_FACTOR), toPercentType(sat), toPercentType(bri)));
+ } else if (bri != null && !"ct".equals(newState.colormode) && hue != null && sat != null) {
+ HSBType hsb = new HSBType(new DecimalType(hue / HUE_FACTOR), toPercentType(sat), toPercentType(bri));
+ logger.trace("updateColorChannel(hsb) channelUID:{}, hsb:{}", channelUID, hsb);
+ updateState(channelUID, hsb);
+ ctChannelUpdate = true;
+ }
+
+ // cross-update the color temperature channel (if any)
+ if (ctChannelUpdate && thing.getChannel(CHANNEL_COLOR_TEMPERATURE) instanceof Channel ctChannel) {
+ logger.trace("updateColorTemperatureChannel() channelUID:{}, ct:UNDEF", ctChannel.getUID());
+ updateState(ctChannel.getUID(), UnDefType.UNDEF);
+ }
+ }
+
+ /**
+ * Update the given {@link ChannelUID} depending on the given {@link LightState}. If the 'colorMode' is "ct" and
+ * there is a 'ct' value (in mired) then convert it to Kelvin and update the channel. If the color temperature
+ * channel state has been updated then cross-update the color channel (if any) state to an {@link HSBType} that
+ * matches the given Kelvin value on the "Planckian Locus" on the CIE color chart as well.
+ *
+ * @param channelUID the UID of the channel being updated.
+ * @param newState the new {@link LightState}
+ */
+ private void updateColorTemperatureChannel(ChannelUID channelUID, LightState newState) {
+ Integer ct = newState.ct;
+ String colorMode = newState.colormode;
+ if ((colorMode == null || "ct".equals(colorMode)) && ct != null && ct >= ctMin && ct <= ctMax) {
+ int kelvin = miredToKelvin(ct);
+ logger.trace("updateColorTemperatureChannel() channelUID:{}, kelvin:{}", channelUID, kelvin);
+ updateState(channelUID, QuantityType.valueOf(kelvin, Units.KELVIN));
+
+ // cross-update the color channel (if any)
+ if (thing.getChannel(CHANNEL_COLOR) instanceof Channel colChannel) {
+ int brightness = !Boolean.TRUE.equals(newState.on) ? 0 : newState.bri instanceof Integer bri ? bri : -1;
+ if (brightness >= 0) {
+ HSBType hsX = ColorUtil.xyToHsb(ColorUtil.kelvinToXY(kelvin));
+ HSBType hsb = new HSBType(hsX.getHue(), hsX.getSaturation(), toPercentType(brightness));
+ logger.trace("updateColorChannel() channelUID:{}, hsb:{}", colChannel.getUID(), hsb);
+ updateState(colChannel.getUID(), hsb);
+ }
+ }
+ }
+ }
+
+ private void updatePosition(ChannelUID channelUID, LightState newState) {
+ Integer lift = newState.lift;
+ if (lift != null) {
+ updateState(channelUID, new PercentType(lift));
}
}
}
diff --git a/bundles/org.openhab.binding.deconz/src/main/resources/OH-INF/thing/group-thing-types.xml b/bundles/org.openhab.binding.deconz/src/main/resources/OH-INF/thing/group-thing-types.xml
index 87adc835222..06dba8331ac 100644
--- a/bundles/org.openhab.binding.deconz/src/main/resources/OH-INF/thing/group-thing-types.xml
+++ b/bundles/org.openhab.binding.deconz/src/main/resources/OH-INF/thing/group-thing-types.xml
@@ -10,6 +10,7 @@
Lightbulb
+ Zone
diff --git a/bundles/org.openhab.binding.deconz/src/main/resources/OH-INF/thing/light-thing-types.xml b/bundles/org.openhab.binding.deconz/src/main/resources/OH-INF/thing/light-thing-types.xml
index 4e4a0442ecf..0f408dd948d 100644
--- a/bundles/org.openhab.binding.deconz/src/main/resources/OH-INF/thing/light-thing-types.xml
+++ b/bundles/org.openhab.binding.deconz/src/main/resources/OH-INF/thing/light-thing-types.xml
@@ -69,9 +69,15 @@
LightSource
-
-
-
+
+ veto
+
+
+ veto
+
+
+ veto
+
@@ -93,10 +99,18 @@
LightSource
-
-
-
-
+
+ veto
+
+
+ veto
+
+
+ veto
+
+
+ veto
+
@@ -118,9 +132,15 @@
LightSource
-
-
-
+
+ veto
+
+
+ veto
+
+
+ veto
+
@@ -142,10 +162,18 @@
LightSource
-
-
-
-
+
+ veto
+
+
+ veto
+
+
+ veto
+
+
+ veto
+
@@ -181,7 +209,7 @@
Rollershutter
Control
- OpenState
+ OpenLevel
@@ -197,7 +225,7 @@
String
- Status
+ Control
Mode
@@ -216,6 +244,10 @@
String
Alarm
+
+ Control
+ Mode
+
@@ -228,6 +260,10 @@
Switch
+
+ Switch
+ OpenState
+
diff --git a/bundles/org.openhab.binding.deconz/src/main/resources/OH-INF/thing/sensor-channel-types.xml b/bundles/org.openhab.binding.deconz/src/main/resources/OH-INF/thing/sensor-channel-types.xml
index 035187402ab..c95f8d404c4 100644
--- a/bundles/org.openhab.binding.deconz/src/main/resources/OH-INF/thing/sensor-channel-types.xml
+++ b/bundles/org.openhab.binding.deconz/src/main/resources/OH-INF/thing/sensor-channel-types.xml
@@ -9,6 +9,10 @@
Current air quality level based on volatile organic compounds (VOCs) measurement. Example: good or poor,
...
+
+ Status
+ VOC
+
@@ -17,6 +21,10 @@
Current air quality based on measurements of volatile organic compounds (VOCs). The measured value is
specified in ppb (parts per billion).
+
+ Status
+ VOC
+
@@ -24,6 +32,9 @@
Switch
Alarm was triggered.
+
+ Alarm
+
@@ -46,6 +57,10 @@
Switch
Carbon-monoxide was detected.
+
+ Alarm
+ CO
+
@@ -54,6 +69,10 @@
Current consumption
Energy
+
+ Measurement
+ Energy
+
@@ -62,6 +81,10 @@
Current current
Energy
+
+ Measurement
+ Current
+
@@ -82,12 +105,20 @@
Contact
+
+ Status
+ OpenState
+
Switch
A fire was detected.
+
+ Alarm
+ Smoke
+
@@ -122,6 +153,10 @@
Target temperature
Heating
+
+ Setpoint
+ Temperature
+
@@ -130,6 +165,10 @@
Current humidity
Humidity
+
+ Measurement
+ Humidity
+
@@ -152,6 +191,10 @@
String
+
+ Status
+ Illuminance
+
@@ -165,6 +208,10 @@
Number:Illuminance
Current light illuminance
+
+ Measurement
+ Illuminance
+
@@ -172,6 +219,10 @@
Number
Current light level.
+
+ Measurement
+ Illuminance
+
@@ -180,6 +231,10 @@
Status of this thermostat's child lock.
Lock
+
+ Status
+ OpenState
+
@@ -187,6 +242,10 @@
Current mode
Heating
+
+ Control
+ Mode
+
@@ -200,6 +259,10 @@
Number:Dimensionless
Current moisture
+
+ Measurement
+ Moisture
+
@@ -213,6 +276,10 @@
Switch
+
+ Switch
+ Heating
+
@@ -220,6 +287,10 @@
Contact
Open/Close detected
+
+ Status
+ OpenState
+
@@ -246,6 +317,10 @@
Current power usage
Energy
+
+ Measurement
+ Power
+
@@ -254,6 +329,10 @@
Current pressure
Pressure
+
+ Measurement
+ Pressure
+
@@ -261,6 +340,10 @@
Switch
A zone is being tampered.
+
+ Alarm
+ Tampered
+
@@ -269,6 +352,10 @@
Current temperature
Temperature
+
+ Measurement
+ Temperature
+
@@ -289,6 +376,10 @@
Number:Dimensionless
Current valve position
+
+ Status
+ OpenLevel
+
@@ -296,6 +387,10 @@
Switch
Vibration was detected.
+
+ Status
+ Vibration
+
@@ -311,6 +406,10 @@
Current voltage
Energy
+
+ Measurement
+ Voltage
+
@@ -318,12 +417,20 @@
Switch
Water leakage detected
+
+ Alarm
+ Water
+
Contact
+
+ Status
+ OpenState
+
diff --git a/bundles/org.openhab.binding.deconz/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.deconz/src/main/resources/OH-INF/thing/thing-types.xml
index 09292a8a7e8..5e87dab2d82 100644
--- a/bundles/org.openhab.binding.deconz/src/main/resources/OH-INF/thing/thing-types.xml
+++ b/bundles/org.openhab.binding.deconz/src/main/resources/OH-INF/thing/thing-types.xml
@@ -7,7 +7,7 @@
A running deCONZ software instance.
- WebService
+ Application
UDN
diff --git a/bundles/org.openhab.binding.deconz/src/test/java/org/openhab/binding/deconz/LightsTest.java b/bundles/org.openhab.binding.deconz/src/test/java/org/openhab/binding/deconz/LightsTest.java
index 5a914f8b758..f8abdda4eb7 100644
--- a/bundles/org.openhab.binding.deconz/src/test/java/org/openhab/binding/deconz/LightsTest.java
+++ b/bundles/org.openhab.binding.deconz/src/test/java/org/openhab/binding/deconz/LightsTest.java
@@ -26,6 +26,7 @@ import org.eclipse.jdt.annotation.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
@@ -37,8 +38,10 @@ import org.openhab.binding.deconz.internal.types.LightType;
import org.openhab.binding.deconz.internal.types.LightTypeDeserializer;
import org.openhab.binding.deconz.internal.types.ThermostatMode;
import org.openhab.binding.deconz.internal.types.ThermostatModeGsonTypeAdapter;
-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.Bridge;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
@@ -46,6 +49,7 @@ import org.openhab.core.thing.ThingUID;
import org.openhab.core.thing.binding.ThingHandlerCallback;
import org.openhab.core.thing.binding.builder.ChannelBuilder;
import org.openhab.core.thing.binding.builder.ThingBuilder;
+import org.openhab.core.types.UnDefType;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@@ -64,6 +68,22 @@ public class LightsTest {
private @Mock @NonNullByDefault({}) DeconzDynamicStateDescriptionProvider stateDescriptionProvider;
private @Mock @NonNullByDefault({}) DeconzDynamicCommandDescriptionProvider commandDescriptionProvider;
+ /**
+ * Custom Mockito {@link ArgumentMatcher} to compare the closeness of two {@link HSBType} values.
+ */
+ private static class CloseToHSBType implements ArgumentMatcher {
+ private HSBType target;
+
+ public CloseToHSBType(HSBType target) {
+ this.target = target;
+ }
+
+ @Override
+ public boolean matches(HSBType source) {
+ return source.closeTo(target, 0.02);
+ }
+ }
+
@BeforeEach
public void initialize() {
GsonBuilder gsonBuilder = new GsonBuilder();
@@ -72,6 +92,75 @@ public class LightsTest {
gson = gsonBuilder.create();
}
+ @Test
+ public void extColorTemperatureLightUpdateHSBTest() throws IOException {
+ LightMessage lightMessage = DeconzTest.getObjectFromJson("extended_hsb.json", LightMessage.class, gson);
+ assertNotNull(lightMessage);
+
+ ThingUID thingUID = new ThingUID("deconz", "light");
+ ChannelUID channelUIDColor = new ChannelUID(thingUID, CHANNEL_COLOR);
+ ChannelUID channelUIDCt = new ChannelUID(thingUID, CHANNEL_COLOR_TEMPERATURE);
+
+ Thing light = ThingBuilder.create(THING_TYPE_COLOR_TEMPERATURE_LIGHT, thingUID)
+ .withProperties(Map.of(PROPERTY_THING_TYPE_VERSION, "1"))
+ .withChannel(ChannelBuilder.create(channelUIDColor, "Color").build())
+ .withChannel(ChannelBuilder.create(channelUIDCt, "Number").build()).build();
+ LightThingHandler lightThingHandler = new LightThingHandler(light, gson, stateDescriptionProvider,
+ commandDescriptionProvider);
+ lightThingHandler.setCallback(thingHandlerCallback);
+
+ lightThingHandler.messageReceived(lightMessage);
+ Mockito.verify(thingHandlerCallback).stateUpdated(eq(channelUIDColor), eq(new HSBType("0,50,100")));
+ Mockito.verify(thingHandlerCallback).stateUpdated(eq(channelUIDCt), eq(UnDefType.UNDEF));
+ }
+
+ @Test
+ public void extColorTemperatureLightUpdateXYTest() throws IOException {
+ LightMessage lightMessage = DeconzTest.getObjectFromJson("extended_xy.json", LightMessage.class, gson);
+ assertNotNull(lightMessage);
+
+ ThingUID thingUID = new ThingUID("deconz", "light");
+ ChannelUID channelUIDColor = new ChannelUID(thingUID, CHANNEL_COLOR);
+ ChannelUID channelUIDCt = new ChannelUID(thingUID, CHANNEL_COLOR_TEMPERATURE);
+
+ Thing light = ThingBuilder.create(THING_TYPE_COLOR_TEMPERATURE_LIGHT, thingUID)
+ .withProperties(Map.of(PROPERTY_THING_TYPE_VERSION, "1"))
+ .withChannel(ChannelBuilder.create(channelUIDColor, "Color").build())
+ .withChannel(ChannelBuilder.create(channelUIDCt, "Number").build()).build();
+ LightThingHandler lightThingHandler = new LightThingHandler(light, gson, stateDescriptionProvider,
+ commandDescriptionProvider);
+ lightThingHandler.setCallback(thingHandlerCallback);
+
+ lightThingHandler.messageReceived(lightMessage);
+ Mockito.verify(thingHandlerCallback).stateUpdated(eq(channelUIDColor),
+ argThat(new CloseToHSBType(new HSBType("357,100,50"))));
+ Mockito.verify(thingHandlerCallback).stateUpdated(eq(channelUIDCt), eq(UnDefType.UNDEF));
+ }
+
+ @Test
+ public void extColorTemperatureLightUpdateCTTest() throws IOException {
+ LightMessage lightMessage = DeconzTest.getObjectFromJson("extended_ct.json", LightMessage.class, gson);
+ assertNotNull(lightMessage);
+
+ ThingUID thingUID = new ThingUID("deconz", "light");
+ ChannelUID channelUIDColor = new ChannelUID(thingUID, CHANNEL_COLOR);
+ ChannelUID channelUIDCt = new ChannelUID(thingUID, CHANNEL_COLOR_TEMPERATURE);
+
+ Thing light = ThingBuilder.create(THING_TYPE_COLOR_TEMPERATURE_LIGHT, thingUID)
+ .withProperties(Map.of(PROPERTY_THING_TYPE_VERSION, "1"))
+ .withChannel(ChannelBuilder.create(channelUIDColor, "Color").build())
+ .withChannel(ChannelBuilder.create(channelUIDCt, "Number").build()).build();
+ LightThingHandler lightThingHandler = new LightThingHandler(light, gson, stateDescriptionProvider,
+ commandDescriptionProvider);
+ lightThingHandler.setCallback(thingHandlerCallback);
+
+ lightThingHandler.messageReceived(lightMessage);
+ Mockito.verify(thingHandlerCallback).stateUpdated(eq(channelUIDColor),
+ argThat(new CloseToHSBType(new HSBType("43,26,50"))));
+ Mockito.verify(thingHandlerCallback).stateUpdated(eq(channelUIDCt),
+ eq(QuantityType.valueOf(4000, Units.KELVIN)));
+ }
+
@Test
public void colorTemperatureLightUpdateTest() throws IOException {
LightMessage lightMessage = DeconzTest.getObjectFromJson("colortemperature.json", LightMessage.class, gson);
@@ -91,7 +180,32 @@ public class LightsTest {
lightThingHandler.messageReceived(lightMessage);
Mockito.verify(thingHandlerCallback).stateUpdated(eq(channelUIDBri), eq(new PercentType("21")));
- Mockito.verify(thingHandlerCallback).stateUpdated(eq(channelUIDCt), eq(new DecimalType("2500")));
+ Mockito.verify(thingHandlerCallback).stateUpdated(eq(channelUIDCt),
+ eq(QuantityType.valueOf(2500, Units.KELVIN)));
+ }
+
+ @Test
+ public void colorTemperatureSparseLightUpdateTest() throws IOException {
+ LightMessage lightMessage = DeconzTest.getObjectFromJson("colortemperature-sparse.json", LightMessage.class,
+ gson);
+ assertNotNull(lightMessage);
+
+ ThingUID thingUID = new ThingUID("deconz", "light");
+ ChannelUID channelUIDBri = new ChannelUID(thingUID, CHANNEL_BRIGHTNESS);
+ ChannelUID channelUIDCt = new ChannelUID(thingUID, CHANNEL_COLOR_TEMPERATURE);
+
+ Thing light = ThingBuilder.create(THING_TYPE_COLOR_TEMPERATURE_LIGHT, thingUID)
+ .withProperties(Map.of(PROPERTY_THING_TYPE_VERSION, "1"))
+ .withChannel(ChannelBuilder.create(channelUIDBri, "Dimmer").build())
+ .withChannel(ChannelBuilder.create(channelUIDCt, "Number").build()).build();
+ LightThingHandler lightThingHandler = new LightThingHandler(light, gson, stateDescriptionProvider,
+ commandDescriptionProvider);
+ lightThingHandler.setCallback(thingHandlerCallback);
+
+ lightThingHandler.messageReceived(lightMessage);
+ Mockito.verify(thingHandlerCallback).stateUpdated(eq(channelUIDBri), eq(new PercentType("21")));
+ Mockito.verify(thingHandlerCallback).stateUpdated(eq(channelUIDCt),
+ eq(QuantityType.valueOf(2500, Units.KELVIN)));
}
@Test
diff --git a/bundles/org.openhab.binding.deconz/src/test/resources/org/openhab/binding/deconz/colortemperature-sparse.json b/bundles/org.openhab.binding.deconz/src/test/resources/org/openhab/binding/deconz/colortemperature-sparse.json
new file mode 100644
index 00000000000..86bc43b5f6e
--- /dev/null
+++ b/bundles/org.openhab.binding.deconz/src/test/resources/org/openhab/binding/deconz/colortemperature-sparse.json
@@ -0,0 +1,14 @@
+{
+ "e": "changed",
+ "id": "3",
+ "r": "lights",
+ "state": {
+ "alert": null,
+ "bri": 51,
+ "ct": 400,
+ "on": true,
+ "reachable": true
+ },
+ "t": "event",
+ "uniqueid": "00:0b:57:ff:fe:eb:2f:84-01"
+}
diff --git a/bundles/org.openhab.binding.deconz/src/test/resources/org/openhab/binding/deconz/extended_ct.json b/bundles/org.openhab.binding.deconz/src/test/resources/org/openhab/binding/deconz/extended_ct.json
new file mode 100644
index 00000000000..a21b66632f5
--- /dev/null
+++ b/bundles/org.openhab.binding.deconz/src/test/resources/org/openhab/binding/deconz/extended_ct.json
@@ -0,0 +1,22 @@
+{
+ "e": "changed",
+ "id": "11",
+ "r": "lights",
+ "state": {
+ "alert": "none",
+ "bri": 127,
+ "colormode": "ct",
+ "ct": 250,
+ "effect": "none",
+ "hue": 0,
+ "on": true,
+ "reachable": true,
+ "sat": 125,
+ "xy": [
+ 0.6981,
+ 0.298
+ ]
+ },
+ "t": "event",
+ "uniqueid": "a4:c1:38:89:fb:f3:c5:a3-0b"
+}
diff --git a/bundles/org.openhab.binding.deconz/src/test/resources/org/openhab/binding/deconz/extended_hsb.json b/bundles/org.openhab.binding.deconz/src/test/resources/org/openhab/binding/deconz/extended_hsb.json
new file mode 100644
index 00000000000..af58e6ad6b2
--- /dev/null
+++ b/bundles/org.openhab.binding.deconz/src/test/resources/org/openhab/binding/deconz/extended_hsb.json
@@ -0,0 +1,22 @@
+{
+ "e": "changed",
+ "id": "11",
+ "r": "lights",
+ "state": {
+ "alert": "none",
+ "bri": 254,
+ "colormode": "hs",
+ "ct": 250,
+ "effect": "none",
+ "hue": 0,
+ "on": true,
+ "reachable": true,
+ "sat": 125,
+ "xy": [
+ 0.6981,
+ 0.298
+ ]
+ },
+ "t": "event",
+ "uniqueid": "a4:c1:38:89:fb:f3:c5:a3-0b"
+}
diff --git a/bundles/org.openhab.binding.deconz/src/test/resources/org/openhab/binding/deconz/extended_xy.json b/bundles/org.openhab.binding.deconz/src/test/resources/org/openhab/binding/deconz/extended_xy.json
new file mode 100644
index 00000000000..e8bc069b2e8
--- /dev/null
+++ b/bundles/org.openhab.binding.deconz/src/test/resources/org/openhab/binding/deconz/extended_xy.json
@@ -0,0 +1,22 @@
+{
+ "e": "changed",
+ "id": "11",
+ "r": "lights",
+ "state": {
+ "alert": "none",
+ "bri": 127,
+ "colormode": "xy",
+ "ct": 250,
+ "effect": "none",
+ "hue": 0,
+ "on": true,
+ "reachable": true,
+ "sat": 125,
+ "xy": [
+ 0.6981,
+ 0.298
+ ]
+ },
+ "t": "event",
+ "uniqueid": "a4:c1:38:89:fb:f3:c5:a3-0b"
+}