]> git.basschouten.com Git - openhab-addons.git/blob
9bde70ba1686ee30d233e9021961d7c946b056f5
[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.bticinosmarther.internal.discovery;
14
15 import static org.openhab.binding.bticinosmarther.internal.SmartherBindingConstants.*;
16
17 import java.util.Collections;
18 import java.util.Date;
19 import java.util.HashMap;
20 import java.util.Map;
21 import java.util.Set;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.openhab.binding.bticinosmarther.internal.account.SmartherAccountHandler;
26 import org.openhab.binding.bticinosmarther.internal.api.dto.Location;
27 import org.openhab.binding.bticinosmarther.internal.api.dto.Module;
28 import org.openhab.core.config.discovery.AbstractDiscoveryService;
29 import org.openhab.core.config.discovery.DiscoveryResult;
30 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
31 import org.openhab.core.config.discovery.DiscoveryService;
32 import org.openhab.core.thing.ThingTypeUID;
33 import org.openhab.core.thing.ThingUID;
34 import org.openhab.core.thing.binding.ThingHandler;
35 import org.openhab.core.thing.binding.ThingHandlerService;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * The {@code SmartherModuleDiscoveryService} queries the Smarther API gateway to discover available Chronothermostat
41  * modules inside existing plants registered under the configured Bridges.
42  *
43  * @author Fabio Possieri - Initial contribution
44  */
45 @NonNullByDefault
46 public class SmartherModuleDiscoveryService extends AbstractDiscoveryService
47         implements DiscoveryService, ThingHandlerService {
48
49     // Only modules can be discovered. A bridge must be manually added.
50     private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.singleton(THING_TYPE_MODULE);
51
52     private static final int DISCOVERY_TIME_SECONDS = 30;
53
54     private static final String ID_SEPARATOR = "-";
55
56     private final Logger logger = LoggerFactory.getLogger(SmartherModuleDiscoveryService.class);
57
58     private @Nullable SmartherAccountHandler bridgeHandler;
59     private @Nullable ThingUID bridgeUID;
60
61     /**
62      * Constructs a {@code SmartherModuleDiscoveryService}.
63      */
64     public SmartherModuleDiscoveryService() {
65         super(SUPPORTED_THING_TYPES_UIDS, DISCOVERY_TIME_SECONDS);
66     }
67
68     @Override
69     public Set<ThingTypeUID> getSupportedThingTypes() {
70         return SUPPORTED_THING_TYPES_UIDS;
71     }
72
73     @Override
74     public void activate() {
75         logger.debug("Bridge[{}] Activating chronothermostat discovery service", this.bridgeUID);
76         Map<String, Object> properties = new HashMap<>();
77         properties.put(DiscoveryService.CONFIG_PROPERTY_BACKGROUND_DISCOVERY, Boolean.TRUE);
78         super.activate(properties);
79     }
80
81     @Override
82     public void deactivate() {
83         logger.debug("Bridge[{}] Deactivating chronothermostat discovery service", this.bridgeUID);
84         removeOlderResults(new Date().getTime());
85     }
86
87     @Override
88     public void setThingHandler(@Nullable ThingHandler handler) {
89         if (handler instanceof SmartherAccountHandler) {
90             final SmartherAccountHandler localBridgeHandler = (SmartherAccountHandler) handler;
91             this.bridgeHandler = localBridgeHandler;
92             this.bridgeUID = localBridgeHandler.getUID();
93         }
94     }
95
96     @Override
97     public @Nullable ThingHandler getThingHandler() {
98         return this.bridgeHandler;
99     }
100
101     @Override
102     protected void startBackgroundDiscovery() {
103         logger.debug("Bridge[{}] Performing background discovery scan for chronothermostats", this.bridgeUID);
104         discoverChronothermostats();
105     }
106
107     @Override
108     protected void startScan() {
109         logger.debug("Bridge[{}] Starting discovery scan for chronothermostats", this.bridgeUID);
110         discoverChronothermostats();
111     }
112
113     @Override
114     public synchronized void abortScan() {
115         super.abortScan();
116     }
117
118     @Override
119     protected synchronized void stopScan() {
120         super.stopScan();
121         removeOlderResults(getTimestampOfLastScan());
122     }
123
124     /**
125      * Discovers Chronothermostat devices for the given bridge handler.
126      */
127     private synchronized void discoverChronothermostats() {
128         final SmartherAccountHandler localBridgeHandler = this.bridgeHandler;
129         if (localBridgeHandler != null) {
130             // If the bridge is not online no other thing devices can be found, so no reason to scan at this moment
131             if (localBridgeHandler.isOnline()) {
132                 localBridgeHandler.getLocations()
133                         .forEach(l -> localBridgeHandler.getLocationModules(l).forEach(m -> addDiscoveredDevice(l, m)));
134             }
135         }
136     }
137
138     /**
139      * Creates a Chronothermostat module Thing based on the remotely discovered location and module.
140      *
141      * @param location
142      *            the location containing the discovered module
143      * @param module
144      *            the discovered module
145      */
146     private void addDiscoveredDevice(Location location, Module module) {
147         ThingUID localBridgeUID = this.bridgeUID;
148         if (localBridgeUID != null) {
149             Map<String, Object> properties = new HashMap<>();
150             properties.put(PROPERTY_PLANT_ID, location.getPlantId());
151             properties.put(PROPERTY_MODULE_ID, module.getId());
152             properties.put(PROPERTY_MODULE_NAME, module.getName());
153             properties.put(PROPERTY_DEVICE_TYPE, module.getDeviceType());
154
155             ThingUID thingUID = new ThingUID(THING_TYPE_MODULE, localBridgeUID, getThingIdFromModule(module));
156
157             final DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withBridge(localBridgeUID)
158                     .withProperties(properties).withRepresentationProperty(PROPERTY_MODULE_ID)
159                     .withLabel(module.getName()).build();
160             thingDiscovered(discoveryResult);
161             logger.debug("Bridge[{}] Chronothermostat with id '{}' and name '{}' added to Inbox with UID '{}'",
162                     localBridgeUID, module.getId(), module.getName(), thingUID);
163         }
164     }
165
166     /**
167      * Generates the Thing identifier based on the Chronothermostat module identifier.
168      *
169      * @param module
170      *            the Chronothermostat module to use
171      *
172      * @return a string containing the generated Thing identifier
173      */
174     private String getThingIdFromModule(Module module) {
175         final String moduleId = module.getId();
176         return moduleId.substring(0, moduleId.indexOf(ID_SEPARATOR));
177     }
178 }