]> git.basschouten.com Git - openhab-addons.git/blob
f157abcdded9d89f5bd1254cfb4850161c817a94
[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.vesync.internal.discovery;
14
15 import static org.openhab.binding.vesync.internal.VeSyncConstants.*;
16
17 import java.util.HashMap;
18 import java.util.Map;
19 import java.util.Set;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.openhab.binding.vesync.internal.handlers.VeSyncBaseDeviceHandler;
24 import org.openhab.binding.vesync.internal.handlers.VeSyncBridgeHandler;
25 import org.openhab.binding.vesync.internal.handlers.VeSyncDeviceAirHumidifierHandler;
26 import org.openhab.binding.vesync.internal.handlers.VeSyncDeviceAirPurifierHandler;
27 import org.openhab.core.config.discovery.AbstractDiscoveryService;
28 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
29 import org.openhab.core.config.discovery.DiscoveryService;
30 import org.openhab.core.thing.ThingStatus;
31 import org.openhab.core.thing.ThingTypeUID;
32 import org.openhab.core.thing.ThingUID;
33 import org.openhab.core.thing.binding.ThingHandler;
34 import org.openhab.core.thing.binding.ThingHandlerService;
35 import org.osgi.service.component.annotations.Component;
36
37 /**
38  * The {@link VeSyncDiscoveryService} is an implementation of a discovery service for VeSync devices. The meta-data is
39  * read by the bridge, and the discovery data updated via a callback implemented by the DeviceMetaDataUpdatedHandler.
40  *
41  * @author David Godyear - Initial contribution
42  */
43 @NonNullByDefault
44 @Component(service = DiscoveryService.class, immediate = true, configurationPid = "discovery.vesync")
45 public class VeSyncDiscoveryService extends AbstractDiscoveryService
46         implements DiscoveryService, ThingHandlerService, DeviceMetaDataUpdatedHandler {
47
48     private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Set.of(THING_TYPE_BRIDGE);
49
50     private static final int DISCOVER_TIMEOUT_SECONDS = 5;
51
52     private @NonNullByDefault({}) VeSyncBridgeHandler bridgeHandler;
53     private @NonNullByDefault({}) ThingUID bridgeUID;
54
55     /**
56      * Creates a VeSyncDiscoveryService with enabled autostart.
57      */
58     public VeSyncDiscoveryService() {
59         super(SUPPORTED_THING_TYPES, DISCOVER_TIMEOUT_SECONDS);
60     }
61
62     @Override
63     public Set<ThingTypeUID> getSupportedThingTypes() {
64         return SUPPORTED_THING_TYPES;
65     }
66
67     @Override
68     public void activate() {
69         final Map<String, Object> properties = new HashMap<>();
70         properties.put(DiscoveryService.CONFIG_PROPERTY_BACKGROUND_DISCOVERY, Boolean.TRUE);
71         super.activate(properties);
72     }
73
74     @Override
75     public void deactivate() {
76         super.deactivate();
77     }
78
79     @Override
80     public void setThingHandler(@Nullable ThingHandler handler) {
81         if (handler instanceof VeSyncBridgeHandler veSyncBridgeHandler) {
82             bridgeHandler = veSyncBridgeHandler;
83             bridgeUID = bridgeHandler.getUID();
84         }
85     }
86
87     @Override
88     public @Nullable ThingHandler getThingHandler() {
89         return bridgeHandler;
90     }
91
92     @Override
93     protected void startBackgroundDiscovery() {
94         if (bridgeHandler != null) {
95             bridgeHandler.registerMetaDataUpdatedHandler(this);
96         }
97     }
98
99     @Override
100     protected void stopBackgroundDiscovery() {
101         if (bridgeHandler != null) {
102             bridgeHandler.unregisterMetaDataUpdatedHandler(this);
103         }
104     }
105
106     @Override
107     protected void startScan() {
108         // If the bridge is not online no other thing devices can be found, so no reason to scan at this moment.
109         removeOlderResults(getTimestampOfLastScan());
110         if (ThingStatus.ONLINE.equals(bridgeHandler.getThing().getStatus())) {
111             bridgeHandler.runDeviceScanSequenceNoAuthErrors();
112         }
113     }
114
115     @Override
116     public void handleMetadataRetrieved(VeSyncBridgeHandler handler) {
117         bridgeHandler.getAirPurifiersMetadata().map(apMeta -> {
118             final Map<String, Object> properties = new HashMap<>(6);
119             final String deviceUUID = apMeta.getUuid();
120             properties.put(DEVICE_PROP_DEVICE_NAME, apMeta.getDeviceName());
121             properties.put(DEVICE_PROP_DEVICE_TYPE, apMeta.getDeviceType());
122             properties.put(DEVICE_PROP_DEVICE_FAMILY,
123                     VeSyncBaseDeviceHandler.getDeviceFamilyMetadata(apMeta.getDeviceType(),
124                             VeSyncDeviceAirHumidifierHandler.DEV_TYPE_FAMILY_AIR_HUMIDIFIER,
125                             VeSyncDeviceAirHumidifierHandler.SUPPORTED_MODEL_FAMILIES));
126             properties.put(DEVICE_PROP_DEVICE_MAC_ID, apMeta.getMacId());
127             properties.put(DEVICE_PROP_DEVICE_UUID, deviceUUID);
128             properties.put(DEVICE_PROP_CONFIG_DEVICE_MAC, apMeta.getMacId());
129             properties.put(DEVICE_PROP_CONFIG_DEVICE_NAME, apMeta.getDeviceName());
130             return DiscoveryResultBuilder.create(new ThingUID(THING_TYPE_AIR_PURIFIER, bridgeUID, deviceUUID))
131                     .withLabel(apMeta.getDeviceName()).withBridge(bridgeUID).withProperties(properties)
132                     .withRepresentationProperty(DEVICE_PROP_DEVICE_MAC_ID).build();
133         }).forEach(this::thingDiscovered);
134
135         bridgeHandler.getAirHumidifiersMetadata().map(apMeta -> {
136             final Map<String, Object> properties = new HashMap<>(6);
137             final String deviceUUID = apMeta.getUuid();
138             properties.put(DEVICE_PROP_DEVICE_NAME, apMeta.getDeviceName());
139             properties.put(DEVICE_PROP_DEVICE_TYPE, apMeta.getDeviceType());
140             properties.put(DEVICE_PROP_DEVICE_FAMILY,
141                     VeSyncBaseDeviceHandler.getDeviceFamilyMetadata(apMeta.getDeviceType(),
142                             VeSyncDeviceAirPurifierHandler.DEV_TYPE_FAMILY_AIR_PURIFIER,
143                             VeSyncDeviceAirPurifierHandler.SUPPORTED_MODEL_FAMILIES));
144             properties.put(DEVICE_PROP_DEVICE_MAC_ID, apMeta.getMacId());
145             properties.put(DEVICE_PROP_DEVICE_UUID, deviceUUID);
146             properties.put(DEVICE_PROP_CONFIG_DEVICE_MAC, apMeta.getMacId());
147             properties.put(DEVICE_PROP_CONFIG_DEVICE_NAME, apMeta.getDeviceName());
148             return DiscoveryResultBuilder.create(new ThingUID(THING_TYPE_AIR_HUMIDIFIER, bridgeUID, deviceUUID))
149                     .withLabel(apMeta.getDeviceName()).withBridge(bridgeUID).withProperties(properties)
150                     .withRepresentationProperty(DEVICE_PROP_DEVICE_MAC_ID).build();
151         }).forEach(this::thingDiscovered);
152     }
153 }