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