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.vesync.internal.discovery;
15 import static org.openhab.binding.vesync.internal.VeSyncConstants.*;
17 import java.util.Collections;
18 import java.util.HashMap;
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.openhab.binding.vesync.internal.handlers.VeSyncBridgeHandler;
25 import org.openhab.core.config.discovery.AbstractDiscoveryService;
26 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
27 import org.openhab.core.config.discovery.DiscoveryService;
28 import org.openhab.core.thing.ThingStatus;
29 import org.openhab.core.thing.ThingTypeUID;
30 import org.openhab.core.thing.ThingUID;
31 import org.openhab.core.thing.binding.ThingHandler;
32 import org.openhab.core.thing.binding.ThingHandlerService;
33 import org.osgi.service.component.annotations.Component;
36 * The {@link VeSyncDiscoveryService} is an implementation of a discovery service for VeSync devices. The meta-data is
37 * read by the bridge, and the discovery data updated via a callback implemented by the DeviceMetaDataUpdatedHandler.
39 * @author David Godyear - Initial contribution
42 @Component(service = DiscoveryService.class, immediate = true, configurationPid = "discovery.vesync")
43 public class VeSyncDiscoveryService extends AbstractDiscoveryService
44 implements DiscoveryService, ThingHandlerService, DeviceMetaDataUpdatedHandler {
46 private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_BRIDGE);
48 private static final int DISCOVER_TIMEOUT_SECONDS = 5;
50 private @NonNullByDefault({}) VeSyncBridgeHandler bridgeHandler;
51 private @NonNullByDefault({}) ThingUID bridgeUID;
54 * Creates a VeSyncDiscoveryService with enabled autostart.
56 public VeSyncDiscoveryService() {
57 super(SUPPORTED_THING_TYPES, DISCOVER_TIMEOUT_SECONDS);
61 public Set<ThingTypeUID> getSupportedThingTypes() {
62 return SUPPORTED_THING_TYPES;
66 public void activate() {
67 final Map<String, Object> properties = new HashMap<>();
68 properties.put(DiscoveryService.CONFIG_PROPERTY_BACKGROUND_DISCOVERY, Boolean.TRUE);
69 super.activate(properties);
73 public void deactivate() {
78 public void setThingHandler(@Nullable ThingHandler handler) {
79 if (handler instanceof VeSyncBridgeHandler) {
80 bridgeHandler = (VeSyncBridgeHandler) handler;
81 bridgeUID = bridgeHandler.getUID();
86 public @Nullable ThingHandler getThingHandler() {
91 protected void startBackgroundDiscovery() {
92 if (bridgeHandler != null) {
93 bridgeHandler.registerMetaDataUpdatedHandler(this);
98 protected void stopBackgroundDiscovery() {
99 if (bridgeHandler != null) {
100 bridgeHandler.unregisterMetaDataUpdatedHandler(this);
105 protected void startScan() {
106 // If the bridge is not online no other thing devices can be found, so no reason to scan at this moment.
107 removeOlderResults(getTimestampOfLastScan());
108 if (ThingStatus.ONLINE.equals(bridgeHandler.getThing().getStatus())) {
109 bridgeHandler.runDeviceScanSequenceNoAuthErrors();
114 public void handleMetadataRetrieved(VeSyncBridgeHandler handler) {
115 bridgeHandler.getAirPurifiersMetadata().map(apMeta -> {
116 final Map<String, Object> properties = new HashMap<>(6);
117 final String deviceUUID = apMeta.getUuid();
118 properties.put(DEVICE_PROP_DEVICE_NAME, apMeta.getDeviceName());
119 properties.put(DEVICE_PROP_DEVICE_TYPE, apMeta.getDeviceType());
120 properties.put(DEVICE_PROP_DEVICE_MAC_ID, apMeta.getMacId());
121 properties.put(DEVICE_PROP_DEVICE_UUID, deviceUUID);
122 properties.put(DEVICE_PROP_CONFIG_DEVICE_MAC, apMeta.getMacId());
123 properties.put(DEVICE_PROP_CONFIG_DEVICE_NAME, apMeta.getDeviceName());
124 return DiscoveryResultBuilder.create(new ThingUID(THING_TYPE_AIR_PURIFIER, bridgeUID, deviceUUID))
125 .withLabel(apMeta.getDeviceName()).withBridge(bridgeUID).withProperties(properties)
126 .withRepresentationProperty(DEVICE_PROP_DEVICE_MAC_ID).build();
127 }).forEach(this::thingDiscovered);
129 bridgeHandler.getAirHumidifiersMetadata().map(apMeta -> {
130 final Map<String, Object> properties = new HashMap<>(6);
131 final String deviceUUID = apMeta.getUuid();
132 properties.put(DEVICE_PROP_DEVICE_NAME, apMeta.getDeviceName());
133 properties.put(DEVICE_PROP_DEVICE_TYPE, apMeta.getDeviceType());
134 properties.put(DEVICE_PROP_DEVICE_MAC_ID, apMeta.getMacId());
135 properties.put(DEVICE_PROP_DEVICE_UUID, deviceUUID);
136 properties.put(DEVICE_PROP_CONFIG_DEVICE_MAC, apMeta.getMacId());
137 properties.put(DEVICE_PROP_CONFIG_DEVICE_NAME, apMeta.getDeviceName());
138 return DiscoveryResultBuilder.create(new ThingUID(THING_TYPE_AIR_HUMIDIFIER, bridgeUID, deviceUUID))
139 .withLabel(apMeta.getDeviceName()).withBridge(bridgeUID).withProperties(properties)
140 .withRepresentationProperty(DEVICE_PROP_DEVICE_MAC_ID).build();
141 }).forEach(this::thingDiscovered);