]> git.basschouten.com Git - openhab-addons.git/blob
75ecf8ff449c60b1098916aa345c57460d28560b
[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.sensorcommunity.internal.handler;
14
15 import static org.openhab.binding.sensorcommunity.internal.utils.Constants.*;
16
17 import java.time.LocalDateTime;
18 import java.util.List;
19 import java.util.Objects;
20 import java.util.concurrent.TimeUnit;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.eclipse.jetty.client.HttpClient;
25 import org.eclipse.jetty.client.api.Request;
26 import org.eclipse.jetty.client.util.BufferingResponseListener;
27 import org.openhab.binding.sensorcommunity.internal.dto.SensorData;
28 import org.openhab.binding.sensorcommunity.internal.dto.SensorDataValue;
29 import org.openhab.binding.sensorcommunity.internal.utils.DateTimeUtils;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 import com.google.gson.Gson;
34
35 /**
36  * The {@link HTTPHandler} is responsible for HTTP requests and JSON handling
37  *
38  * @author Bernd Weymann - Initial contribution
39  */
40 @NonNullByDefault
41 public class HTTPHandler {
42     private final Logger logger = LoggerFactory.getLogger(HTTPHandler.class);
43
44     private static final Gson GSON = new Gson();
45     private static final HTTPHandler HTTP_HANDLER = new HTTPHandler();
46
47     private static @Nullable HttpClient commonHttpClient;
48
49     public static void init(HttpClient httpClient) {
50         commonHttpClient = httpClient;
51     }
52
53     public static HTTPHandler getHandler() {
54         return HTTP_HANDLER;
55     }
56
57     public synchronized void request(String url, BaseSensorHandler callback) {
58         HttpClient localClient = commonHttpClient;
59         if (localClient == null) {
60             logger.warn("HTTP Client not initialized");
61         } else {
62             Request req = localClient.newRequest(url);
63             req.timeout(15, TimeUnit.SECONDS).send(new BufferingResponseListener() {
64                 @NonNullByDefault({})
65                 @Override
66                 public void onComplete(org.eclipse.jetty.client.api.Result result) {
67                     if (result.getResponse().getStatus() != 200) {
68                         String failure;
69                         if (result.getResponse().getReason() != null) {
70                             failure = result.getResponse().getReason();
71                         } else {
72                             failure = result.getFailure().getMessage();
73                         }
74                         callback.onError(Objects.requireNonNullElse(failure, "Unknown error"));
75                     } else {
76                         callback.onResponse(getContentAsString());
77                     }
78                 }
79             });
80         }
81     }
82
83     public @Nullable List<SensorDataValue> getLatestValues(String response) {
84         SensorData[] valueArray = GSON.fromJson(response, SensorData[].class);
85         if (valueArray.length == 0) {
86             return null;
87         } else if (valueArray.length == 1) {
88             SensorData v = valueArray[0];
89             return v.getSensorDataValues();
90         } else if (valueArray.length > 1) {
91             // declare first item as latest
92             SensorData latestData = valueArray[0];
93             String latestTimeStr = latestData.getTimeStamp();
94             LocalDateTime latestTime = DateTimeUtils.toDate(latestTimeStr);
95             if (latestTime == null) {
96                 logDateConversionError(response, latestData);
97             }
98             for (int i = 1; i < valueArray.length; i++) {
99                 SensorData iterData = valueArray[i];
100                 String iterTimeStr = iterData.getTimeStamp();
101                 LocalDateTime iterTime = DateTimeUtils.toDate(iterTimeStr);
102                 if (iterTime == null) {
103                     logDateConversionError(response, latestData);
104                 }
105                 if (iterTime != null && latestTime != null) {
106                     if (latestTime.isBefore(iterTime)) {
107                         // found item is newer - take it as latest
108                         latestTime = iterTime;
109                         latestData = iterData;
110                     } // else - found item is older - nothing to do
111
112                 } else {
113                     logger.warn("One or two dates cannot be decoded 1) {} 2) {}", iterTimeStr, latestTimeStr);
114                 }
115             }
116             return latestData.getSensorDataValues();
117         } else {
118             return null;
119         }
120     }
121
122     public void logDateConversionError(final String response, final Object dto) {
123         logger.warn("Unable to get timestamp");
124         logger.warn("Response: {}", response);
125         String json = GSON.toJson(dto);
126         logger.warn("GSon: {}", json);
127     }
128
129     public boolean isParticulate(@Nullable List<SensorDataValue> valueList) {
130         if (valueList == null) {
131             return false;
132         }
133         return valueList.stream().map(v -> v.getValueType()).filter(t -> t.endsWith(P1) || t.endsWith(P2)).findAny()
134                 .isPresent();
135     }
136
137     public boolean isCondition(@Nullable List<SensorDataValue> valueList) {
138         if (valueList == null) {
139             return false;
140         }
141         return valueList.stream().map(v -> v.getValueType()).filter(t -> t.equals(TEMPERATURE) || t.endsWith(HUMIDITY)
142                 || t.endsWith(PRESSURE) || t.endsWith(PRESSURE_SEALEVEL)).findAny().isPresent();
143     }
144
145     public boolean isNoise(@Nullable List<SensorDataValue> valueList) {
146         if (valueList == null) {
147             return false;
148         }
149         return valueList.stream().map(v -> v.getValueType())
150                 .filter(t -> t.endsWith(NOISE_EQ) || t.endsWith(NOISE_MAX) || t.endsWith(NOISE_MIN)).findAny()
151                 .isPresent();
152     }
153 }