]> git.basschouten.com Git - openhab-addons.git/blob
1aff0b0fa9a0ef31b372cc15f4d900f8c0e16536
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 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.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;
39
40 /**
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}.
45  *
46  * @author Michael Ochel - Initial contribution
47  * @author Matthias Siegele - Initial contribution
48  */
49 public class DeviceDiscoveryService extends AbstractDiscoveryService {
50
51     private final Logger logger = LoggerFactory.getLogger(DeviceDiscoveryService.class);
52
53     private final BridgeHandler bridgeHandler;
54     private final String deviceType;
55     private final ThingUID bridgeUID;
56
57     public static final int TIMEOUT = 10;
58
59     /**
60      * Creates a new {@link DeviceDiscoveryService} for the given supported {@link ThingTypeUID}.
61      *
62      * @param bridgeHandler (must not be null)
63      * @param supportedThingType (must not be null)
64      * @throws IllegalArgumentException see {@link AbstractDiscoveryService#AbstractDiscoveryService(int)}
65      */
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();
72     }
73
74     /**
75      * Deactivates the {@link DeviceDiscoveryService} and removes the {@link DiscoveryResult}s.
76      */
77     @Override
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());
82     }
83
84     @Override
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);
92                     }
93                 }
94             } else {
95                 List<Circuit> circuits = bridgeHandler.getCircuits();
96                 if (circuits != null) {
97                     for (Circuit circuit : circuits) {
98                         onDeviceAddedInternal(circuit);
99                     }
100                 }
101             }
102         }
103     }
104
105     @Override
106     protected synchronized void stopScan() {
107         super.stopScan();
108         removeOlderResults(getTimestampOfLastScan());
109     }
110
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())) {
119                 isSupported = true;
120             }
121         } else if (device instanceof Circuit
122                 && DsDeviceThingTypeProvider.SupportedThingTypes.circuit.toString().equals(deviceType)) {
123             isSupported = true;
124         }
125         if (isSupported) {
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();
134                 }
135                 DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withProperties(properties)
136                         .withBridge(bridgeUID).withLabel(deviceName).build();
137
138                 thingDiscovered(discoveryResult);
139             } else {
140                 if (device instanceof Device) {
141                     logger.debug("Discovered unsupported device hardware type '{}' with uid {}",
142                             ((Device) device).getHWinfo(), device.getDSUID());
143                 }
144             }
145         } else {
146             if (device instanceof Device) {
147                 logger.debug(
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());
152             }
153         }
154     }
155
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);
164             }
165         } else {
166             thingTypeUID = new ThingTypeUID(BINDING_ID,
167                     DsDeviceThingTypeProvider.SupportedThingTypes.circuit.toString());
168         }
169         if (getSupportedThingTypes().contains(thingTypeUID)) {
170             String thingDeviceId = device.getDSID().toString();
171             ThingUID thingUID = new ThingUID(thingTypeUID, bridgeUID, thingDeviceId);
172             return thingUID;
173         } else {
174             return null;
175         }
176     }
177
178     /**
179      * Removes the {@link Thing} of the given {@link Device}.
180      *
181      * @param device (must not be null)
182      */
183     public void onDeviceRemoved(GeneralDeviceInformation device) {
184         ThingUID thingUID = getThingUID(device);
185
186         if (thingUID != null) {
187             thingRemoved(thingUID);
188         }
189     }
190
191     /**
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}.
194      *
195      * @param device (must not be null)
196      */
197     public void onDeviceAdded(GeneralDeviceInformation device) {
198         if (super.isBackgroundDiscoveryEnabled()) {
199             onDeviceAddedInternal(device);
200         }
201     }
202
203     /**
204      * Returns the ID of this {@link DeviceDiscoveryService}.
205      *
206      * @return id of the service
207      */
208     public String getID() {
209         return deviceType;
210     }
211 }