]> git.basschouten.com Git - openhab-addons.git/blob
1e6921638467211cfb00efa9e419654e6e0d45d3
[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.plugwiseha.internal.discovery;
14
15 import static org.openhab.binding.plugwiseha.internal.PlugwiseHABindingConstants.*;
16
17 import java.util.HashMap;
18 import java.util.Map;
19 import java.util.concurrent.ScheduledFuture;
20 import java.util.concurrent.TimeUnit;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.openhab.binding.plugwiseha.internal.PlugwiseHABindingConstants;
25 import org.openhab.binding.plugwiseha.internal.api.exception.PlugwiseHAException;
26 import org.openhab.binding.plugwiseha.internal.api.model.PlugwiseHAController;
27 import org.openhab.binding.plugwiseha.internal.api.model.dto.Appliance;
28 import org.openhab.binding.plugwiseha.internal.api.model.dto.DomainObjects;
29 import org.openhab.binding.plugwiseha.internal.api.model.dto.Location;
30 import org.openhab.binding.plugwiseha.internal.handler.PlugwiseHABridgeHandler;
31 import org.openhab.core.config.discovery.AbstractDiscoveryService;
32 import org.openhab.core.config.discovery.DiscoveryResult;
33 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
34 import org.openhab.core.thing.ThingUID;
35 import org.openhab.core.thing.binding.ThingHandler;
36 import org.openhab.core.thing.binding.ThingHandlerService;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 /**
41  * The {@link PlugwiseHADiscoveryService} class is capable of discovering the
42  * available data from the Plugwise Home Automation gateway
43  *
44  * @author Bas van Wetten - Initial contribution
45  * @author Leo Siepel - finish initial contribution
46  */
47 @NonNullByDefault
48 public class PlugwiseHADiscoveryService extends AbstractDiscoveryService implements ThingHandlerService {
49
50     private final Logger logger = LoggerFactory.getLogger(PlugwiseHADiscoveryService.class);
51     private static final int TIMEOUT_SECONDS = 5;
52     private static final int REFRESH_SECONDS = 600;
53     private @Nullable PlugwiseHABridgeHandler bridgeHandler;
54     private @Nullable ScheduledFuture<?> discoveryFuture;
55
56     public PlugwiseHADiscoveryService() {
57         super(SUPPORTED_THING_TYPES_UIDS, TIMEOUT_SECONDS, true);
58     }
59
60     @Override
61     protected synchronized void startScan() {
62         try {
63             discoverDomainObjects();
64         } catch (PlugwiseHAException e) {
65             // Ignore silently
66         }
67     }
68
69     @Override
70     protected synchronized void stopScan() {
71         super.stopScan();
72         removeOlderResults(getTimestampOfLastScan());
73     }
74
75     @Override
76     protected void startBackgroundDiscovery() {
77         logger.debug("Start Plugwise Home Automation background discovery");
78
79         ScheduledFuture<?> localDiscoveryFuture = discoveryFuture;
80         if (localDiscoveryFuture == null || localDiscoveryFuture.isCancelled()) {
81             discoveryFuture = scheduler.scheduleWithFixedDelay(this::startScan, 30, REFRESH_SECONDS, TimeUnit.SECONDS);
82         }
83     }
84
85     @Override
86     protected void stopBackgroundDiscovery() {
87         logger.debug("Stopping Plugwise Home Automation background discovery");
88
89         ScheduledFuture<?> localDiscoveryFuture = discoveryFuture;
90         if (localDiscoveryFuture != null) {
91             if (!localDiscoveryFuture.isCancelled()) {
92                 localDiscoveryFuture.cancel(true);
93                 localDiscoveryFuture = null;
94             }
95         }
96     }
97
98     @Override
99     public void deactivate() {
100         super.deactivate();
101     }
102
103     @Override
104     public void setThingHandler(@Nullable ThingHandler handler) {
105         if (handler instanceof PlugwiseHABridgeHandler bridgeHandler) {
106             this.bridgeHandler = bridgeHandler;
107         }
108     }
109
110     @Override
111     public @Nullable ThingHandler getThingHandler() {
112         return bridgeHandler;
113     }
114
115     private void discoverDomainObjects() throws PlugwiseHAException {
116         PlugwiseHAController controller = null;
117         PlugwiseHABridgeHandler localBridgeHandler = this.bridgeHandler;
118         if (localBridgeHandler != null) {
119             controller = localBridgeHandler.getController();
120         }
121
122         if (controller != null) {
123             DomainObjects domainObjects = controller.getDomainObjects();
124
125             if (domainObjects != null) {
126                 for (Location location : domainObjects.getLocations().values()) {
127                     // Only add locations with at least 1 appliance (this ignores the 'root' (home)
128                     // location which is the parent of all other locations.)
129                     if (location.applianceCount() > 0) {
130                         locationDiscovery(location);
131                     }
132                 }
133
134                 for (Appliance appliance : domainObjects.getAppliances().values()) {
135                     // Only add appliances that are required/supported for this binding
136                     if (PlugwiseHABindingConstants.SUPPORTED_APPLIANCE_TYPES.contains(appliance.getType())) {
137                         applianceDiscovery(appliance);
138                     }
139                 }
140             }
141         }
142     }
143
144     private void applianceDiscovery(Appliance appliance) {
145         String applianceId = appliance.getId();
146         String applianceName = appliance.getName();
147         String applianceType = appliance.getType();
148
149         PlugwiseHABridgeHandler localBridgeHandler = this.bridgeHandler;
150         if (localBridgeHandler != null) {
151             ThingUID bridgeUID = localBridgeHandler.getThing().getUID();
152
153             ThingUID uid;
154
155             Map<String, Object> configProperties = new HashMap<>();
156
157             configProperties.put(APPLIANCE_CONFIG_ID, applianceId);
158
159             switch (applianceType) {
160                 case "thermostatic_radiator_valve":
161                     uid = new ThingUID(PlugwiseHABindingConstants.THING_TYPE_APPLIANCE_VALVE, bridgeUID, applianceId);
162                     configProperties.put(APPLIANCE_CONFIG_LOWBATTERY, 15);
163                     break;
164                 case "central_heating_pump":
165                     uid = new ThingUID(PlugwiseHABindingConstants.THING_TYPE_APPLIANCE_PUMP, bridgeUID, applianceId);
166                     break;
167                 case "heater_central":
168                     uid = new ThingUID(PlugwiseHABindingConstants.THING_TYPE_APPLIANCE_BOILER, bridgeUID, applianceId);
169                     break;
170                 case "zone_thermostat":
171                     uid = new ThingUID(PlugwiseHABindingConstants.THING_TYPE_APPLIANCE_THERMOSTAT, bridgeUID,
172                             applianceId);
173                     configProperties.put(APPLIANCE_CONFIG_LOWBATTERY, 15);
174                     break;
175                 default:
176                     return;
177             }
178
179             DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(uid).withBridge(bridgeUID)
180                     .withLabel(applianceName).withProperties(configProperties)
181                     .withRepresentationProperty(APPLIANCE_CONFIG_ID).build();
182
183             thingDiscovered(discoveryResult);
184
185             logger.debug("Discovered plugwise appliance type '{}' with name '{}' with id {} ({})", applianceType,
186                     applianceName, applianceId, uid);
187         }
188     }
189
190     private void locationDiscovery(Location location) {
191         String locationId = location.getId();
192         String locationName = location.getName();
193
194         PlugwiseHABridgeHandler localBridgeHandler = this.bridgeHandler;
195         if (localBridgeHandler != null) {
196             ThingUID bridgeUID = localBridgeHandler.getThing().getUID();
197             ThingUID uid = new ThingUID(PlugwiseHABindingConstants.THING_TYPE_ZONE, bridgeUID, locationId);
198
199             Map<String, Object> configProperties = new HashMap<>();
200
201             configProperties.put(ZONE_CONFIG_ID, locationId);
202
203             DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(uid).withBridge(bridgeUID)
204                     .withLabel(locationName).withRepresentationProperty(ZONE_CONFIG_ID).withProperties(configProperties)
205                     .build();
206
207             thingDiscovered(discoveryResult);
208
209             logger.debug("Discovered plugwise zone '{}' with id {} ({})", locationName, locationId, uid);
210         }
211     }
212 }