From fea02122ebfe109730aa0dfb88b862dd87c570ed Mon Sep 17 00:00:00 2001 From: Andrew Fiddian-Green Date: Fri, 14 Jun 2024 20:09:39 +0100 Subject: [PATCH] [tado] Add mDNS discovery (#16861) * [tado] Add mDNS discovery Signed-off-by: Andrew Fiddian-Green --- bundles/org.openhab.binding.tado/README.md | 7 +- .../discovery/TadoDiscoveryParticipant.java | 85 +++++++++++++++++++ .../resources/OH-INF/i18n/tado.properties | 4 + 3 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 bundles/org.openhab.binding.tado/src/main/java/org/openhab/binding/tado/internal/discovery/TadoDiscoveryParticipant.java diff --git a/bundles/org.openhab.binding.tado/README.md b/bundles/org.openhab.binding.tado/README.md index 3debca6c1e0ac..568180c2412b9 100644 --- a/bundles/org.openhab.binding.tado/README.md +++ b/bundles/org.openhab.binding.tado/README.md @@ -7,8 +7,9 @@ You can then monitor and control all zone types (Heating, AC, Hot Water) as well ## `home` Thing (the Bridge) -The binding supports discovery, but a `home` thing type has to be configured first. -It serves as bridge to the tado° cloud services. +The `home` thing serves as bridge to the tado° cloud services. +The binding will automatically discover this thing and place it in the Inbox. +It has to be manually configured with its `username` and `password` before it will actually go onlime. Parameter | Required | Description -|-|- @@ -21,7 +22,7 @@ Example `tado.things` Bridge tado:home:demo [ username="mail@example.com", password="secret" ] ``` -Afterwards the discovery will show all zones and mobile devices associated with the user's home. +Once the `home` thing is online, the binding will discover all its respective zones and mobile devices, and place them in the Inbox. ### Channels diff --git a/bundles/org.openhab.binding.tado/src/main/java/org/openhab/binding/tado/internal/discovery/TadoDiscoveryParticipant.java b/bundles/org.openhab.binding.tado/src/main/java/org/openhab/binding/tado/internal/discovery/TadoDiscoveryParticipant.java new file mode 100644 index 0000000000000..8598a8a9a6167 --- /dev/null +++ b/bundles/org.openhab.binding.tado/src/main/java/org/openhab/binding/tado/internal/discovery/TadoDiscoveryParticipant.java @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2010-2024 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.tado.internal.discovery; + +import static org.openhab.binding.tado.internal.TadoBindingConstants.THING_TYPE_HOME; + +import java.util.Set; +import java.util.regex.Pattern; + +import javax.jmdns.ServiceInfo; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.core.config.discovery.DiscoveryResult; +import org.openhab.core.config.discovery.DiscoveryResultBuilder; +import org.openhab.core.config.discovery.mdns.MDNSDiscoveryParticipant; +import org.openhab.core.thing.ThingTypeUID; +import org.openhab.core.thing.ThingUID; +import org.osgi.service.component.annotations.Component; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Discovers Tado Internet Bridges by means of mDNS + * + * @author Andrew Fiddian-Green - Initial contribution + */ +@Component(configurationPid = "discovery.tado") +@NonNullByDefault +public class TadoDiscoveryParticipant implements MDNSDiscoveryParticipant { + + private static final String SERVICE_TYPE = "_hap._tcp.local."; + private static final String TADO_INTERNET_BRIDGE = "tado Internet Bridge"; + private static final String DISCOVERY_BRIDGE_LABEL_KEY = "discovery.bridge.label"; + + public static final Pattern VALID_IP_V4_ADDRESS = Pattern + .compile("\\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.|$)){4}\\b"); + + private final Logger logger = LoggerFactory.getLogger(TadoDiscoveryParticipant.class); + + @Override + public Set getSupportedThingTypeUIDs() { + return Set.of(THING_TYPE_HOME); + } + + @Override + public String getServiceType() { + return SERVICE_TYPE; + } + + @Override + public @Nullable DiscoveryResult createResult(ServiceInfo service) { + ThingUID thingUID = getThingUID(service); + if (thingUID != null) { + String ipAddress = thingUID.getId().replace("_", "."); + DiscoveryResult hub = DiscoveryResultBuilder.create(thingUID) + .withLabel(String.format("@text/%s [\"%s\"]", DISCOVERY_BRIDGE_LABEL_KEY, ipAddress)).build(); + logger.debug("mDNS discovered tado° internet bridge '{}' on '{}'", thingUID, ipAddress); + return hub; + } + return null; + } + + @Override + public @Nullable ThingUID getThingUID(ServiceInfo service) { + if (service.getName().startsWith(TADO_INTERNET_BRIDGE)) { + for (String host : service.getHostAddresses()) { + if (VALID_IP_V4_ADDRESS.matcher(host).matches()) { + return new ThingUID(THING_TYPE_HOME, host.replace('.', '_')); + } + } + } + return null; + } +} diff --git a/bundles/org.openhab.binding.tado/src/main/resources/OH-INF/i18n/tado.properties b/bundles/org.openhab.binding.tado/src/main/resources/OH-INF/i18n/tado.properties index 69c64c98e0778..b9d79d3bb0d30 100644 --- a/bundles/org.openhab.binding.tado/src/main/resources/OH-INF/i18n/tado.properties +++ b/bundles/org.openhab.binding.tado/src/main/resources/OH-INF/i18n/tado.properties @@ -109,3 +109,7 @@ channel-type.tado.verticalSwing.state.option.MID_DOWN = MID-DOWN channel-type.tado.verticalSwing.state.option.DOWN = DOWN channel-type.tado.verticalSwing.state.option.ON = ON channel-type.tado.verticalSwing.state.option.OFF = OFF + +# discovery + +discovery.bridge.label = tado° Internet Bridge ({0})