2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.mihome.internal.discovery;
15 import static org.openhab.binding.mihome.internal.ModelMapper.*;
16 import static org.openhab.binding.mihome.internal.XiaomiGatewayBindingConstants.*;
18 import java.util.Arrays;
19 import java.util.Date;
20 import java.util.HashMap;
21 import java.util.HashSet;
24 import java.util.concurrent.TimeUnit;
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;
35 import com.google.gson.JsonObject;
38 * Discovery service for items/sensors.
40 * @author Patrick Boos - Initial contribution
42 public class XiaomiItemDiscoveryService extends AbstractDiscoveryService implements XiaomiItemUpdateListener {
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));
53 private static final int DISCOVERY_TIMEOUT_SEC = 30;
54 private final XiaomiBridgeHandler xiaomiBridgeHandler;
56 private final Logger logger = LoggerFactory.getLogger(XiaomiItemDiscoveryService.class);
58 public XiaomiItemDiscoveryService(XiaomiBridgeHandler xiaomiBridgeHandler) {
59 super(SUPPORTED_THING_TYPES, DISCOVERY_TIMEOUT_SEC, true);
60 this.xiaomiBridgeHandler = xiaomiBridgeHandler;
61 xiaomiBridgeHandler.registerItemListener(this);
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));
72 protected synchronized void stopScan() {
74 removeOlderResults(getTimestampOfLastScan());
78 public void deactivate() {
80 xiaomiBridgeHandler.unregisterItemListener(this);
84 public int getScanTimeout() {
85 return DISCOVERY_TIMEOUT_SEC;
88 public void onHandlerRemoved() {
89 removeOlderResults(new Date().getTime());
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();
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);
105 Map<String, Object> properties = new HashMap<>(1);
106 properties.put(ITEM_ID, sid);
108 ThingUID bridgeUID = xiaomiBridgeHandler.getThing().getUID();
109 ThingUID thingUID = new ThingUID(thingType, bridgeUID, sid);
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());
118 public String getItemId() {
119 // The discovery service is not bound to a specific device