2 * Copyright (c) 2010-2022 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.remoteopenhab.internal.discovery;
15 import static org.openhab.binding.remoteopenhab.internal.RemoteopenhabBindingConstants.*;
16 import static org.openhab.binding.remoteopenhab.internal.config.RemoteopenhabServerConfiguration.*;
18 import java.util.List;
21 import java.util.stream.Collectors;
23 import javax.jmdns.ServiceInfo;
25 import org.eclipse.jdt.annotation.NonNullByDefault;
26 import org.eclipse.jdt.annotation.Nullable;
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.net.NetUtil;
31 import org.openhab.core.thing.ThingTypeUID;
32 import org.openhab.core.thing.ThingUID;
33 import org.osgi.service.component.annotations.Component;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
38 * The {@link RemoteopenhabDiscoveryParticipant} is responsible for discovering
39 * the remote openHAB servers using mDNS discovery service.
41 * @author Laurent Garnier - Initial contribution
44 @Component(service = MDNSDiscoveryParticipant.class, configurationPid = "mdnsdiscovery.remoteopenhab")
45 public class RemoteopenhabDiscoveryParticipant implements MDNSDiscoveryParticipant {
47 private static final String SERVICE_TYPE = "_openhab-server._tcp.local.";
49 private final Logger logger = LoggerFactory.getLogger(RemoteopenhabDiscoveryParticipant.class);
52 public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
53 return SUPPORTED_BRIDGE_TYPES_UIDS;
57 public String getServiceType() {
62 public @Nullable ThingUID getThingUID(ServiceInfo service) {
63 // We use the first host address as thing ID
64 String ip = (service.getHostAddresses() != null && service.getHostAddresses().length > 0
65 && !service.getHostAddresses()[0].isEmpty()) ? service.getHostAddresses()[0].replaceAll("\\[|\\]", "")
67 // Host address matching a local IP address are ignored
68 if (getServiceType().equals(service.getType()) && ip != null && !matchLocalIpAddress(ip)) {
69 return new ThingUID(BRIDGE_TYPE_SERVER, ip.replaceAll("[^A-Za-z0-9_]", "_"));
74 private boolean matchLocalIpAddress(String ipAddress) {
75 List<String> localIpAddresses = NetUtil.getAllInterfaceAddresses().stream()
76 .filter(a -> !a.getAddress().isLinkLocalAddress())
77 .map(a -> a.getAddress().getHostAddress().split("%")[0]).collect(Collectors.toList());
78 return localIpAddresses.contains(ipAddress);
82 public @Nullable DiscoveryResult createResult(ServiceInfo service) {
83 logger.debug("createResult ServiceInfo: {}", service);
84 DiscoveryResult result = null;
85 String ip = (service.getHostAddresses() != null && service.getHostAddresses().length > 0
86 && !service.getHostAddresses()[0].isEmpty()) ? service.getHostAddresses()[0].replaceAll("\\[|\\]", "")
88 String restPath = service.getPropertyString("uri");
89 ThingUID thingUID = getThingUID(service);
90 if (thingUID != null && ip != null && restPath != null) {
91 logger.debug("Create a DiscoveryResult for remote openHAB server {} with IP {}", thingUID, ip);
92 Map<String, Object> properties = Map.of(HOST, ip, REST_PATH, restPath);
93 result = DiscoveryResultBuilder.create(thingUID).withProperties(properties).withRepresentationProperty(HOST)
94 .withLabel("@text/discovery.server.label").build();