diff --git a/extensions/binding/org.eclipse.smarthome.binding.tradfri/ESH-INF/thing/thing-types.xml b/extensions/binding/org.eclipse.smarthome.binding.tradfri/ESH-INF/thing/thing-types.xml
index 4292bf656b9..3d81d2e9d6f 100644
--- a/extensions/binding/org.eclipse.smarthome.binding.tradfri/ESH-INF/thing/thing-types.xml
+++ b/extensions/binding/org.eclipse.smarthome.binding.tradfri/ESH-INF/thing/thing-types.xml
@@ -70,6 +70,26 @@
+
+
+
+
+
+
+ A group of Tradfri lamps
+
+
+
+
+
+
+
+
+ The identifier of the group on the gateway
+
+
+
+
@@ -107,5 +127,11 @@
Control the color temperature of the light.
ColorLight
-
+
+
+ Switch
+
+ Allows to switch on or off all lamps in a group.
+
+
diff --git a/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/TradfriBindingConstants.java b/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/TradfriBindingConstants.java
index 63815deda64..9d948fea743 100644
--- a/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/TradfriBindingConstants.java
+++ b/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/TradfriBindingConstants.java
@@ -29,6 +29,8 @@ public class TradfriBindingConstants {
public final static ThingTypeUID THING_TYPE_DIMMABLE_LIGHT = new ThingTypeUID(BINDING_ID, "0100");
public final static ThingTypeUID THING_TYPE_COLOR_TEMP_LIGHT = new ThingTypeUID(BINDING_ID, "0220");
public final static ThingTypeUID THING_TYPE_DIMMER = new ThingTypeUID(BINDING_ID, "0820");
+ // Grouped lights (and maybe in the future other devices)
+ public final static ThingTypeUID THING_TYPE_GROUP = new ThingTypeUID(BINDING_ID, "group");
public static final Set SUPPORTED_LIGHT_TYPES_UIDS = ImmutableSet.of(THING_TYPE_DIMMABLE_LIGHT,
THING_TYPE_COLOR_TEMP_LIGHT);
@@ -39,6 +41,7 @@ public class TradfriBindingConstants {
// List of all Channel IDs
public static final String CHANNEL_BRIGHTNESS = "brightness";
public static final String CHANNEL_COLOR_TEMPERATURE = "color_temperature";
+ public static final String CHANNEL_GROUP_STATE = "group_state";
// IPSO Objects
public static final String DEVICES = "15001";
diff --git a/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/handler/TradfriGatewayHandler.java b/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/handler/TradfriGatewayHandler.java
index a7f2aca47e6..0cfb5cbfa61 100644
--- a/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/handler/TradfriGatewayHandler.java
+++ b/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/handler/TradfriGatewayHandler.java
@@ -7,7 +7,7 @@
*/
package org.eclipse.smarthome.binding.tradfri.handler;
-import static org.eclipse.smarthome.binding.tradfri.TradfriBindingConstants.DEVICES;
+import static org.eclipse.smarthome.binding.tradfri.TradfriBindingConstants.*;
import java.io.IOException;
import java.net.InetSocketAddress;
@@ -48,13 +48,13 @@
* sent to one of the channels.
*
* @author Kai Kreuzer - Initial contribution
+ * @author Mario Smit - Group Handler added
*/
-public class TradfriGatewayHandler extends BaseBridgeHandler implements CoapCallback {
+public class TradfriGatewayHandler extends BaseBridgeHandler {
private final Logger logger = LoggerFactory.getLogger(TradfriGatewayHandler.class);
- private TradfriCoapClient deviceClient;
- private String gatewayURI;
+ public TradfriCoapCallback devices, groups;
private DTLSConnector dtlsConnector;
private CoapEndpoint endPoint;
@@ -85,27 +85,47 @@ public void initialize() {
return;
}
- this.gatewayURI = "coaps://" + configuration.host + ":" + configuration.port + "/" + DEVICES;
- try {
- URI uri = new URI(gatewayURI);
- deviceClient = new TradfriCoapClient(uri);
- } catch (URISyntaxException e) {
- logger.debug("Illegal gateway URI `{}`: {}", gatewayURI, e.getMessage());
- updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
- return;
- }
-
DtlsConnectorConfig.Builder builder = new DtlsConnectorConfig.Builder(new InetSocketAddress(0));
builder.setPskStore(new StaticPskStore("", configuration.code.getBytes()));
dtlsConnector = new DTLSConnector(builder.build());
endPoint = new CoapEndpoint(dtlsConnector, NetworkConfig.getStandard());
- deviceClient.setEndpoint(endPoint);
+
+ // setup DEVICES scanner
+ devices = setupScanner("coaps://" + configuration.host + ":" + configuration.port + "/" + DEVICES);
+ if (devices == null) {
+ logger.debug("Unable to scan for Tradfri DEVICES");
+ }
+ groups = setupScanner("coaps://" + configuration.host + ":" + configuration.port + "/" + GROUPS);
+ if (groups == null) {
+ logger.debug("Unable to scan for Tradfri GROUPS");
+ }
+
updateStatus(ThingStatus.UNKNOWN);
// schedule a new scan every minute
scanJob = scheduler.scheduleWithFixedDelay(() -> {
- startScan();
- }, 0, 1, TimeUnit.MINUTES);
+ if (devices != null) {
+ devices.startScan();
+ }
+ if (groups != null) {
+ groups.startScan();
+ }
+ }, 0, 60, TimeUnit.SECONDS);
+ }
+
+ TradfriCoapCallback setupScanner(String url) {
+ TradfriCoapCallback scanner = new TradfriCoapCallback();
+ scanner.gatewayURI = url;
+ try {
+ URI uri = new URI(scanner.gatewayURI);
+ scanner.client = new TradfriCoapClient(uri);
+ } catch (URISyntaxException e) {
+ logger.debug("Illegal gateway URI `{}`: {}", scanner.gatewayURI, e.getMessage());
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
+ return null;
+ }
+ scanner.client.setEndpoint(endPoint);
+ return scanner;
}
@Override
@@ -114,9 +134,13 @@ public void dispose() {
scanJob.cancel(true);
scanJob = null;
}
- if (deviceClient != null) {
- deviceClient.shutdown();
- deviceClient = null;
+ if (devices != null && devices.client != null) {
+ devices.client.shutdown();
+ devices.client = null;
+ }
+ if (groups != null && groups.client != null) {
+ groups.client.shutdown();
+ groups.client = null;
}
if (endPoint != null) {
endPoint.destroy();
@@ -125,74 +149,79 @@ public void dispose() {
super.dispose();
}
- /**
- * Does a request to the gateway to list all available devices/services.
- * The response is received and processed by the method {@link onUpdate(JsonElement data)}.
- */
- public void startScan() {
- if (endPoint != null) {
- deviceClient.get(new TradfriCoapHandler(this));
+ public class TradfriCoapCallback implements CoapCallback {
+ private TradfriCoapClient client;
+ private String gatewayURI;
+
+ /**
+ * Does a request to the gateway to list all available devices/services.
+ * The response is received and processed by the method {@link onUpdate(JsonElement data)}.
+ */
+ public void startScan() {
+ if (endPoint != null) {
+ client.get(new TradfriCoapHandler(this));
+ }
}
- }
- /**
- * Returns the root URI of the gateway.
- *
- * @return root URI of the gateway with coaps scheme
- */
- public String getGatewayURI() {
- return gatewayURI;
- }
+ /**
+ * Returns the root URI of the gateway.
+ *
+ * @return root URI of the gateway with coaps scheme
+ */
+ public String getGatewayURI() {
+ return gatewayURI;
+ }
- /**
- * Returns the coap endpoint that can be used within coap clients.
- *
- * @return the coap endpoint
- */
- public CoapEndpoint getEndpoint() {
- return endPoint;
- }
+ /**
+ * Returns the coap endpoint that can be used within coap clients.
+ *
+ * @return the coap endpoint
+ */
+ public CoapEndpoint getEndpoint() {
+ return endPoint;
+ }
- @Override
- public void onUpdate(JsonElement data) {
- logger.trace("Response: {}", data);
+ @Override
+ public void onUpdate(JsonElement data) {
+ logger.debug("Gateway response: {}", data);
- if (endPoint != null) {
- try {
- JsonArray array = data.getAsJsonArray();
- for (int i = 0; i < array.size(); i++) {
- requestDeviceDetails(array.get(i).getAsString());
+ if (endPoint != null) {
+ try {
+ JsonArray array = data.getAsJsonArray();
+ for (int i = 0; i < array.size(); i++) {
+ requestDeviceDetails(array.get(i).getAsString());
+ }
+ } catch (JsonSyntaxException e) {
+ logger.debug("JSON error: {}", e.getMessage());
+ setStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
}
- } catch (JsonSyntaxException e) {
- logger.debug("JSON error: {}", e.getMessage());
- setStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
}
}
- }
- private void requestDeviceDetails(String instanceId) {
- // we are reusing our coap client and merely temporarily set a sub-URI to call
- deviceClient.setURI(gatewayURI + "/" + instanceId);
- deviceClient.asyncGet().thenAccept(data -> {
- logger.debug("Response: {}", data);
- JsonObject json = new JsonParser().parse(data).getAsJsonObject();
- deviceUpdateListeners.forEach(listener -> listener.onUpdate(instanceId, json));
- });
- // restore root URI
- deviceClient.setURI(gatewayURI);
- }
+ private void requestDeviceDetails(String instanceId) {
+ // we are reusing our coap client and merely temporarily set a sub-URI to call
+ client.setURI(gatewayURI + "/" + instanceId);
+ client.asyncGet().thenAccept(data -> {
+ logger.debug("Response: {}", data);
+ JsonObject json = new JsonParser().parse(data).getAsJsonObject();
+ deviceUpdateListeners.forEach(listener -> listener.onUpdate(instanceId, json));
+ });
+ // restore root URI
+ client.setURI(gatewayURI);
+ }
- @Override
- public void setStatus(ThingStatus status, ThingStatusDetail statusDetail) {
- // are we still connected at all?
- if (endPoint != null) {
- updateStatus(status, statusDetail);
- if (dtlsConnector != null && status == ThingStatus.OFFLINE) {
- try {
- dtlsConnector.stop();
- dtlsConnector.start();
- } catch (IOException e) {
- logger.debug("Error restarting the DTLS connector: {}", e.getMessage());
+ @Override
+ public void setStatus(ThingStatus status, ThingStatusDetail statusDetail) {
+ // are we still connected at all?
+ if (endPoint != null) {
+ updateStatus(status, statusDetail);
+ if (dtlsConnector != null && status == ThingStatus.OFFLINE) {
+ try {
+ dtlsConnector.stop();
+ dtlsConnector.start();
+ } catch (IOException e) {
+ logger.debug("Error restarting the DTLS connector: {}", e.getMessage());
+ }
}
}
}
diff --git a/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/handler/TradfriGroupHandler.java b/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/handler/TradfriGroupHandler.java
new file mode 100644
index 00000000000..378932a0cca
--- /dev/null
+++ b/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/handler/TradfriGroupHandler.java
@@ -0,0 +1,191 @@
+/**
+ * Copyright (c) 2014-2017 by the respective copyright holders.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.smarthome.binding.tradfri.handler;
+
+import static org.eclipse.smarthome.binding.tradfri.TradfriBindingConstants.*;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.smarthome.binding.tradfri.DeviceConfig;
+import org.eclipse.smarthome.binding.tradfri.internal.CoapCallback;
+import org.eclipse.smarthome.binding.tradfri.internal.TradfriCoapClient;
+import org.eclipse.smarthome.core.library.types.OnOffType;
+import org.eclipse.smarthome.core.thing.ChannelUID;
+import org.eclipse.smarthome.core.thing.Thing;
+import org.eclipse.smarthome.core.thing.ThingStatus;
+import org.eclipse.smarthome.core.thing.ThingStatusDetail;
+import org.eclipse.smarthome.core.thing.binding.BaseThingHandler;
+import org.eclipse.smarthome.core.types.Command;
+import org.eclipse.smarthome.core.types.RefreshType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonSyntaxException;
+
+/**
+ * The {@link TradfriGroupHandler} is responsible for handling commands for
+ * individual lights.
+ *
+ * @author Kai Kreuzer - Initial contribution
+ * @author Mario Smit - Group Handler added
+ */
+public class TradfriGroupHandler extends BaseThingHandler implements CoapCallback {
+
+ private final Logger logger = LoggerFactory.getLogger(TradfriGroupHandler.class);
+
+ // keeps track of the current state for handling of increase/decrease
+ private GroupData state;
+
+ // the unique instance id of the light
+ private Integer id;
+
+ // used to check whether we have already been disposed when receiving data asynchronously
+ private volatile boolean active;
+
+ private TradfriCoapClient coapClient;
+
+ public TradfriGroupHandler(Thing thing) {
+ super(thing);
+ }
+
+ @Override
+ public synchronized void initialize() {
+ this.id = getConfigAs(DeviceConfig.class).id;
+ TradfriGatewayHandler handler = (TradfriGatewayHandler) getBridge().getHandler();
+ String uriString = handler.groups.getGatewayURI() + "/" + id;
+ try {
+ URI uri = new URI(uriString);
+ coapClient = new TradfriCoapClient(uri);
+ coapClient.setEndpoint(handler.groups.getEndpoint());
+ } catch (URISyntaxException e) {
+ logger.debug("Illegal device URI `{}`: {}", uriString, e.getMessage());
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
+ return;
+ }
+ updateStatus(ThingStatus.UNKNOWN);
+ active = true;
+
+ scheduler.schedule(() -> {
+ coapClient.startObserve(this);
+ }, 3, TimeUnit.SECONDS);
+ }
+
+ @Override
+ public synchronized void dispose() {
+ active = false;
+ if (coapClient != null) {
+ coapClient.shutdown();
+ }
+ super.dispose();
+ }
+
+ @Override
+ public void setStatus(ThingStatus status, ThingStatusDetail statusDetail) {
+ if (active && getBridge().getStatus() != ThingStatus.OFFLINE && status != ThingStatus.ONLINE) {
+ updateStatus(status, statusDetail);
+ // we are offline and lost our observe relation - let's try to establish the connection in 10 seconds again
+ scheduler.schedule(() -> {
+ coapClient.startObserve(this);
+ }, 10, TimeUnit.SECONDS);
+ }
+ }
+
+ @Override
+ public void onUpdate(JsonElement data) {
+ if (active && !(data.isJsonNull())) {
+ state = new GroupData(data);
+ updateStatus(ThingStatus.ONLINE);
+
+ if (state.getOnOffState()) {
+ updateState(CHANNEL_GROUP_STATE, OnOffType.ON);
+ } else {
+ updateState(CHANNEL_GROUP_STATE, OnOffType.OFF);
+ }
+ }
+ }
+
+ private void set(String payload) {
+ logger.debug("Sending payload: {}", payload);
+ coapClient.asyncPut(payload, this);
+ }
+
+ private void setState(OnOffType onOff) {
+ GroupData data = new GroupData();
+ data.setOnOffState(onOff == OnOffType.ON);
+ set(data.getJsonString());
+ }
+
+ @Override
+ public void handleCommand(ChannelUID channelUID, Command command) {
+ if (command instanceof RefreshType) {
+ logger.debug("Refreshing channel {}", channelUID);
+ coapClient.asyncGet(this);
+ return;
+ }
+
+ switch (channelUID.getId()) {
+ case CHANNEL_GROUP_STATE:
+ handleGroupStateCommand(command);
+ break;
+
+ default:
+ logger.error("Unknown channel UID {}", channelUID);
+ }
+ }
+
+ private void handleGroupStateCommand(Command command) {
+ if (command instanceof OnOffType) {
+ setState(((OnOffType) command));
+ } else {
+ logger.debug("Cannot handle command {} for channel {}", command, CHANNEL_GROUP_STATE);
+ }
+ }
+
+ /**
+ * This class is a Java wrapper for the raw JSON data about the group state.
+ */
+ private static class GroupData {
+
+ private final Logger logger = LoggerFactory.getLogger(GroupData.class);
+
+ JsonObject root;
+ boolean ison;
+
+ public GroupData() {
+ root = new JsonObject();
+ }
+
+ public GroupData(JsonElement json) {
+ try {
+ root = json.getAsJsonObject();
+ ison = (root.get(ONOFF).getAsInt() == 1) ? true : false;
+ } catch (JsonSyntaxException e) {
+ logger.error("JSON error: {}", e.getMessage(), e);
+ }
+ }
+
+ GroupData setOnOffState(boolean on) {
+ ison = on;
+ root.addProperty(ONOFF, ison ? 1 : 0);
+ return this;
+ }
+
+ boolean getOnOffState() {
+ return ison;
+ }
+
+ String getJsonString() {
+ return root.toString();
+ }
+ }
+
+}
diff --git a/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/handler/TradfriLightHandler.java b/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/handler/TradfriLightHandler.java
index 61116b10a80..970f1af61e8 100644
--- a/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/handler/TradfriLightHandler.java
+++ b/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/handler/TradfriLightHandler.java
@@ -67,11 +67,11 @@ public TradfriLightHandler(Thing thing) {
public synchronized void initialize() {
this.id = getConfigAs(DeviceConfig.class).id;
TradfriGatewayHandler handler = (TradfriGatewayHandler) getBridge().getHandler();
- String uriString = handler.getGatewayURI() + "/" + id;
+ String uriString = handler.devices.getGatewayURI() + "/" + id;
try {
URI uri = new URI(uriString);
coapClient = new TradfriCoapClient(uri);
- coapClient.setEndpoint(handler.getEndpoint());
+ coapClient.setEndpoint(handler.devices.getEndpoint());
} catch (URISyntaxException e) {
logger.debug("Illegal device URI `{}`: {}", uriString, e.getMessage());
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
diff --git a/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/internal/TradfriHandlerFactory.java b/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/internal/TradfriHandlerFactory.java
index 347c783a734..1e39e028d2f 100644
--- a/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/internal/TradfriHandlerFactory.java
+++ b/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/internal/TradfriHandlerFactory.java
@@ -16,6 +16,7 @@
import java.util.Set;
import org.eclipse.smarthome.binding.tradfri.handler.TradfriGatewayHandler;
+import org.eclipse.smarthome.binding.tradfri.handler.TradfriGroupHandler;
import org.eclipse.smarthome.binding.tradfri.handler.TradfriLightHandler;
import org.eclipse.smarthome.binding.tradfri.internal.discovery.TradfriDiscoveryService;
import org.eclipse.smarthome.config.discovery.DiscoveryService;
@@ -36,8 +37,9 @@
*/
public class TradfriHandlerFactory extends BaseThingHandlerFactory {
- private static final Set SUPPORTED_THING_TYPES_UIDS = Sets
- .union(Collections.singleton(GATEWAY_TYPE_UID), SUPPORTED_LIGHT_TYPES_UIDS);
+ private static final Set SUPPORTED_THING_TYPES_UIDS = Sets.union(
+ Collections.singleton(GATEWAY_TYPE_UID),
+ Sets.union(SUPPORTED_LIGHT_TYPES_UIDS, Collections.singleton(THING_TYPE_GROUP)));
private Map> discoveryServiceRegs = new HashMap<>();
@@ -56,6 +58,8 @@ protected ThingHandler createHandler(Thing thing) {
return handler;
} else if (SUPPORTED_LIGHT_TYPES_UIDS.contains(thingTypeUID)) {
return new TradfriLightHandler(thing);
+ } else if (thingTypeUID.equals(THING_TYPE_GROUP)) {
+ return new TradfriGroupHandler(thing);
}
return null;
}
diff --git a/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/internal/discovery/TradfriDiscoveryService.java b/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/internal/discovery/TradfriDiscoveryService.java
index ef8317dfb80..54388adc0f0 100644
--- a/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/internal/discovery/TradfriDiscoveryService.java
+++ b/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/internal/discovery/TradfriDiscoveryService.java
@@ -10,10 +10,10 @@
import static org.eclipse.smarthome.binding.tradfri.TradfriBindingConstants.*;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
-import org.eclipse.smarthome.binding.tradfri.TradfriBindingConstants;
import org.eclipse.smarthome.binding.tradfri.handler.TradfriGatewayHandler;
import org.eclipse.smarthome.binding.tradfri.internal.DeviceUpdateListener;
import org.eclipse.smarthome.config.discovery.AbstractDiscoveryService;
@@ -23,6 +23,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.collect.Sets;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
@@ -30,6 +31,7 @@
* This class identifies devices that are available on the gateway and adds discovery results for them.
*
* @author Kai Kreuzer - Initial contribution
+ * @author Mario Smit - Group Handler added
*/
public class TradfriDiscoveryService extends AbstractDiscoveryService implements DeviceUpdateListener {
@@ -37,17 +39,18 @@ public class TradfriDiscoveryService extends AbstractDiscoveryService implements
private TradfriGatewayHandler handler;
- private String[] COLOR_TEMP_MODELS = new String[] { "TRADFRI bulb E27 WS opal 980lm",
- "TRADFRI bulb GU10 WS 400lm" };
+ private String[] COLOR_TEMP_MODELS = new String[] { "TRADFRI bulb E27 WS opal 980lm", "TRADFRI bulb GU10 WS 400lm",
+ "TRADFRI bulb E14 WS opal 400lm" };
public TradfriDiscoveryService(TradfriGatewayHandler bridgeHandler) {
- super(TradfriBindingConstants.SUPPORTED_LIGHT_TYPES_UIDS, 10, true);
+ super(Sets.union(SUPPORTED_LIGHT_TYPES_UIDS, Collections.singleton(THING_TYPE_GROUP)), 10, true);
this.handler = bridgeHandler;
}
@Override
protected void startScan() {
- handler.startScan();
+ handler.devices.startScan();
+ handler.groups.startScan();
}
public void activate() {
@@ -65,23 +68,30 @@ public void onUpdate(String instanceId, JsonObject data) {
try {
if (data.has(INSTANCE_ID)) {
int id = data.get(INSTANCE_ID).getAsInt();
- String type = data.get(TYPE).getAsString();
- JsonObject deviceInfo = data.get(DEVICE).getAsJsonObject();
- String model = deviceInfo.get(DEVICE_MODEL).getAsString();
ThingUID thingId = null;
-
- if (type.equals(TYPE_LIGHT) && data.has(LIGHT)) {
- JsonObject state = data.get(LIGHT).getAsJsonArray().get(0).getAsJsonObject();
-
- // Color temperature light
- // We do not always receive a COLOR attribute, even the light supports it - but the gateway does not
- // seem to have this information, if the bulb is unreachable. We therefore also check against
- // concrete model names.
- if (state.has(COLOR) || (model != null && Arrays.asList(COLOR_TEMP_MODELS).contains(model))) {
- thingId = new ThingUID(THING_TYPE_COLOR_TEMP_LIGHT, bridge, Integer.toString(id));
- } else {
- thingId = new ThingUID(THING_TYPE_DIMMABLE_LIGHT, bridge, Integer.toString(id));
+ JsonObject deviceInfo = new JsonObject();
+ if (data.has(TYPE)) {
+ String type = data.get(TYPE).getAsString();
+ deviceInfo = data.get(DEVICE).getAsJsonObject();
+ String model = deviceInfo.get(DEVICE_MODEL).getAsString();
+
+ if (type.equals(TYPE_LIGHT) && data.has(LIGHT)) {
+ JsonObject state = data.get(LIGHT).getAsJsonArray().get(0).getAsJsonObject();
+
+ // Color temperature light
+ // We do not always receive a COLOR attribute, even the light supports it - but the gateway does
+ // not
+ // seem to have this information, if the bulb is unreachable. We therefore also check against
+ // concrete model names.
+ if (state.has(COLOR) || (model != null && Arrays.asList(COLOR_TEMP_MODELS).contains(model))) {
+ thingId = new ThingUID(THING_TYPE_COLOR_TEMP_LIGHT, bridge, Integer.toString(id));
+ } else {
+ thingId = new ThingUID(THING_TYPE_DIMMABLE_LIGHT, bridge, Integer.toString(id));
+ }
}
+ } else if (data.has(HS_ACCESSORY_LINK)) {
+ // GROUP info
+ thingId = new ThingUID(THING_TYPE_GROUP, bridge, Integer.toString(id));
}
if (thingId == null) {