From 6b42d75378cb9956a607371911b9a17344709d4b Mon Sep 17 00:00:00 2001 From: Leo Siepel Date: Tue, 24 Dec 2024 13:42:24 +0100 Subject: [PATCH 1/2] Fix performance Signed-off-by: Leo Siepel --- .../openhab/binding/network/internal/utils/NetworkUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.openhab.binding.network/src/main/java/org/openhab/binding/network/internal/utils/NetworkUtils.java b/bundles/org.openhab.binding.network/src/main/java/org/openhab/binding/network/internal/utils/NetworkUtils.java index a8bfc3202ce..f09924361d9 100644 --- a/bundles/org.openhab.binding.network/src/main/java/org/openhab/binding/network/internal/utils/NetworkUtils.java +++ b/bundles/org.openhab.binding.network/src/main/java/org/openhab/binding/network/internal/utils/NetworkUtils.java @@ -139,7 +139,7 @@ public class NetworkUtils { try { for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { NetworkInterface networkInterface = en.nextElement(); - if (!networkInterface.isLoopback()) { + if (networkInterface.isUp() && !networkInterface.isLoopback()) { result.add(networkInterface.getName()); } } From f6c6a3cf82bb6bb39596376ad7fb1d87f83991f0 Mon Sep 17 00:00:00 2001 From: Leo Siepel Date: Wed, 1 Jan 2025 23:26:22 +0100 Subject: [PATCH 2/2] Improvements Signed-off-by: Leo Siepel --- .../discovery/NetworkDiscoveryService.java | 64 +++++++++++-------- .../network/internal/utils/NetworkUtils.java | 28 +++++++- 2 files changed, 63 insertions(+), 29 deletions(-) diff --git a/bundles/org.openhab.binding.network/src/main/java/org/openhab/binding/network/internal/discovery/NetworkDiscoveryService.java b/bundles/org.openhab.binding.network/src/main/java/org/openhab/binding/network/internal/discovery/NetworkDiscoveryService.java index d2cc7de23bd..4cba2f74ee1 100644 --- a/bundles/org.openhab.binding.network/src/main/java/org/openhab/binding/network/internal/discovery/NetworkDiscoveryService.java +++ b/bundles/org.openhab.binding.network/src/main/java/org/openhab/binding/network/internal/discovery/NetworkDiscoveryService.java @@ -19,6 +19,7 @@ import java.time.Duration; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -37,6 +38,7 @@ import org.openhab.core.config.core.Configuration; import org.openhab.core.config.discovery.AbstractDiscoveryService; import org.openhab.core.config.discovery.DiscoveryResultBuilder; import org.openhab.core.config.discovery.DiscoveryService; +import org.openhab.core.net.CidrAddress; import org.openhab.core.thing.ThingUID; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; @@ -133,37 +135,43 @@ public class NetworkDiscoveryService extends AbstractDiscoveryService implements return; } removeOlderResults(getTimestampOfLastScan(), null); - logger.trace("Starting Network Device Discovery"); + logger.debug("Starting Network Device Discovery"); + Map> discoveryList = networkUtils.getNetworkIPsPerInterface(); - final Set networkIPs = networkUtils.getNetworkIPs(MAXIMUM_IPS_PER_INTERFACE); - scannedIPcount.set(0); + for (String networkInterface : discoveryList.keySet()) { + final Set networkIPs = networkUtils.getNetworkIPs( + Objects.requireNonNull(discoveryList.get(networkInterface)), MAXIMUM_IPS_PER_INTERFACE); + logger.debug("Scanning {} IPs on interface {} ", networkIPs.size(), networkInterface); + scannedIPcount.set(0); + for (String ip : networkIPs) { + final PresenceDetection pd = new PresenceDetection(this, scheduler, Duration.ofSeconds(2)); + pd.setHostname(ip); + pd.setNetworkInterfaceNames(Set.of(networkInterface)); + pd.setIOSDevice(true); + pd.setUseDhcpSniffing(false); + pd.setTimeout(PING_TIMEOUT); + // Ping devices + pd.setUseIcmpPing(true); + pd.setUseArpPing(true, configuration.arpPingToolPath, configuration.arpPingUtilMethod); + // TCP devices + pd.setServicePorts(tcpServicePorts); - for (String ip : networkIPs) { - final PresenceDetection pd = new PresenceDetection(this, scheduler, Duration.ofSeconds(2)); - pd.setHostname(ip); - pd.setIOSDevice(true); - pd.setUseDhcpSniffing(false); - pd.setTimeout(PING_TIMEOUT); - // Ping devices - pd.setUseIcmpPing(true); - pd.setUseArpPing(true, configuration.arpPingToolPath, configuration.arpPingUtilMethod); - // TCP devices - pd.setServicePorts(tcpServicePorts); - - service.execute(() -> { - Thread.currentThread().setName("Discovery thread " + ip); - try { - pd.getValue(); - } catch (ExecutionException | InterruptedException e) { - stopScan(); - } - int count = scannedIPcount.incrementAndGet(); - if (count == networkIPs.size()) { - logger.trace("Scan of {} IPs successful", scannedIPcount); - stopScan(); - } - }); + service.execute(() -> { + Thread.currentThread().setName("Discovery thread " + ip); + try { + pd.getValue(); + } catch (ExecutionException | InterruptedException e) { + stopScan(); + } + int count = scannedIPcount.incrementAndGet(); + if (count == networkIPs.size()) { + logger.trace("Scan of {} IPs on interface {} successful", scannedIPcount, networkInterface); + stopScan(); + } + }); + } } + logger.debug("Finished Network Device Discovery"); } @Override diff --git a/bundles/org.openhab.binding.network/src/main/java/org/openhab/binding/network/internal/utils/NetworkUtils.java b/bundles/org.openhab.binding.network/src/main/java/org/openhab/binding/network/internal/utils/NetworkUtils.java index f09924361d9..31e4482a03a 100644 --- a/bundles/org.openhab.binding.network/src/main/java/org/openhab/binding/network/internal/utils/NetworkUtils.java +++ b/bundles/org.openhab.binding.network/src/main/java/org/openhab/binding/network/internal/utils/NetworkUtils.java @@ -32,9 +32,11 @@ import java.time.Duration; import java.time.Instant; import java.util.ArrayList; import java.util.Enumeration; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -160,6 +162,30 @@ public class NetworkUtils { return getNetworkIPs(getInterfaceIPs(), maximumPerInterface); } + /** + * Retrieves a map of network interface names to their associated IP addresses. + * + * @return A map where the key is the name of the network interface and the value is a set of CidrAddress objects + * representing the IP addresses and network prefix lengths for that interface. + */ + public Map> getNetworkIPsPerInterface() { + Map> outputMap = new HashMap<>(); + try { + for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { + NetworkInterface networkInterface = en.nextElement(); + if (networkInterface.isUp() && !networkInterface.isLoopback()) { + outputMap.put(networkInterface.getName(), + networkInterface.getInterfaceAddresses().stream() + .map(m -> new CidrAddress(m.getAddress(), m.getNetworkPrefixLength())) + .collect(Collectors.toSet())); + } + } + } catch (SocketException e) { + logger.trace("Could not get network interfaces", e); + } + return outputMap; + } + /** * Takes the interfaceIPs and fetches every IP which can be assigned on their network * @@ -167,7 +193,7 @@ public class NetworkUtils { * @param maximumPerInterface The maximum of IP addresses per interface or 0 to get all. * @return Every single IP which can be assigned on the Networks the computer is connected to */ - private Set getNetworkIPs(Set interfaceIPs, int maximumPerInterface) { + public Set getNetworkIPs(Set interfaceIPs, int maximumPerInterface) { Set networkIPs = new LinkedHashSet<>(); short minCidrPrefixLength = 8; // historic Class A network, addresses = 16777214