]> git.basschouten.com Git - openhab-addons.git/blob
d8f5d9862d01ffbed051b72412fa6f623fd36793
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 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.hdpowerview.internal.discovery;
14
15 import java.util.Collections;
16 import java.util.List;
17 import java.util.concurrent.ScheduledFuture;
18 import java.util.concurrent.TimeUnit;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants;
23 import org.openhab.binding.hdpowerview.internal.HDPowerViewWebTargets;
24 import org.openhab.binding.hdpowerview.internal.api.responses.RepeaterData;
25 import org.openhab.binding.hdpowerview.internal.api.responses.Shades;
26 import org.openhab.binding.hdpowerview.internal.api.responses.Shades.ShadeData;
27 import org.openhab.binding.hdpowerview.internal.config.HDPowerViewRepeaterConfiguration;
28 import org.openhab.binding.hdpowerview.internal.config.HDPowerViewShadeConfiguration;
29 import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase;
30 import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase.Capabilities;
31 import org.openhab.binding.hdpowerview.internal.exceptions.HubException;
32 import org.openhab.binding.hdpowerview.internal.exceptions.HubInvalidResponseException;
33 import org.openhab.binding.hdpowerview.internal.exceptions.HubMaintenanceException;
34 import org.openhab.binding.hdpowerview.internal.exceptions.HubProcessingException;
35 import org.openhab.binding.hdpowerview.internal.handler.HDPowerViewHubHandler;
36 import org.openhab.core.config.discovery.AbstractDiscoveryService;
37 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
38 import org.openhab.core.thing.ThingUID;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42 /**
43  * Discovers an HD PowerView Shade from an existing hub
44  *
45  * @author Andy Lintner - Initial contribution
46  */
47 @NonNullByDefault
48 public class HDPowerViewDeviceDiscoveryService extends AbstractDiscoveryService {
49
50     private final Logger logger = LoggerFactory.getLogger(HDPowerViewDeviceDiscoveryService.class);
51     private final HDPowerViewHubHandler hub;
52     private final Runnable scanner;
53     private @Nullable ScheduledFuture<?> backgroundFuture;
54     private final ShadeCapabilitiesDatabase db = new ShadeCapabilitiesDatabase();
55
56     public HDPowerViewDeviceDiscoveryService(HDPowerViewHubHandler hub) {
57         super(Collections.singleton(HDPowerViewBindingConstants.THING_TYPE_SHADE), 600, true);
58         this.hub = hub;
59         this.scanner = createScanner();
60     }
61
62     @Override
63     protected void startScan() {
64         scheduler.execute(scanner);
65     }
66
67     @Override
68     protected void startBackgroundDiscovery() {
69         ScheduledFuture<?> backgroundFuture = this.backgroundFuture;
70         if (backgroundFuture != null && !backgroundFuture.isDone()) {
71             backgroundFuture.cancel(true);
72         }
73         this.backgroundFuture = scheduler.scheduleWithFixedDelay(scanner, 0, 60, TimeUnit.SECONDS);
74     }
75
76     @Override
77     protected void stopBackgroundDiscovery() {
78         ScheduledFuture<?> backgroundFuture = this.backgroundFuture;
79         if (backgroundFuture != null && !backgroundFuture.isDone()) {
80             backgroundFuture.cancel(true);
81             this.backgroundFuture = null;
82         }
83         super.stopBackgroundDiscovery();
84     }
85
86     private Runnable createScanner() {
87         return () -> {
88             try {
89                 HDPowerViewWebTargets webTargets = hub.getWebTargets();
90                 if (webTargets == null) {
91                     throw new HubProcessingException("Web targets not initialized");
92                 }
93                 discoverShades(webTargets);
94                 discoverRepeaters(webTargets);
95             } catch (HubMaintenanceException e) {
96                 // exceptions are logged in HDPowerViewWebTargets
97             } catch (HubException e) {
98                 logger.warn("Unexpected error: {}", e.getMessage());
99             }
100             stopScan();
101         };
102     }
103
104     private void discoverShades(HDPowerViewWebTargets webTargets)
105             throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException {
106         Shades shades = webTargets.getShades();
107         List<ShadeData> shadesData = shades.shadeData;
108         if (shadesData == null) {
109             return;
110         }
111         ThingUID bridgeUid = hub.getThing().getUID();
112         for (ShadeData shadeData : shadesData) {
113             if (shadeData.id == 0) {
114                 continue;
115             }
116             String id = Integer.toString(shadeData.id);
117             ThingUID thingUID = new ThingUID(HDPowerViewBindingConstants.THING_TYPE_SHADE, bridgeUid, id);
118             Capabilities capabilities = db.getCapabilities(shadeData.capabilities);
119
120             DiscoveryResultBuilder builder = DiscoveryResultBuilder.create(thingUID).withLabel(shadeData.getName())
121                     .withBridge(bridgeUid).withProperty(HDPowerViewShadeConfiguration.ID, id)
122                     .withProperty(HDPowerViewBindingConstants.PROPERTY_SHADE_TYPE,
123                             db.getType(shadeData.type).toString())
124                     .withProperty(HDPowerViewBindingConstants.PROPERTY_SHADE_CAPABILITIES, capabilities.toString())
125                     .withRepresentationProperty(HDPowerViewShadeConfiguration.ID);
126
127             logger.debug("Hub discovered shade '{}'", id);
128             thingDiscovered(builder.build());
129         }
130     }
131
132     private void discoverRepeaters(HDPowerViewWebTargets webTargets)
133             throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException {
134         List<RepeaterData> repeaters = webTargets.getRepeaters().repeaterData;
135         if (repeaters == null) {
136             return;
137         }
138         ThingUID bridgeUid = hub.getThing().getUID();
139         for (RepeaterData repeaterData : repeaters) {
140             if (repeaterData.id == 0) {
141                 continue;
142             }
143             String id = Integer.toString(repeaterData.id);
144             ThingUID thingUid = new ThingUID(HDPowerViewBindingConstants.THING_TYPE_REPEATER, bridgeUid, id);
145
146             DiscoveryResultBuilder builder = DiscoveryResultBuilder.create(thingUid).withLabel(repeaterData.getName())
147                     .withBridge(bridgeUid).withProperty(HDPowerViewRepeaterConfiguration.ID, id)
148                     .withRepresentationProperty(HDPowerViewRepeaterConfiguration.ID);
149
150             logger.debug("Hub discovered repeater '{}'", id);
151             thingDiscovered(builder.build());
152         }
153     }
154 }