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