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