]> git.basschouten.com Git - openhab-addons.git/blob
8fe5df702a6baa89f95cb735b6a77f19eba899a1
[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.tapocontrol.internal;
14
15 import static org.openhab.binding.tapocontrol.internal.constants.TapoBindingSettings.*;
16 import static org.openhab.binding.tapocontrol.internal.constants.TapoThingConstants.*;
17 import static org.openhab.binding.tapocontrol.internal.helpers.TapoUtils.*;
18
19 import java.util.HashMap;
20 import java.util.Map;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.openhab.binding.tapocontrol.internal.device.TapoBridgeHandler;
24 import org.openhab.binding.tapocontrol.internal.structures.TapoBridgeConfiguration;
25 import org.openhab.core.config.discovery.AbstractThingHandlerDiscoveryService;
26 import org.openhab.core.config.discovery.DiscoveryResult;
27 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
28 import org.openhab.core.config.discovery.DiscoveryService;
29 import org.openhab.core.thing.Thing;
30 import org.openhab.core.thing.ThingTypeUID;
31 import org.openhab.core.thing.ThingUID;
32 import org.osgi.service.component.annotations.Component;
33 import org.osgi.service.component.annotations.ServiceScope;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 import com.google.gson.JsonArray;
38 import com.google.gson.JsonElement;
39 import com.google.gson.JsonObject;
40
41 /**
42  * Handler class for TAPO Smart Home thing discovery
43  *
44  * @author Christian Wild - Initial contribution
45  */
46 @Component(scope = ServiceScope.PROTOTYPE, service = TapoDiscoveryService.class)
47 @NonNullByDefault
48 public class TapoDiscoveryService extends AbstractThingHandlerDiscoveryService<TapoBridgeHandler> {
49     private final Logger logger = LoggerFactory.getLogger(TapoDiscoveryService.class);
50
51     /***********************************
52      *
53      * INITIALIZATION
54      *
55      ************************************/
56
57     /**
58      * INIT CLASS
59      */
60     public TapoDiscoveryService() {
61         super(TapoBridgeHandler.class, SUPPORTED_THING_TYPES_UIDS, TAPO_DISCOVERY_TIMEOUT_S, false);
62     }
63
64     @Override
65     public void initialize() {
66         thingHandler.setDiscoveryService(this);
67         TapoBridgeConfiguration config = thingHandler.getBridgeConfig();
68         modified(Map.of(DiscoveryService.CONFIG_PROPERTY_BACKGROUND_DISCOVERY, config.cloudDiscovery));
69         super.initialize();
70     }
71
72     /***********************************
73      *
74      * SCAN HANDLING
75      *
76      ************************************/
77
78     /**
79      * Start scan manually
80      */
81     @Override
82     public void startScan() {
83         removeOlderResults(getTimestampOfLastScan());
84         JsonArray jsonArray = thingHandler.getDeviceList();
85         handleCloudDevices(jsonArray);
86     }
87
88     /***********************************
89      *
90      * handle Results
91      *
92      ************************************/
93
94     /**
95      * CREATE DISCOVERY RESULT
96      * creates discoveryResult (Thing) from JsonObject got from Cloud
97      * 
98      * @param device JsonObject with device information
99      * @return DiscoveryResult-Object
100      */
101     public DiscoveryResult createResult(JsonObject device) {
102         String deviceModel = getDeviceModel(device);
103         String label = getDeviceLabel(device);
104         String deviceMAC = device.get(CLOUD_JSON_KEY_MAC).getAsString();
105         ThingTypeUID thingTypeUID = new ThingTypeUID(BINDING_ID, deviceModel);
106
107         /* create properties */
108         Map<String, Object> properties = new HashMap<>();
109         properties.put(Thing.PROPERTY_VENDOR, DEVICE_VENDOR);
110         properties.put(Thing.PROPERTY_MAC_ADDRESS, formatMac(deviceMAC, MAC_DIVISION_CHAR));
111         properties.put(Thing.PROPERTY_FIRMWARE_VERSION, device.get(CLOUD_JSON_KEY_FW).getAsString());
112         properties.put(Thing.PROPERTY_HARDWARE_VERSION, device.get(CLOUD_JSON_KEY_HW).getAsString());
113         properties.put(Thing.PROPERTY_MODEL_ID, deviceModel);
114         properties.put(Thing.PROPERTY_SERIAL_NUMBER, device.get(CLOUD_JSON_KEY_ID).getAsString());
115
116         logger.debug("device {} discovered", deviceModel);
117         ThingUID bridgeUID = thingHandler.getUID();
118         ThingUID thingUID = new ThingUID(thingTypeUID, bridgeUID, deviceMAC);
119         return DiscoveryResultBuilder.create(thingUID).withProperties(properties)
120                 .withRepresentationProperty(DEVICE_REPRESENTATION_PROPERTY).withBridge(bridgeUID).withLabel(label)
121                 .build();
122     }
123
124     /**
125      * work with result from get devices from cloud devices
126      * 
127      * @param deviceList
128      */
129     protected void handleCloudDevices(JsonArray deviceList) {
130         try {
131             for (JsonElement deviceElement : deviceList) {
132                 if (deviceElement.isJsonObject()) {
133                     JsonObject device = deviceElement.getAsJsonObject();
134                     String deviceModel = getDeviceModel(device);
135                     ThingTypeUID thingTypeUID = new ThingTypeUID(BINDING_ID, deviceModel);
136
137                     /* create thing */
138                     if (SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID)) {
139                         DiscoveryResult discoveryResult = createResult(device);
140                         thingDiscovered(discoveryResult);
141                     }
142                 }
143             }
144         } catch (Exception e) {
145             logger.debug("error handling CloudDevices", e);
146         }
147     }
148
149     /**
150      * GET DEVICEMODEL
151      * 
152      * @param device JsonObject with deviceData
153      * @return String with DeviceModel
154      */
155     protected String getDeviceModel(JsonObject device) {
156         try {
157             String deviceModel = device.get(CLOUD_JSON_KEY_MODEL).getAsString();
158             deviceModel = deviceModel.replaceAll("\\(.*\\)", ""); // replace (DE)
159             deviceModel = deviceModel.replace("Tapo", "");
160             deviceModel = deviceModel.replace("Series", "");
161             deviceModel = deviceModel.trim();
162             deviceModel = deviceModel.replace(" ", "_");
163             return deviceModel;
164         } catch (Exception e) {
165             logger.debug("error getDeviceModel", e);
166             return "";
167         }
168     }
169
170     /**
171      * GET DEVICE LABEL
172      * 
173      * @param device JsonObject with deviceData
174      * @return String with DeviceLabel
175      */
176     protected String getDeviceLabel(JsonObject device) {
177         try {
178             String deviceLabel = "";
179             String deviceModel = getDeviceModel(device);
180             ThingTypeUID deviceUID = new ThingTypeUID(BINDING_ID, deviceModel);
181
182             if (SUPPORTED_SMART_PLUG_UIDS.contains(deviceUID)) {
183                 deviceLabel = DEVICE_DESCRIPTION_SMART_PLUG;
184             } else if (SUPPORTED_WHITE_BULB_UIDS.contains(deviceUID)) {
185                 deviceLabel = DEVICE_DESCRIPTION_WHITE_BULB;
186             } else if (SUPPORTED_COLOR_BULB_UIDS.contains(deviceUID)) {
187                 deviceLabel = DEVICE_DESCRIPTION_COLOR_BULB;
188             }
189             return DEVICE_VENDOR + " " + deviceModel + " " + deviceLabel;
190         } catch (Exception e) {
191             logger.debug("error getDeviceLabel", e);
192             return "";
193         }
194     }
195 }