]> git.basschouten.com Git - openhab-addons.git/blob
db18e1ba4a75e215bc2bcf6f80286f9d9c1fa2ba
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.neeo.internal.discovery;
14
15 import static org.openhab.binding.neeo.internal.NeeoConstants.BRIDGE_TYPE_BRAIN;
16
17 import java.net.InetAddress;
18 import java.net.UnknownHostException;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.Map;
22 import java.util.Objects;
23 import java.util.Set;
24
25 import javax.jmdns.ServiceInfo;
26
27 import org.apache.commons.lang.StringUtils;
28 import org.eclipse.jdt.annotation.NonNullByDefault;
29 import org.eclipse.jdt.annotation.Nullable;
30 import org.openhab.binding.neeo.internal.NeeoConstants;
31 import org.openhab.core.config.discovery.DiscoveryResult;
32 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
33 import org.openhab.core.config.discovery.mdns.MDNSDiscoveryParticipant;
34 import org.openhab.core.thing.ThingTypeUID;
35 import org.openhab.core.thing.ThingUID;
36 import org.osgi.service.component.annotations.Component;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 /**
41  * Implementation of {@link MDNSDiscoveryParticipant} that will discover NEEO brain(s).
42  *
43  * @author Tim Roberts - initial contribution
44  */
45 @NonNullByDefault
46 @Component(immediate = true)
47 public class NeeoBrainDiscovery implements MDNSDiscoveryParticipant {
48
49     /** The logger */
50     private Logger logger = LoggerFactory.getLogger(NeeoBrainDiscovery.class);
51
52     @Override
53     public Set<@Nullable ThingTypeUID> getSupportedThingTypeUIDs() {
54         return Collections.singleton(BRIDGE_TYPE_BRAIN);
55     }
56
57     @Override
58     public String getServiceType() {
59         return NeeoConstants.NEEO_MDNS_TYPE;
60     }
61
62     @Nullable
63     @Override
64     public DiscoveryResult createResult(@Nullable ServiceInfo service) {
65         if (service == null) {
66             return null;
67         }
68
69         final ThingUID uid = getThingUID(service);
70         if (uid == null) {
71             return null;
72         }
73
74         logger.debug("createResult is evaluating: {}", service);
75
76         final Map<String, Object> properties = new HashMap<>(2);
77
78         final InetAddress ip = getIpAddress(service);
79         if (ip == null) {
80             logger.debug("Application not 'neeo' in MDNS serviceinfo: {}", service);
81             return null;
82         }
83         final String inetAddress = ip.getHostAddress();
84
85         final String id = uid.getId();
86         final String label = service.getName() + " (" + id + ")";
87
88         properties.put(NeeoConstants.CONFIG_IPADDRESS, inetAddress);
89         properties.put(NeeoConstants.CONFIG_ENABLEFORWARDACTIONS, true);
90
91         logger.debug("Adding NEEO Brain to inbox: {} at {}", id, inetAddress);
92         return DiscoveryResultBuilder.create(uid).withProperties(properties).withLabel(label).build();
93     }
94
95     @Nullable
96     @Override
97     public ThingUID getThingUID(@Nullable ServiceInfo service) {
98         if (service == null) {
99             return null;
100         }
101
102         logger.debug("getThingUID is evaluating: {}", service);
103         if (!StringUtils.equals("neeo", service.getApplication())) {
104             logger.debug("Application not 'neeo' in MDNS serviceinfo: {}", service);
105             return null;
106         }
107
108         if (getIpAddress(service) == null) {
109             logger.debug("No IP address found in MDNS serviceinfo: {}", service);
110             return null;
111         }
112
113         String model = service.getPropertyString("hon"); // model
114         if (model == null) {
115             final String server = service.getServer(); // NEEO-xxxxx.local.
116             if (server != null) {
117                 final int idx = server.indexOf(".");
118                 if (idx >= 0) {
119                     model = server.substring(0, idx);
120                 }
121             }
122         }
123         if (model == null || model.length() <= 5 || !model.toLowerCase().startsWith("neeo")) {
124             logger.debug("No 'hon' found in MDNS serviceinfo: {}", service);
125             return null;
126         }
127
128         final String id = model.substring(5);
129         logger.debug("NEEO Brain Found: {}", id);
130
131         return new ThingUID(BRIDGE_TYPE_BRAIN, id);
132     }
133
134     /**
135      * Gets the ip address found in the {@link ServiceInfo}
136      *
137      * @param service a non-null service
138      * @return the ip address of the service or null if none found.
139      */
140     @Nullable
141     private InetAddress getIpAddress(ServiceInfo service) {
142         Objects.requireNonNull(service, "service cannot be null");
143
144         for (String addr : service.getHostAddresses()) {
145             try {
146                 return InetAddress.getByName(addr);
147             } catch (UnknownHostException e) {
148                 // ignore
149             }
150         }
151
152         for (InetAddress addr : service.getInet4Addresses()) {
153             return addr;
154         }
155         // Fallback for Inet6addresses
156         for (InetAddress addr : service.getInet6Addresses()) {
157             return addr;
158         }
159         return null;
160     }
161 }