2 * Copyright (c) 2010-2020 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.luftdateninfo.internal.handler;
15 import java.time.LocalDateTime;
16 import java.util.List;
17 import java.util.Objects;
18 import java.util.concurrent.TimeUnit;
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;
31 import com.google.gson.Gson;
34 * The {@link HTTPHandler} is responsible for HTTP requests and JSON handling
36 * @author Bernd Weymann - Initial contribution
39 public class HTTPHandler {
40 private final Logger logger = LoggerFactory.getLogger(HTTPHandler.class);
42 private static final Gson GSON = new Gson();
43 private static final HTTPHandler HTTP_HANDLER = new HTTPHandler();
45 public static final String P1 = "P1";
46 public static final String P2 = "P2";
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";
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";
57 private static String sensorUrl = "http://data.sensor.community/airrohr/v1/sensor/";
58 private static @Nullable HttpClient commonHttpClient;
60 public static void init(HttpClient httpClient) {
61 commonHttpClient = httpClient;
64 public static HTTPHandler getHandler() {
68 public synchronized void request(int sensorId, BaseSensorHandler callback) {
69 HttpClient localClient = commonHttpClient;
70 if (localClient == null) {
71 logger.warn("HTTP Client not initialized");
73 String url = sensorUrl + sensorId + "/";
74 Request req = localClient.newRequest(url);
75 req.timeout(15, TimeUnit.SECONDS).send(new BufferingResponseListener() {
78 public void onComplete(org.eclipse.jetty.client.api.Result result) {
79 if (result.getResponse().getStatus() != 200) {
81 if (result.getResponse().getReason() != null) {
82 failure = result.getResponse().getReason();
84 failure = result.getFailure().getMessage();
86 callback.onError(Objects.requireNonNullElse(failure, "Unknown error"));
88 callback.onResponse(getContentAsString());
95 public @Nullable List<SensorDataValue> getLatestValues(String response) {
96 SensorData[] valueArray = GSON.fromJson(response, SensorData[].class);
97 if (valueArray.length == 0) {
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);
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);
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
125 logger.warn("One or two dates cannot be decoded 1) {} 2) {}", iterTimeStr, latestTimeStr);
128 return latestData.getSensorDataValues();
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);
141 public boolean isParticulate(@Nullable List<SensorDataValue> valueList) {
142 if (valueList == null) {
145 return valueList.stream().map(v -> v.getValueType()).filter(t -> t.equals(P1) || t.equals(P2)).findAny()
149 public boolean isCondition(@Nullable List<SensorDataValue> valueList) {
150 if (valueList == null) {
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();
158 public boolean isNoise(@Nullable List<SensorDataValue> valueList) {
159 if (valueList == null) {
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();