/** * 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.digitalstrom.internal.discovery; import static org.eclipse.smarthome.binding.digitalstrom.DigitalSTROMBindingConstants.*; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.eclipse.smarthome.binding.digitalstrom.DigitalSTROMBindingConstants; import org.eclipse.smarthome.binding.digitalstrom.handler.BridgeHandler; import org.eclipse.smarthome.binding.digitalstrom.handler.DeviceHandler; import org.eclipse.smarthome.binding.digitalstrom.internal.lib.structure.devices.Device; import org.eclipse.smarthome.binding.digitalstrom.internal.lib.structure.devices.deviceParameters.OutputModeEnum; import org.eclipse.smarthome.config.discovery.AbstractDiscoveryService; import org.eclipse.smarthome.config.discovery.DiscoveryResult; import org.eclipse.smarthome.config.discovery.DiscoveryResultBuilder; import org.eclipse.smarthome.core.thing.Thing; import org.eclipse.smarthome.core.thing.ThingTypeUID; import org.eclipse.smarthome.core.thing.ThingUID; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.Sets; /** * The {@link DeviceDiscoveryService} discovers all digitalSTROM-Devices, of one supported device-color-type. The * device-color-type has to be given to the {@link #DeviceDiscoveryService(BridgeHandler, ThingTypeUID)} as * {@link ThingTypeUID}. The supported {@link ThingTypeUID} can be found at {@link DeviceHandler#SUPPORTED_THING_TYPES}. * * @author Michael Ochel - Initial contribution * @author Matthias Siegele - Initial contribution */ public class DeviceDiscoveryService extends AbstractDiscoveryService { private final static Logger logger = LoggerFactory.getLogger(DeviceDiscoveryService.class); private final BridgeHandler bridgeHandler; private final String deviceType; /** * Creates a new {@link DeviceDiscoveryService} for the given supported {@link ThingTypeUID}. * * @param bridgeHandler (must not be null) * @param supportedThingType (must not be null) * @throws IllegalArgumentException */ public DeviceDiscoveryService(BridgeHandler bridgeHandler, ThingTypeUID supportedThingType) throws IllegalArgumentException { super(Sets.newHashSet(supportedThingType), 10, true); this.deviceType = supportedThingType.getId(); this.bridgeHandler = bridgeHandler; } /** * Deactivates the {@link DeviceDiscoveryService} and removes the {@link DiscoveryResult}s. */ @Override public void deactivate() { logger.debug("deactivate discovery service for device type " + deviceType + " thing types are: " + super.getSupportedThingTypes().toString()); removeOlderResults(new Date().getTime()); } @Override protected void startScan() { if (bridgeHandler != null) { List<Device> devices = bridgeHandler.getDevices(); if (devices != null) { for (Device device : devices) { onDeviceAddedInternal(device); } } } } @Override protected synchronized void stopScan() { super.stopScan(); removeOlderResults(getTimestampOfLastScan()); } private void onDeviceAddedInternal(Device device) { if (deviceType.equals(device.getHWinfo().substring(0, 2)) && device.isDeviceWithOutput() && device.isPresent()) { ThingUID thingUID = getThingUID(device); if (thingUID != null) { ThingUID bridgeUID = bridgeHandler.getThing().getUID(); Map<String, Object> properties = new HashMap<>(9); properties.put(DigitalSTROMBindingConstants.DEVICE_UID, device.getDSUID()); properties.put(DigitalSTROMBindingConstants.DEVICE_DSID, device.getDSID().getValue()); properties.put(DigitalSTROMBindingConstants.DEVICE_HW_INFO, device.getHWinfo()); properties.put(DigitalSTROMBindingConstants.DEVICE_GROUPS, device.getGroups().toString()); properties.put(DigitalSTROMBindingConstants.DEVICE_OUTPUT_MODE, device.getOutputMode()); properties.put(DigitalSTROMBindingConstants.DEVICE_ZONE_ID, device.getZoneId()); properties.put(DigitalSTROMBindingConstants.DEVICE_FUNCTIONAL_COLOR_GROUP, device.getFunctionalColorGroup()); properties.put(DigitalSTROMBindingConstants.DEVICE_METER_ID, device.getMeterDSID().getValue()); String deviceName = null; if (StringUtils.isNotBlank(device.getName())) { deviceName = device.getName(); } else { // if no name is set, the dSID will be used as name deviceName = device.getDSID().getValue(); } properties.put(DEVICE_NAME, deviceName); DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withProperties(properties) .withBridge(bridgeUID).withLabel(deviceName).build(); thingDiscovered(discoveryResult); } else { logger.debug("Discovered unsupported device hardware type '{}' with uid {}", device.getHWinfo(), device.getDSUID()); } } else { logger.debug( "Discovered device with disabled or no output mode. Device was not added to inbox. " + "Device information: hardware info: {}, dSUID: {}, device-name: {}, output value: {}", device.getHWinfo(), device.getDSUID(), device.getName(), device.getOutputMode()); } } private ThingUID getThingUID(Device device) { ThingUID bridgeUID = bridgeHandler.getThing().getUID(); ThingTypeUID thingTypeUID = new ThingTypeUID(BINDING_ID, device.getHWinfo().substring(0, 2)); if (getSupportedThingTypes().contains(thingTypeUID)) { String thingDeviceId = device.getDSID().toString(); ThingUID thingUID = new ThingUID(thingTypeUID, bridgeUID, thingDeviceId); return thingUID; } else { return null; } } /** * Removes the {@link Thing} of the given {@link Device}. * * @param device (must not be null) */ public void onDeviceRemoved(Device device) { if (deviceType.equals(device.getHWinfo().substring(0, 2))) { ThingUID thingUID = getThingUID(device); if (thingUID != null) { thingRemoved(thingUID); } } } /** * Creates a {@link DiscoveryResult} for the given {@link Device}, if the {@link Device} is supported and the * {@link Device#getOutputMode()} is unequal {@link OutputModeEnum#DISABLED}. * * @param device (must not be null) */ public void onDeviceAdded(Device device) { if (super.isBackgroundDiscoveryEnabled()) { onDeviceAddedInternal(device); } } /** * Returns the ID of this {@link DeviceDiscoveryService}. * * @return id of the service */ public String getID() { return deviceType; } }