2 * Copyright (c) 2010-2022 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.digitalstrom.internal.discovery;
15 import static org.openhab.binding.digitalstrom.internal.DigitalSTROMBindingConstants.BINDING_ID;
17 import java.util.Arrays;
18 import java.util.Date;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.List;
24 import org.openhab.binding.digitalstrom.internal.DigitalSTROMBindingConstants;
25 import org.openhab.binding.digitalstrom.internal.handler.BridgeHandler;
26 import org.openhab.binding.digitalstrom.internal.lib.structure.devices.Circuit;
27 import org.openhab.binding.digitalstrom.internal.lib.structure.devices.Device;
28 import org.openhab.binding.digitalstrom.internal.lib.structure.devices.GeneralDeviceInformation;
29 import org.openhab.binding.digitalstrom.internal.lib.structure.devices.deviceparameters.constants.OutputModeEnum;
30 import org.openhab.binding.digitalstrom.internal.providers.DsDeviceThingTypeProvider;
31 import org.openhab.core.config.discovery.AbstractDiscoveryService;
32 import org.openhab.core.config.discovery.DiscoveryResult;
33 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
34 import org.openhab.core.thing.Thing;
35 import org.openhab.core.thing.ThingTypeUID;
36 import org.openhab.core.thing.ThingUID;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
41 * The {@link DeviceDiscoveryService} discovers all digitalSTROM-Devices, of one supported device-color-type. The
42 * device-color-type has to be given to the {@link #DeviceDiscoveryService(BridgeHandler, ThingTypeUID)} as
43 * {@link ThingTypeUID}. The supported {@link ThingTypeUID} can be found at
44 * {@link DeviceHandler#SUPPORTED_THING_TYPES}.
46 * @author Michael Ochel - Initial contribution
47 * @author Matthias Siegele - Initial contribution
49 public class DeviceDiscoveryService extends AbstractDiscoveryService {
51 private final Logger logger = LoggerFactory.getLogger(DeviceDiscoveryService.class);
53 private final BridgeHandler bridgeHandler;
54 private final String deviceType;
55 private final ThingUID bridgeUID;
57 public static final int TIMEOUT = 10;
60 * Creates a new {@link DeviceDiscoveryService} for the given supported {@link ThingTypeUID}.
62 * @param bridgeHandler (must not be null)
63 * @param supportedThingType (must not be null)
64 * @throws IllegalArgumentException see {@link AbstractDiscoveryService#AbstractDiscoveryService(int)}
66 public DeviceDiscoveryService(BridgeHandler bridgeHandler, ThingTypeUID supportedThingType)
67 throws IllegalArgumentException {
68 super(new HashSet<>(Arrays.asList(supportedThingType)), TIMEOUT, true);
69 this.deviceType = supportedThingType.getId();
70 this.bridgeHandler = bridgeHandler;
71 bridgeUID = bridgeHandler.getThing().getUID();
75 * Deactivates the {@link DeviceDiscoveryService} and removes the {@link DiscoveryResult}s.
78 public void deactivate() {
79 logger.debug("deactivate discovery service for device type {} thing types are: {}", deviceType,
80 super.getSupportedThingTypes().toString());
81 removeOlderResults(new Date().getTime());
85 protected void startScan() {
86 if (bridgeHandler != null) {
87 if (!DsDeviceThingTypeProvider.SupportedThingTypes.circuit.toString().equals(deviceType)) {
88 List<Device> devices = bridgeHandler.getDevices();
89 if (devices != null) {
90 for (Device device : devices) {
91 onDeviceAddedInternal(device);
95 List<Circuit> circuits = bridgeHandler.getCircuits();
96 if (circuits != null) {
97 for (Circuit circuit : circuits) {
98 onDeviceAddedInternal(circuit);
106 protected synchronized void stopScan() {
108 removeOlderResults(getTimestampOfLastScan());
111 private void onDeviceAddedInternal(GeneralDeviceInformation device) {
112 boolean isSupported = false;
113 if (device instanceof Device) {
114 Device tempDevice = (Device) device;
115 if ((tempDevice.isSensorDevice() && deviceType.equals(tempDevice.getHWinfo().replaceAll("-", "")))
116 || (deviceType.equals(tempDevice.getHWinfo().substring(0, 2))
117 && (tempDevice.isDeviceWithOutput() || tempDevice.isBinaryInputDevice())
118 && tempDevice.isPresent())) {
121 } else if (device instanceof Circuit
122 && DsDeviceThingTypeProvider.SupportedThingTypes.circuit.toString().equals(deviceType)) {
126 ThingUID thingUID = getThingUID(device);
127 if (thingUID != null) {
128 Map<String, Object> properties = new HashMap<>(1);
129 properties.put(DigitalSTROMBindingConstants.DEVICE_DSID, device.getDSID().getValue());
130 String deviceName = device.getName();
131 if (deviceName == null || deviceName.isBlank()) {
132 // if no name is set, the dSID will be used as name
133 deviceName = device.getDSID().getValue();
135 DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withProperties(properties)
136 .withBridge(bridgeUID).withLabel(deviceName).build();
138 thingDiscovered(discoveryResult);
140 if (device instanceof Device) {
141 logger.debug("Discovered unsupported device hardware type '{}' with uid {}",
142 ((Device) device).getHWinfo(), device.getDSUID());
146 if (device instanceof Device) {
148 "Discovered device with disabled or no output mode. Device was not added to inbox. "
149 + "Device information: hardware info: {}, dSUID: {}, device-name: {}, output value: {}",
150 ((Device) device).getHWinfo(), device.getDSUID(), device.getName(),
151 ((Device) device).getOutputMode());
156 private ThingUID getThingUID(GeneralDeviceInformation device) {
157 ThingUID bridgeUID = bridgeHandler.getThing().getUID();
158 ThingTypeUID thingTypeUID = null;
159 if (device instanceof Device) {
160 Device tempDevice = (Device) device;
161 thingTypeUID = new ThingTypeUID(BINDING_ID, tempDevice.getHWinfo().substring(0, 2));
162 if (tempDevice.isSensorDevice() && deviceType.equals(tempDevice.getHWinfo().replaceAll("-", ""))) {
163 thingTypeUID = new ThingTypeUID(BINDING_ID, deviceType);
166 thingTypeUID = new ThingTypeUID(BINDING_ID,
167 DsDeviceThingTypeProvider.SupportedThingTypes.circuit.toString());
169 if (getSupportedThingTypes().contains(thingTypeUID)) {
170 String thingDeviceId = device.getDSID().toString();
171 ThingUID thingUID = new ThingUID(thingTypeUID, bridgeUID, thingDeviceId);
179 * Removes the {@link Thing} of the given {@link Device}.
181 * @param device (must not be null)
183 public void onDeviceRemoved(GeneralDeviceInformation device) {
184 ThingUID thingUID = getThingUID(device);
186 if (thingUID != null) {
187 thingRemoved(thingUID);
192 * Creates a {@link DiscoveryResult} for the given {@link Device}, if the {@link Device} is supported and the
193 * {@link Device#getOutputMode()} is unequal {@link OutputModeEnum#DISABLED}.
195 * @param device (must not be null)
197 public void onDeviceAdded(GeneralDeviceInformation device) {
198 if (super.isBackgroundDiscoveryEnabled()) {
199 onDeviceAddedInternal(device);
204 * Returns the ID of this {@link DeviceDiscoveryService}.
206 * @return id of the service
208 public String getID() {