]> git.basschouten.com Git - openhab-addons.git/blob
afb26963ae9971af80ebfaa2dca0055e4a34547f
[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.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         return get(uriBuilder, StationDataResponse.class);
62     }
63
64     /**
65      * Returns data from a user's Weather Station, this stations can be a station owned by the user or a favorite
66      * station or a guest station.
67      *
68      * @param deviceId Id of the device you want to retrieve information
69      * @return NAMain
70      * @throws NetatmoException If fail to call the API, e.g. server error or deserializing
71      */
72     public NAMain getStationData(String deviceId) throws NetatmoException {
73         ListBodyResponse<NAMain> answer = getStationsData(deviceId, true).getBody();
74         if (answer != null) {
75             NAMain station = answer.getElement(deviceId);
76             if (station != null) {
77                 return station;
78             }
79         }
80         throw new NetatmoException("Unexpected answer searching device '%s' : not found.", deviceId);
81     }
82
83     /**
84      * Returns data from a Weather Station owned by the user
85      *
86      * This method must be preferred to getStationData when you know that the device is a station owned by the user
87      * (because it avoids requesting additional data for favorite/guest stations).
88      *
89      * @param deviceId Id of the device you want to retrieve information
90      * @return NAMain
91      * @throws NetatmoException If fail to call the API, e.g. server error or deserializing
92      */
93     public NAMain getOwnedStationData(String deviceId) throws NetatmoException {
94         ListBodyResponse<NAMain> answer = getStationsData(deviceId, false).getBody();
95         if (answer != null) {
96             NAMain station = answer.getElement(deviceId);
97             if (station != null) {
98                 return station;
99             }
100         }
101         throw new NetatmoException("Unexpected answer searching device '%s' : not found.", deviceId);
102     }
103
104     public Collection<NAMain> getFavoriteAndGuestStationsData() throws NetatmoException {
105         ListBodyResponse<NAMain> answer = getStationsData(null, true).getBody();
106         return answer != null ? answer.getElements() : List.of();
107     }
108
109     public @Nullable Object getMeasures(String deviceId, @Nullable String moduleId, @Nullable String scale,
110             String apiDescriptor) throws NetatmoException {
111         MeasureBodyElem<?> result = getMeasure(deviceId, moduleId, scale, apiDescriptor);
112         return result.getSingleValue();
113     }
114
115     public @Nullable Object getMeasures(String deviceId, @Nullable String moduleId, @Nullable String scale,
116             String apiDescriptor, String limit) throws NetatmoException {
117         String queryLimit = limit;
118         if (!apiDescriptor.contains("_")) {
119             queryLimit += "_" + apiDescriptor;
120         }
121
122         MeasureBodyElem<?> result = getMeasure(deviceId, moduleId, scale, queryLimit.toLowerCase());
123         return result.getSingleValue();
124     }
125
126     private MeasureBodyElem<?> getMeasure(String deviceId, @Nullable String moduleId, @Nullable String scale,
127             String measureType) throws NetatmoException {
128         // NAMeasuresResponse is not designed for optimize=false
129         UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_GET_MEASURE, PARAM_DEVICE_ID, deviceId, "real_time", true,
130                 "date_end", "last", "optimize", true, "type", measureType.toLowerCase(), PARAM_MODULE_ID, moduleId);
131
132         if (scale != null) {
133             uriBuilder.queryParam("scale", scale.toLowerCase());
134         }
135         if (measureType.startsWith("date")) {
136             NADateMeasuresResponse response = get(uriBuilder, NADateMeasuresResponse.class);
137             List<MeasureBodyElem<ZonedDateTime>> body = response.getBody();
138             if (body != null && !body.isEmpty()) {
139                 return body.get(0);
140             }
141         } else {
142             NAMeasuresResponse response = get(uriBuilder, NAMeasuresResponse.class);
143             List<MeasureBodyElem<Double>> body = response.getBody();
144             if (body != null && !body.isEmpty()) {
145                 return body.get(0);
146             }
147         }
148         throw new NetatmoException("Empty response while getting measurements");
149     }
150 }