]> git.basschouten.com Git - openhab-addons.git/blob
d66ec0b93135ba7591a32075cfe81e3dd756689d
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.miele.internal.discovery;
14
15 import java.io.IOException;
16 import java.net.InetAddress;
17 import java.net.Socket;
18 import java.util.Collections;
19 import java.util.HashMap;
20 import java.util.Map;
21 import java.util.Set;
22
23 import javax.jmdns.ServiceInfo;
24
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.openhab.binding.miele.internal.MieleBindingConstants;
27 import org.openhab.core.config.discovery.DiscoveryResult;
28 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
29 import org.openhab.core.config.discovery.mdns.MDNSDiscoveryParticipant;
30 import org.openhab.core.config.discovery.mdns.internal.MDNSDiscoveryService;
31 import org.openhab.core.thing.ThingTypeUID;
32 import org.openhab.core.thing.ThingUID;
33 import org.osgi.service.component.annotations.Activate;
34 import org.osgi.service.component.annotations.Component;
35 import org.osgi.service.component.annotations.Modified;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * The {@link MieleMDNSDiscoveryParticipant} is responsible for discovering Miele XGW3000 Gateways. It uses the central
41  * {@link MDNSDiscoveryService}.
42  *
43  * @author Karel Goderis - Initial contribution
44  * @author Martin Lepsy - Added check for Miele gateway for cleaner discovery
45  * @author Jacob Laursen - Fixed multicast and protocol support (ZigBee/LAN)
46  */
47 @Component(configurationPid = "discovery.miele")
48 public class MieleMDNSDiscoveryParticipant implements MDNSDiscoveryParticipant {
49
50     private final Logger logger = LoggerFactory.getLogger(MieleMDNSDiscoveryParticipant.class);
51     private static final String PATH_TO_CHECK_FOR_XGW3000 = "/rest/";
52     private static final String SERVICE_NAME = "mieleathome";
53     private static final String PATH_PROPERTY_NAME = "path";
54
55     private long removalGracePeriodSeconds = 15;
56
57     @Activate
58     public void activate(@Nullable Map<String, Object> configProperties) {
59         updateRemovalGracePeriod(configProperties);
60     }
61
62     @Modified
63     public void modified(@Nullable Map<String, Object> configProperties) {
64         updateRemovalGracePeriod(configProperties);
65     }
66
67     /**
68      * Update the removalGracePeriodSeconds when the component is activates or modified.
69      *
70      * @param configProperties the passed configuration parameters.
71      */
72     private void updateRemovalGracePeriod(Map<String, Object> configProperties) {
73         if (configProperties != null) {
74             Object value = configProperties.get(MieleBindingConstants.REMOVAL_GRACE_PERIOD);
75             if (value != null) {
76                 try {
77                     removalGracePeriodSeconds = Integer.parseInt(value.toString());
78                 } catch (NumberFormatException e) {
79                     logger.warn("Configuration property '{}' has invalid value: {}",
80                             MieleBindingConstants.REMOVAL_GRACE_PERIOD, value);
81                 }
82             }
83         }
84     }
85
86     @Override
87     public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
88         return Collections.singleton(MieleBindingConstants.THING_TYPE_XGW3000);
89     }
90
91     @Override
92     public String getServiceType() {
93         return "_mieleathome._tcp.local.";
94     }
95
96     @Override
97     public DiscoveryResult createResult(ServiceInfo service) {
98         if (isMieleGateway(service)) {
99             ThingUID uid = getThingUID(service);
100
101             if (uid != null) {
102                 Map<String, Object> properties = new HashMap<>(2);
103
104                 InetAddress[] addresses = service.getInetAddresses();
105                 if (addresses.length > 0 && addresses[0] != null) {
106                     properties.put(MieleBindingConstants.HOST, addresses[0].getHostAddress());
107
108                     Socket socket = null;
109                     try {
110                         socket = new Socket(addresses[0], 80);
111                         InetAddress ourAddress = socket.getLocalAddress();
112                         properties.put(MieleBindingConstants.INTERFACE, ourAddress.getHostAddress());
113                     } catch (IOException e) {
114                         logger.error("An exception occurred while connecting to the Miele Gateway : '{}'",
115                                 e.getMessage());
116                     }
117                 }
118
119                 return DiscoveryResultBuilder.create(uid).withProperties(properties)
120                         .withRepresentationProperty(MieleBindingConstants.HOST).withLabel("Miele XGW3000").build();
121             }
122         }
123         return null;
124     }
125
126     @Override
127     public ThingUID getThingUID(ServiceInfo service) {
128         if (service.getType() != null) {
129             if (service.getType().equals(getServiceType())) {
130                 logger.trace("Discovered a Miele@Home gateway thing with name '{}'", service.getName());
131                 return new ThingUID(MieleBindingConstants.THING_TYPE_XGW3000, service.getName().replace(" ", "_"));
132             }
133         }
134
135         return null;
136     }
137
138     /**
139      * Checks if service is a Miele XGW3000 Gateway
140      *
141      * application must be mieleathome
142      * must contain path with value /rest/
143      *
144      * @param service the service to check
145      * @return true, if the discovered service is a Miele XGW3000 Gateway
146      */
147     private boolean isMieleGateway(ServiceInfo service) {
148         return service.getApplication().contains(SERVICE_NAME) && service.getPropertyString(PATH_PROPERTY_NAME) != null
149                 && service.getPropertyString(PATH_PROPERTY_NAME).equalsIgnoreCase(PATH_TO_CHECK_FOR_XGW3000);
150     }
151
152     /**
153      * Miele devices are sometimes a few seconds late in updating their mDNS announcements, which means that they are
154      * repeatedly removed from, and (re)added to, the Inbox. To prevent this, we override this method to specify an
155      * additional delay period (grace period) to wait before the device is removed from the Inbox.
156      */
157     @Override
158     public long getRemovalGracePeriodSeconds(ServiceInfo serviceInfo) {
159         return removalGracePeriodSeconds;
160     }
161 }