]> git.basschouten.com Git - openhab-addons.git/blob
bdb8905c1a57976d56d902400d08890da5bf084c
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 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.netatmo.internal.api;
14
15 import static org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.*;
16
17 import java.time.ZonedDateTime;
18 import java.util.Collection;
19 import java.util.List;
20
21 import javax.ws.rs.core.UriBuilder;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.FeatureArea;
26 import org.openhab.binding.netatmo.internal.api.dto.MeasureBodyElem;
27 import org.openhab.binding.netatmo.internal.api.dto.NAMain;
28 import org.openhab.binding.netatmo.internal.api.dto.NAMain.StationDataResponse;
29 import org.openhab.binding.netatmo.internal.handler.ApiBridgeHandler;
30
31 /**
32  * Base class for all Weather related endpoints
33  *
34  * @author GaĆ«l L'hopital - Initial contribution
35  */
36 @NonNullByDefault
37 public class WeatherApi extends RestManager {
38     private class NAMeasuresResponse extends ApiResponse<List<MeasureBodyElem<Double>>> {
39     }
40
41     private class NADateMeasuresResponse extends ApiResponse<List<MeasureBodyElem<ZonedDateTime>>> {
42     }
43
44     public WeatherApi(ApiBridgeHandler apiClient) {
45         super(apiClient, FeatureArea.WEATHER);
46     }
47
48     /**
49      * Returns data from a user's Weather Stations (measures and device specific data);
50      *
51      * @param deviceId Id of the device you want to retrieve information of (optional)
52      * @param getFavorites Whether to include the user's favorite Weather Stations in addition to the user's
53      *            own Weather Stations
54      * @return StationDataResponse
55      * @throws NetatmoException If fail to call the API, e.g. server error or deserializing
56      */
57     private StationDataResponse getStationsData(@Nullable String deviceId, boolean getFavorites)
58             throws NetatmoException {
59         UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_GET_STATION, PARAM_DEVICE_ID, deviceId, //
60                 PARAM_FAVORITES, getFavorites);
61         StationDataResponse response = get(uriBuilder, StationDataResponse.class);
62         return response;
63     }
64
65     /**
66      * Returns data from a user's Weather Station, this stations can be a station owned by the user or a favorite
67      * station or a guest station.
68      *
69      * @param deviceId Id of the device you want to retrieve information
70      * @return NAMain
71      * @throws NetatmoException If fail to call the API, e.g. server error or deserializing
72      */
73     public NAMain getStationData(String deviceId) throws NetatmoException {
74         ListBodyResponse<NAMain> answer = getStationsData(deviceId, true).getBody();
75         if (answer != null) {
76             NAMain station = answer.getElement(deviceId);
77             if (station != null) {
78                 return station;
79             }
80         }
81         throw new NetatmoException("Unexpected answer searching device '%s' : not found.", deviceId);
82     }
83
84     /**
85      * Returns data from a Weather Station owned by the user
86      *
87      * This method must be preferred to getStationData when you know that the device is a station owned by the user
88      * (because it avoids requesting additional data for favorite/guest stations).
89      *
90      * @param deviceId Id of the device you want to retrieve information
91      * @return NAMain
92      * @throws NetatmoException If fail to call the API, e.g. server error or deserializing
93      */
94     public NAMain getOwnedStationData(String deviceId) throws NetatmoException {
95         ListBodyResponse<NAMain> answer = getStationsData(deviceId, false).getBody();
96         if (answer != null) {
97             NAMain station = answer.getElement(deviceId);
98             if (station != null) {
99                 return station;
100             }
101         }
102         throw new NetatmoException("Unexpected answer searching device '%s' : not found.", deviceId);
103     }
104
105     public Collection<NAMain> getFavoriteAndGuestStationsData() throws NetatmoException {
106         ListBodyResponse<NAMain> answer = getStationsData(null, true).getBody();
107         return answer != null ? answer.getElements() : List.of();
108     }
109
110     public @Nullable Object getMeasures(String deviceId, @Nullable String moduleId, @Nullable String scale,
111             String apiDescriptor) throws NetatmoException {
112         MeasureBodyElem<?> result = getMeasure(deviceId, moduleId, scale, apiDescriptor);
113         return result.getSingleValue();
114     }
115
116     public @Nullable Object getMeasures(String deviceId, @Nullable String moduleId, @Nullable String scale,
117             String apiDescriptor, String limit) throws NetatmoException {
118         String queryLimit = limit;
119         if (!apiDescriptor.contains("_")) {
120             queryLimit += "_" + apiDescriptor;
121         }
122
123         MeasureBodyElem<?> result = getMeasure(deviceId, moduleId, scale, queryLimit.toLowerCase());
124         return result.getSingleValue();
125     }
126
127     private MeasureBodyElem<?> getMeasure(String deviceId, @Nullable String moduleId, @Nullable String scale,
128             String measureType) throws NetatmoException {
129         // NAMeasuresResponse is not designed for optimize=false
130         UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_GET_MEASURE, PARAM_DEVICE_ID, deviceId, "real_time", true,
131                 "date_end", "last", "optimize", true, "type", measureType.toLowerCase(), PARAM_MODULE_ID, moduleId);
132
133         if (scale != null) {
134             uriBuilder.queryParam("scale", scale.toLowerCase());
135         }
136         if (measureType.startsWith("date")) {
137             NADateMeasuresResponse response = get(uriBuilder, NADateMeasuresResponse.class);
138             List<MeasureBodyElem<ZonedDateTime>> body = response.getBody();
139             if (body != null && !body.isEmpty()) {
140                 return body.get(0);
141             }
142         } else {
143             NAMeasuresResponse response = get(uriBuilder, NAMeasuresResponse.class);
144             List<MeasureBodyElem<Double>> body = response.getBody();
145             if (body != null && !body.isEmpty()) {
146                 return body.get(0);
147             }
148         }
149         throw new NetatmoException("Empty response while getting measurements");
150     }
151 }