2 * Copyright (c) 2010-2024 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.resol.internal.discovery;
15 import java.io.IOException;
16 import java.io.InterruptedIOException;
17 import java.net.InetAddress;
18 import java.net.UnknownHostException;
19 import java.util.HashMap;
21 import java.util.concurrent.Future;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.openhab.binding.resol.internal.ResolBindingConstants;
26 import org.openhab.core.config.discovery.AbstractDiscoveryService;
27 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
28 import org.openhab.core.config.discovery.DiscoveryService;
29 import org.openhab.core.thing.ThingUID;
30 import org.osgi.service.component.annotations.Component;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
34 import de.resol.vbus.TcpDataSource;
35 import de.resol.vbus.TcpDataSourceProvider;
38 * The {@link ResolVBusBridgeDiscovery} class provides the DiscoverySerivce to
39 * discover Resol VBus-LAN adapters
41 * @author Raphael Mack - Initial contribution
43 @Component(service = DiscoveryService.class)
45 public class ResolVBusBridgeDiscovery extends AbstractDiscoveryService {
46 public static final String THING_PROPERTY_IPADDRESS = "ipAddress";
47 public static final String THING_PROPERTY_PORT = "port";
48 public static final String THING_PROPERTY_ADAPTER_SERIAL = "adapterSerial";
50 private final Logger logger = LoggerFactory.getLogger(ResolVBusBridgeDiscovery.class);
52 private volatile boolean discoveryRunning = false;
53 private @Nullable Future<?> searchFuture;
55 public ResolVBusBridgeDiscovery() throws IllegalArgumentException {
56 super(ResolBindingConstants.SUPPORTED_BRIDGE_THING_TYPES_UIDS, 35, false);
60 protected void startScan() {
61 discoveryRunning = true;
62 searchFuture = scheduler.submit(this::searchRunnable);
66 protected void stopScan() {
67 discoveryRunning = false;
68 if (searchFuture != null) {
69 searchFuture.cancel(true);
74 * The runnable for the search routine.
76 public void searchRunnable() {
78 InetAddress broadcastAddress = InetAddress
79 .getByAddress(new byte[] { (byte) 255, (byte) 255, (byte) 255, (byte) 255 });
81 TcpDataSource[] dataSources = TcpDataSourceProvider.discoverDataSources(broadcastAddress, 3, 500, false);
83 Map<String, TcpDataSource> currentDataSourceById = new HashMap<String, TcpDataSource>();
84 for (TcpDataSource ds : dataSources) {
85 if (!discoveryRunning) {
88 InetAddress address = ds.getAddress();
89 String addressId = address.getHostAddress();
90 TcpDataSource dsWithInfo;
92 dsWithInfo = TcpDataSourceProvider.fetchInformation(address, 1500);
93 logger.trace("Discovered Resol VBus-LAN interface @{} {} ({})", addressId,
94 dsWithInfo.getDeviceName(), dsWithInfo.getSerial());
96 currentDataSourceById.put(addressId, dsWithInfo);
97 addAdapter(addressId, dsWithInfo);
98 // here we can add the detection of Multi-Channel interfaces like DL3
99 } catch (InterruptedIOException ex) {
100 /* openHAB interrupted the io thread and wants to shutdown */
102 } catch (IOException ex) {
103 /* address is no valid adapter */
107 } catch (UnknownHostException e) {
108 logger.debug("Could not resolve IPv4 broadcast address");
112 private void addAdapter(String remoteIP, TcpDataSource dsWithInfo) {
113 String adapterSerial = dsWithInfo.getSerial();
114 Map<String, Object> properties = new HashMap<>(3);
115 properties.put(THING_PROPERTY_IPADDRESS, remoteIP);
116 properties.put(THING_PROPERTY_PORT, dsWithInfo.getLivePort());
117 properties.put(THING_PROPERTY_ADAPTER_SERIAL, adapterSerial);
119 ThingUID uid = new ThingUID(ResolBindingConstants.THING_TYPE_UID_BRIDGE, adapterSerial);
120 thingDiscovered(DiscoveryResultBuilder.create(uid).withRepresentationProperty(THING_PROPERTY_IPADDRESS)
121 .withProperties(properties).withLabel(dsWithInfo.getName()).build());