/**
* 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.hue.internal;
import static org.eclipse.smarthome.binding.hue.HueBindingConstants.*;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import org.eclipse.smarthome.binding.hue.handler.HueBridgeHandler;
import org.eclipse.smarthome.binding.hue.handler.HueLightHandler;
import org.eclipse.smarthome.binding.hue.internal.discovery.HueLightDiscoveryService;
import org.eclipse.smarthome.config.core.Configuration;
import org.eclipse.smarthome.config.discovery.DiscoveryService;
import org.eclipse.smarthome.core.thing.Bridge;
import org.eclipse.smarthome.core.thing.Thing;
import org.eclipse.smarthome.core.thing.ThingTypeUID;
import org.eclipse.smarthome.core.thing.ThingUID;
import org.eclipse.smarthome.core.thing.binding.BaseThingHandlerFactory;
import org.eclipse.smarthome.core.thing.binding.ThingHandler;
import org.osgi.framework.ServiceRegistration;
import com.google.common.collect.Sets;
/**
* {@link HueThingHandlerFactory} is a factory for {@link HueBridgeHandler}s.
*
* @author Dennis Nobel - Initial contribution of hue binding
* @author Kai Kreuzer - added supportsThingType method
* @author Andre Fuechsel - implemented to use one discovery service per bridge
*
*/
public class HueThingHandlerFactory extends BaseThingHandlerFactory {
public final static Set<ThingTypeUID> SUPPORTED_THING_TYPES = Sets.union(HueBridgeHandler.SUPPORTED_THING_TYPES,
HueLightHandler.SUPPORTED_THING_TYPES);
private Map<ThingUID, ServiceRegistration<?>> discoveryServiceRegs = new HashMap<>();
@Override
public Thing createThing(ThingTypeUID thingTypeUID, Configuration configuration, ThingUID thingUID,
ThingUID bridgeUID) {
if (HueBridgeHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
ThingUID hueBridgeUID = getBridgeThingUID(thingTypeUID, thingUID, configuration);
return super.createThing(thingTypeUID, configuration, hueBridgeUID, null);
}
if (HueLightHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
ThingUID hueLightUID = getLightUID(thingTypeUID, thingUID, configuration, bridgeUID);
return super.createThing(thingTypeUID, configuration, hueLightUID, bridgeUID);
}
throw new IllegalArgumentException("The thing type " + thingTypeUID + " is not supported by the hue binding.");
}
@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return SUPPORTED_THING_TYPES.contains(thingTypeUID);
}
private ThingUID getBridgeThingUID(ThingTypeUID thingTypeUID, ThingUID thingUID, Configuration configuration) {
if (thingUID == null) {
String serialNumber = (String) configuration.get(SERIAL_NUMBER);
thingUID = new ThingUID(thingTypeUID, serialNumber);
}
return thingUID;
}
private ThingUID getLightUID(ThingTypeUID thingTypeUID, ThingUID thingUID, Configuration configuration,
ThingUID bridgeUID) {
String lightId = (String) configuration.get(LIGHT_ID);
if (thingUID == null) {
thingUID = new ThingUID(thingTypeUID, lightId, bridgeUID.getId());
}
return thingUID;
}
@Override
protected ThingHandler createHandler(Thing thing) {
if (HueBridgeHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
HueBridgeHandler handler = new HueBridgeHandler((Bridge) thing);
registerLightDiscoveryService(handler);
return handler;
} else if (HueLightHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
return new HueLightHandler(thing);
} else {
return null;
}
}
private synchronized void registerLightDiscoveryService(HueBridgeHandler bridgeHandler) {
HueLightDiscoveryService discoveryService = new HueLightDiscoveryService(bridgeHandler);
discoveryService.activate();
this.discoveryServiceRegs.put(bridgeHandler.getThing().getUID(), bundleContext
.registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<String, Object>()));
}
@Override
protected synchronized void removeHandler(ThingHandler thingHandler) {
if (thingHandler instanceof HueBridgeHandler) {
ServiceRegistration<?> serviceReg = this.discoveryServiceRegs.get(thingHandler.getThing().getUID());
if (serviceReg != null) {
// remove discovery service, if bridge handler is removed
HueLightDiscoveryService service = (HueLightDiscoveryService) bundleContext
.getService(serviceReg.getReference());
service.deactivate();
serviceReg.unregister();
discoveryServiceRegs.remove(thingHandler.getThing().getUID());
}
}
}
}