]> git.basschouten.com Git - openhab-addons.git/blob
93f8820d05e319a75323f78d80cbaa206322d650
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.digitalstrom.internal.discovery;
14
15 import static org.openhab.binding.digitalstrom.internal.DigitalSTROMBindingConstants.BINDING_ID;
16
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;
22 import java.util.Map;
23
24 import org.apache.commons.lang.StringUtils;
25 import org.openhab.binding.digitalstrom.internal.DigitalSTROMBindingConstants;
26 import org.openhab.binding.digitalstrom.internal.handler.BridgeHandler;
27 import org.openhab.binding.digitalstrom.internal.lib.structure.devices.Circuit;
28 import org.openhab.binding.digitalstrom.internal.lib.structure.devices.Device;
29 import org.openhab.binding.digitalstrom.internal.lib.structure.devices.GeneralDeviceInformation;
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.ThingTypeUID;
35 import org.openhab.core.thing.ThingUID;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * The {@link DeviceDiscoveryService} discovers all digitalSTROM-Devices, of one supported device-color-type. The
41  * device-color-type has to be given to the {@link #DeviceDiscoveryService(BridgeHandler, ThingTypeUID)} as
42  * {@link ThingTypeUID}. The supported {@link ThingTypeUID} can be found at
43  * {@link DeviceHandler#SUPPORTED_THING_TYPES}.
44  *
45  * @author Michael Ochel - Initial contribution
46  * @author Matthias Siegele - Initial contribution
47  */
48 public class DeviceDiscoveryService extends AbstractDiscoveryService {
49
50     private final Logger logger = LoggerFactory.getLogger(DeviceDiscoveryService.class);
51
52     private final BridgeHandler bridgeHandler;
53     private final String deviceType;
54     private final ThingUID bridgeUID;
55
56     public static final int TIMEOUT = 10;
57
58     /**
59      * Creates a new {@link DeviceDiscoveryService} for the given supported {@link ThingTypeUID}.
60      *
61      * @param bridgeHandler (must not be null)
62      * @param supportedThingType (must not be null)
63      * @throws IllegalArgumentException see {@link AbstractDiscoveryService#AbstractDiscoveryService(int)}
64      */
65     public DeviceDiscoveryService(BridgeHandler bridgeHandler, ThingTypeUID supportedThingType)
66             throws IllegalArgumentException {
67         super(new HashSet<>(Arrays.asList(supportedThingType)), TIMEOUT, true);
68         this.deviceType = supportedThingType.getId();
69         this.bridgeHandler = bridgeHandler;
70         bridgeUID = bridgeHandler.getThing().getUID();
71     }
72
73     /**
74      * Deactivates the {@link DeviceDiscoveryService} and removes the {@link DiscoveryResult}s.
75      */
76     @Override
77     public void deactivate() {
78         logger.debug("deactivate discovery service for device type {} thing types are: {}", deviceType,
79                 super.getSupportedThingTypes().toString());
80         removeOlderResults(new Date().getTime());
81     }
82
83     @Override
84     protected void startScan() {
85         if (bridgeHandler != null) {
86             if (!DsDeviceThingTypeProvider.SupportedThingTypes.circuit.toString().equals(deviceType)) {
87                 List<Device> devices = bridgeHandler.getDevices();
88                 if (devices != null) {
89                     for (Device device : devices) {
90                         onDeviceAddedInternal(device);
91                     }
92                 }
93             } else {
94                 List<Circuit> circuits = bridgeHandler.getCircuits();
95                 if (circuits != null) {
96                     for (Circuit circuit : circuits) {
97                         onDeviceAddedInternal(circuit);
98                     }
99                 }
100             }
101         }
102     }
103
104     @Override
105     protected synchronized void stopScan() {
106         super.stopScan();
107         removeOlderResults(getTimestampOfLastScan());
108     }
109
110     private void onDeviceAddedInternal(GeneralDeviceInformation device) {
111         boolean isSupported = false;
112         if (device instanceof Device) {
113             Device tempDevice = (Device) device;
114             if ((tempDevice.isSensorDevice() && deviceType.equals(tempDevice.getHWinfo().replaceAll("-", "")))
115                     || (deviceType.equals(tempDevice.getHWinfo().substring(0, 2))
116                             && (tempDevice.isDeviceWithOutput() || tempDevice.isBinaryInputDevice())
117                             && tempDevice.isPresent())) {
118                 isSupported = true;
119             }
120         } else if (device instanceof Circuit
121                 && DsDeviceThingTypeProvider.SupportedThingTypes.circuit.toString().equals(deviceType)) {
122             isSupported = true;
123         }
124         if (isSupported) {
125             ThingUID thingUID = getThingUID(device);
126             if (thingUID != null) {
127                 Map<String, Object> properties = new HashMap<>(1);
128                 properties.put(DigitalSTROMBindingConstants.DEVICE_DSID, device.getDSID().getValue());
129                 String deviceName = null;
130                 if (StringUtils.isNotBlank(device.getName())) {
131                     deviceName = device.getName();
132                 } else {
133                     // if no name is set, the dSID will be used as name
134                     deviceName = device.getDSID().getValue();
135                 }
136                 DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withProperties(properties)
137                         .withBridge(bridgeUID).withLabel(deviceName).build();
138
139                 thingDiscovered(discoveryResult);
140             } else {
141                 if (device instanceof Device) {
142                     logger.debug("Discovered unsupported device hardware type '{}' with uid {}",
143                             ((Device) device).getHWinfo(), device.getDSUID());
144                 }
145             }
146         } else {
147             if (device instanceof Device) {
148                 logger.debug(
149                         "Discovered device with disabled or no output mode. Device was not added to inbox. "
150                                 + "Device information: hardware info: {}, dSUID: {}, device-name: {}, output value: {}",
151                         ((Device) device).getHWinfo(), device.getDSUID(), device.getName(),
152                         ((Device) device).getOutputMode());
153             }
154         }
155     }
156
157     private ThingUID getThingUID(GeneralDeviceInformation device) {
158         ThingUID bridgeUID = bridgeHandler.getThing().getUID();
159         ThingTypeUID thingTypeUID = null;
160         if (device instanceof Device) {
161             Device tempDevice = (Device) device;
162             thingTypeUID = new ThingTypeUID(BINDING_ID, tempDevice.getHWinfo().substring(0, 2));
163             if (tempDevice.isSensorDevice() && deviceType.equals(tempDevice.getHWinfo().replaceAll("-", ""))) {
164                 thingTypeUID = new ThingTypeUID(BINDING_ID, deviceType);
165             }
166         } else {
167             thingTypeUID = new ThingTypeUID(BINDING_ID,
168                     DsDeviceThingTypeProvider.SupportedThingTypes.circuit.toString());
169         }
170         if (getSupportedThingTypes().contains(thingTypeUID)) {
171             String thingDeviceId = device.getDSID().toString();
172             ThingUID thingUID = new ThingUID(thingTypeUID, bridgeUID, thingDeviceId);
173             return thingUID;
174         } else {
175             return null;
176         }
177     }
178
179     /**
180      * Removes the {@link Thing} of the given {@link Device}.
181      *
182      * @param device (must not be null)
183      */
184     public void onDeviceRemoved(GeneralDeviceInformation device) {
185         ThingUID thingUID = getThingUID(device);
186
187         if (thingUID != null) {
188             thingRemoved(thingUID);
189         }
190     }
191
192     /**
193      * Creates a {@link DiscoveryResult} for the given {@link Device}, if the {@link Device} is supported and the
194      * {@link Device#getOutputMode()} is unequal {@link OutputModeEnum#DISABLED}.
195      *
196      * @param device (must not be null)
197      */
198     public void onDeviceAdded(GeneralDeviceInformation device) {
199         if (super.isBackgroundDiscoveryEnabled()) {
200             onDeviceAddedInternal(device);
201         }
202     }
203
204     /**
205      * Returns the ID of this {@link DeviceDiscoveryService}.
206      *
207      * @return id of the service
208      */
209     public String getID() {
210         return deviceType;
211     }
212 }