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