2 * Copyright (c) 2010-2023 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.network.internal;
15 import java.util.ArrayList;
16 import java.util.List;
18 import java.util.TreeSet;
19 import java.util.stream.Collectors;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
24 * Contains the result or partial result of a presence detection.
26 * @author David Graeff - Initial contribution
29 public class PresenceDetectionValue {
30 private double latency;
31 private boolean detectionIsFinished;
32 private final Set<PresenceDetectionType> reachableByType = new TreeSet<>();
33 private final List<Integer> tcpServiceReachable = new ArrayList<>();
34 private final String hostAddress;
37 * Returns true if the target is reachable by any means.
39 public boolean isReachable() {
44 * Return the ping latency in ms or -1 if not reachable. Can be 0 if
45 * no specific latency is known but the device is still reachable.
47 public double getLowestLatency() {
52 * Return a string of comma separated successful presence detection types.
54 public String getSuccessfulDetectionTypes() {
55 return reachableByType.stream().map(v -> v.name()).collect(Collectors.joining(", "));
59 * Return the reachable tcp ports of the presence detection value.
62 public List<Integer> getReachableTCPports() {
63 synchronized (tcpServiceReachable) {
64 List<Integer> copy = new ArrayList<>();
65 copy.addAll(tcpServiceReachable);
71 * Return true if the presence detection is fully completed (no running
74 public boolean isFinished() {
75 return detectionIsFinished;
78 ////// Package private methods //////
81 * Create a new PresenceDetectionValue with an initial latency.
83 * @param hostAddress The target IP
84 * @param latency The ping latency in ms. Can be <0 if the device is not reachable.
86 PresenceDetectionValue(String hostAddress, double latency) {
87 this.hostAddress = hostAddress;
88 this.latency = latency;
92 * Add a successful PresenceDetectionType.
94 * @param type A PresenceDetectionType.
96 void addType(PresenceDetectionType type) {
97 reachableByType.add(type);
101 * Called by {@see PresenceDetection} by all different means of presence detections.
102 * If the given latency is lower than the already stored one, the stored one will be overwritten.
104 * @param newLatency The new latency.
105 * @return Returns true if the latency was indeed lower and updated the stored one.
107 boolean updateLatency(double newLatency) {
108 if (newLatency < 0) {
109 throw new IllegalArgumentException(
110 "Latency must be >=0. Create a new PresenceDetectionValue for a not reachable device!");
112 if (newLatency > 0 && (latency == 0 || newLatency < latency)) {
113 latency = newLatency;
120 * Add a reachable tcp port to this presence detection result value object.
123 void addReachableTcpService(int tcpPort) {
124 synchronized (tcpServiceReachable) {
125 tcpServiceReachable.add(tcpPort);
130 * Mark the result value as final. No modifications should occur after this call.
132 void setDetectionIsFinished(boolean detectionIsFinished) {
133 this.detectionIsFinished = detectionIsFinished;
137 * Return the host address of the presence detection result object.
139 public String getHostAddress() {
144 * Return true if the target can be reached by ICMP or ARP pings.
146 public boolean isPingReachable() {
147 return reachableByType.contains(PresenceDetectionType.ARP_PING)
148 || reachableByType.contains(PresenceDetectionType.ICMP_PING);
152 * Return true if the target provides open TCP ports.
154 public boolean isTCPServiceReachable() {
155 return reachableByType.contains(PresenceDetectionType.TCP_CONNECTION);