]> git.basschouten.com Git - openhab-addons.git/blob
ca2b305b9635a0672a30510a5c10365c4e71657c
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.network.internal;
14
15 import java.util.ArrayList;
16 import java.util.List;
17 import java.util.Set;
18 import java.util.TreeSet;
19 import java.util.stream.Collectors;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22
23 /**
24  * Contains the result or partial result of a presence detection.
25  *
26  * @author David Graeff - Initial contribution
27  */
28 @NonNullByDefault
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;
35
36     /**
37      * Returns true if the target is reachable by any means.
38      */
39     public boolean isReachable() {
40         return latency >= 0;
41     }
42
43     /**
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.
46      */
47     public double getLowestLatency() {
48         return latency;
49     }
50
51     /**
52      * Return a string of comma separated successful presence detection types.
53      */
54     public String getSuccessfulDetectionTypes() {
55         return reachableByType.stream().map(v -> v.name()).collect(Collectors.joining(", "));
56     }
57
58     /**
59      * Return the reachable tcp ports of the presence detection value.
60      * Thread safe.
61      */
62     public List<Integer> getReachableTCPports() {
63         synchronized (tcpServiceReachable) {
64             List<Integer> copy = new ArrayList<>();
65             copy.addAll(tcpServiceReachable);
66             return copy;
67         }
68     }
69
70     /**
71      * Return true if the presence detection is fully completed (no running
72      * threads anymore).
73      */
74     public boolean isFinished() {
75         return detectionIsFinished;
76     }
77
78     ////// Package private methods //////
79
80     /**
81      * Create a new PresenceDetectionValue with an initial latency.
82      *
83      * @param hostAddress The target IP
84      * @param latency The ping latency in ms. Can be <0 if the device is not reachable.
85      */
86     PresenceDetectionValue(String hostAddress, double latency) {
87         this.hostAddress = hostAddress;
88         this.latency = latency;
89     }
90
91     /**
92      * Add a successful PresenceDetectionType.
93      *
94      * @param type A PresenceDetectionType.
95      */
96     void addType(PresenceDetectionType type) {
97         reachableByType.add(type);
98     }
99
100     /**
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.
103      *
104      * @param newLatency The new latency.
105      * @return Returns true if the latency was indeed lower and updated the stored one.
106      */
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!");
111         }
112         if (newLatency > 0 && (latency == 0 || newLatency < latency)) {
113             latency = newLatency;
114             return true;
115         }
116         return false;
117     }
118
119     /**
120      * Add a reachable tcp port to this presence detection result value object.
121      * Thread safe.
122      */
123     void addReachableTcpService(int tcpPort) {
124         synchronized (tcpServiceReachable) {
125             tcpServiceReachable.add(tcpPort);
126         }
127     }
128
129     /**
130      * Mark the result value as final. No modifications should occur after this call.
131      */
132     void setDetectionIsFinished(boolean detectionIsFinished) {
133         this.detectionIsFinished = detectionIsFinished;
134     }
135
136     /**
137      * Return the host address of the presence detection result object.
138      */
139     public String getHostAddress() {
140         return hostAddress;
141     }
142
143     /**
144      * Return true if the target can be reached by ICMP or ARP pings.
145      */
146     public boolean isPingReachable() {
147         return reachableByType.contains(PresenceDetectionType.ARP_PING)
148                 || reachableByType.contains(PresenceDetectionType.ICMP_PING);
149     }
150
151     /**
152      * Return true if the target provides open TCP ports.
153      */
154     public boolean isTCPServiceReachable() {
155         return reachableByType.contains(PresenceDetectionType.TCP_CONNECTION);
156     }
157 }