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