]> git.basschouten.com Git - openhab-addons.git/blob
28a2ed31fb4b5fe44aa2e5f6df6ceeee026f882c
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.mihome.internal.discovery;
14
15 import static org.openhab.binding.mihome.internal.ModelMapper.*;
16 import static org.openhab.binding.mihome.internal.XiaomiGatewayBindingConstants.*;
17
18 import java.util.Arrays;
19 import java.util.Date;
20 import java.util.HashMap;
21 import java.util.HashSet;
22 import java.util.Map;
23 import java.util.Set;
24 import java.util.concurrent.TimeUnit;
25
26 import org.openhab.binding.mihome.internal.XiaomiItemUpdateListener;
27 import org.openhab.binding.mihome.internal.handler.XiaomiBridgeHandler;
28 import org.openhab.core.config.discovery.AbstractDiscoveryService;
29 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
30 import org.openhab.core.thing.ThingTypeUID;
31 import org.openhab.core.thing.ThingUID;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 import com.google.gson.JsonObject;
36
37 /**
38  * Discovery service for items/sensors.
39  *
40  * @author Patrick Boos - Initial contribution
41  */
42 public class XiaomiItemDiscoveryService extends AbstractDiscoveryService implements XiaomiItemUpdateListener {
43
44     public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(Arrays.asList(THING_TYPE_GATEWAY,
45             THING_TYPE_SENSOR_HT, THING_TYPE_SENSOR_AQARA_WEATHER_V1, THING_TYPE_SENSOR_MOTION,
46             THING_TYPE_SENSOR_AQARA_MOTION, THING_TYPE_SENSOR_SWITCH, THING_TYPE_SENSOR_AQARA_SWITCH,
47             THING_TYPE_SENSOR_MAGNET, THING_TYPE_SENSOR_AQARA_LOCK, THING_TYPE_SENSOR_AQARA_MAGNET,
48             THING_TYPE_SENSOR_CUBE, THING_TYPE_SENSOR_AQARA_VIBRATION, THING_TYPE_SENSOR_AQARA1,
49             THING_TYPE_SENSOR_AQARA2, THING_TYPE_SENSOR_GAS, THING_TYPE_SENSOR_SMOKE, THING_TYPE_SENSOR_WATER,
50             THING_TYPE_ACTOR_AQARA1, THING_TYPE_ACTOR_AQARA2, THING_TYPE_ACTOR_PLUG, THING_TYPE_ACTOR_AQARA_ZERO1,
51             THING_TYPE_ACTOR_AQARA_ZERO2, THING_TYPE_ACTOR_CURTAIN, THING_TYPE_BASIC));
52
53     private static final int DISCOVERY_TIMEOUT_SEC = 30;
54     private final XiaomiBridgeHandler xiaomiBridgeHandler;
55
56     private final Logger logger = LoggerFactory.getLogger(XiaomiItemDiscoveryService.class);
57
58     public XiaomiItemDiscoveryService(XiaomiBridgeHandler xiaomiBridgeHandler) {
59         super(SUPPORTED_THING_TYPES, DISCOVERY_TIMEOUT_SEC, true);
60         this.xiaomiBridgeHandler = xiaomiBridgeHandler;
61         xiaomiBridgeHandler.registerItemListener(this);
62     }
63
64     @Override
65     public void startScan() {
66         logger.debug("Start scan for items");
67         xiaomiBridgeHandler.registerItemListener(this); // this will as well get us all items
68         xiaomiBridgeHandler.discoverItems(TimeUnit.SECONDS.toMillis(DISCOVERY_TIMEOUT_SEC));
69     }
70
71     @Override
72     protected synchronized void stopScan() {
73         super.stopScan();
74         removeOlderResults(getTimestampOfLastScan());
75     }
76
77     @Override
78     public void deactivate() {
79         super.deactivate();
80         xiaomiBridgeHandler.unregisterItemListener(this);
81     }
82
83     @Override
84     public int getScanTimeout() {
85         return DISCOVERY_TIMEOUT_SEC;
86     }
87
88     public void onHandlerRemoved() {
89         removeOlderResults(new Date().getTime());
90     }
91
92     @Override
93     public void onItemUpdate(String sid, String command, JsonObject data) {
94         if ("read_ack".equals(command) || "report".equals(command) || "heartbeat".equals(command)) {
95             String model = data.get("model").getAsString();
96
97             ThingTypeUID thingType = getThingTypeForModel(model);
98             String modelLabel = getLabelForModel(model);
99             if (thingType == null) {
100                 logger.warn("Discovered unsupported device with id \"{}\" -> Creating Basic Device Thing", model);
101                 thingType = THING_TYPE_BASIC;
102                 modelLabel = String.format("Unsupported Xiaomi MiHome Device \"%s\"", model);
103             }
104
105             Map<String, Object> properties = new HashMap<>(1);
106             properties.put(ITEM_ID, sid);
107
108             ThingUID bridgeUID = xiaomiBridgeHandler.getThing().getUID();
109             ThingUID thingUID = new ThingUID(thingType, bridgeUID, sid);
110
111             logger.debug("Discovered device - sid: {} model: {}", sid, model);
112             thingDiscovered(DiscoveryResultBuilder.create(thingUID).withThingType(thingType).withProperties(properties)
113                     .withRepresentationProperty(ITEM_ID).withLabel(modelLabel).withBridge(bridgeUID).build());
114         }
115     }
116
117     @Override
118     public String getItemId() {
119         // The discovery service is not bound to a specific device
120         return null;
121     }
122 }