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.plugwiseha.internal.discovery;
15 import static org.openhab.binding.plugwiseha.internal.PlugwiseHABindingConstants.*;
17 import java.util.HashMap;
19 import java.util.concurrent.ScheduledFuture;
20 import java.util.concurrent.TimeUnit;
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;
41 * The {@link PlugwiseHADiscoveryService} class is capable of discovering the
42 * available data from the Plugwise Home Automation gateway
44 * @author Bas van Wetten - Initial contribution
45 * @author Leo Siepel - finish initial contribution
48 public class PlugwiseHADiscoveryService extends AbstractDiscoveryService implements ThingHandlerService {
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;
56 public PlugwiseHADiscoveryService() {
57 super(SUPPORTED_THING_TYPES_UIDS, TIMEOUT_SECONDS, true);
61 protected synchronized void startScan() {
63 discoverDomainObjects();
64 } catch (PlugwiseHAException e) {
70 protected synchronized void stopScan() {
72 removeOlderResults(getTimestampOfLastScan());
76 protected void startBackgroundDiscovery() {
77 logger.debug("Start Plugwise Home Automation background discovery");
79 ScheduledFuture<?> localDiscoveryFuture = discoveryFuture;
80 if (localDiscoveryFuture == null || localDiscoveryFuture.isCancelled()) {
81 discoveryFuture = scheduler.scheduleWithFixedDelay(this::startScan, 30, REFRESH_SECONDS, TimeUnit.SECONDS);
86 protected void stopBackgroundDiscovery() {
87 logger.debug("Stopping Plugwise Home Automation background discovery");
89 ScheduledFuture<?> localDiscoveryFuture = discoveryFuture;
90 if (localDiscoveryFuture != null) {
91 if (!localDiscoveryFuture.isCancelled()) {
92 localDiscoveryFuture.cancel(true);
93 localDiscoveryFuture = null;
99 public void deactivate() {
104 public void setThingHandler(@Nullable ThingHandler handler) {
105 if (handler instanceof PlugwiseHABridgeHandler bridgeHandler) {
106 this.bridgeHandler = bridgeHandler;
111 public @Nullable ThingHandler getThingHandler() {
112 return bridgeHandler;
115 private void discoverDomainObjects() throws PlugwiseHAException {
116 PlugwiseHAController controller = null;
117 PlugwiseHABridgeHandler localBridgeHandler = this.bridgeHandler;
118 if (localBridgeHandler != null) {
119 controller = localBridgeHandler.getController();
122 if (controller != null) {
123 DomainObjects domainObjects = controller.getDomainObjects();
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);
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);
144 private void applianceDiscovery(Appliance appliance) {
145 String applianceId = appliance.getId();
146 String applianceName = appliance.getName();
147 String applianceType = appliance.getType();
149 PlugwiseHABridgeHandler localBridgeHandler = this.bridgeHandler;
150 if (localBridgeHandler != null) {
151 ThingUID bridgeUID = localBridgeHandler.getThing().getUID();
155 Map<String, Object> configProperties = new HashMap<>();
157 configProperties.put(APPLIANCE_CONFIG_ID, applianceId);
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);
164 case "central_heating_pump":
165 uid = new ThingUID(PlugwiseHABindingConstants.THING_TYPE_APPLIANCE_PUMP, bridgeUID, applianceId);
167 case "heater_central":
168 uid = new ThingUID(PlugwiseHABindingConstants.THING_TYPE_APPLIANCE_BOILER, bridgeUID, applianceId);
170 case "zone_thermostat":
171 uid = new ThingUID(PlugwiseHABindingConstants.THING_TYPE_APPLIANCE_THERMOSTAT, bridgeUID,
173 configProperties.put(APPLIANCE_CONFIG_LOWBATTERY, 15);
179 DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(uid).withBridge(bridgeUID)
180 .withLabel(applianceName).withProperties(configProperties)
181 .withRepresentationProperty(APPLIANCE_CONFIG_ID).build();
183 thingDiscovered(discoveryResult);
185 logger.debug("Discovered plugwise appliance type '{}' with name '{}' with id {} ({})", applianceType,
186 applianceName, applianceId, uid);
190 private void locationDiscovery(Location location) {
191 String locationId = location.getId();
192 String locationName = location.getName();
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);
199 Map<String, Object> configProperties = new HashMap<>();
201 configProperties.put(ZONE_CONFIG_ID, locationId);
203 DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(uid).withBridge(bridgeUID)
204 .withLabel(locationName).withRepresentationProperty(ZONE_CONFIG_ID).withProperties(configProperties)
207 thingDiscovered(discoveryResult);
209 logger.debug("Discovered plugwise zone '{}' with id {} ({})", locationName, locationId, uid);