[netatmo] Avoid requesting favorite stations when not needed (#12777)

* [netatmo] Avoid requesting favorite stations when not needed
* Add new method getFavoriteAndGuestStationsData
* Enhanced description for method getOwnedStationData
* getFavoriteAndGuestStationsData returns a collection of NAMain

Fix #12769

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
This commit is contained in:
lolodomo 2022-05-22 10:32:09 +02:00 committed by GitHub
parent cab63283f3
commit 2fbdc7d21e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 12 deletions

View File

@ -15,6 +15,7 @@ package org.openhab.binding.netatmo.internal.api;
import static org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.*; import static org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.*;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.Collection;
import java.util.List; import java.util.List;
import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriBuilder;
@ -45,16 +46,15 @@ public class WeatherApi extends RestManager {
} }
/** /**
*
* Returns data from a user's Weather Stations (measures and device specific data); * Returns data from a user's Weather Stations (measures and device specific data);
* *
* @param deviceId Id of the device you want to retrieve information of (optional) * @param deviceId Id of the device you want to retrieve information of (optional)
* @param getFavorites Whether to include the user's favorite Weather Stations in addition to the user's * @param getFavorites Whether to include the user's favorite Weather Stations in addition to the user's
* own Weather Stations (optional, default to false) * own Weather Stations
* @return StationDataResponse * @return StationDataResponse
* @throws NetatmoException If fail to call the API, e.g. server error or deserializing * @throws NetatmoException If fail to call the API, e.g. server error or deserializing
*/ */
public StationDataResponse getStationsData(@Nullable String deviceId, boolean getFavorites) private StationDataResponse getStationsData(@Nullable String deviceId, boolean getFavorites)
throws NetatmoException { throws NetatmoException {
UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_GETSTATION, PARAM_DEVICEID, deviceId, // UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_GETSTATION, PARAM_DEVICEID, deviceId, //
PARAM_FAVORITES, getFavorites); PARAM_FAVORITES, getFavorites);
@ -62,6 +62,14 @@ public class WeatherApi extends RestManager {
return response; return response;
} }
/**
* Returns data from a user's Weather Station, this stations can be a station owned by the user or a favorite
* station or a guest station.
*
* @param deviceId Id of the device you want to retrieve information
* @return NAMain
* @throws NetatmoException If fail to call the API, e.g. server error or deserializing
*/
public NAMain getStationData(String deviceId) throws NetatmoException { public NAMain getStationData(String deviceId) throws NetatmoException {
ListBodyResponse<NAMain> answer = getStationsData(deviceId, true).getBody(); ListBodyResponse<NAMain> answer = getStationsData(deviceId, true).getBody();
if (answer != null) { if (answer != null) {
@ -73,6 +81,32 @@ public class WeatherApi extends RestManager {
throw new NetatmoException("Unexpected answer searching device '%s' : not found.", deviceId); throw new NetatmoException("Unexpected answer searching device '%s' : not found.", deviceId);
} }
/**
* Returns data from a Weather Station owned by the user
*
* This method must be preferred to getStationData when you know that the device is a station owned by the user
* (because it avoids requesting additional data for favorite/guest stations).
*
* @param deviceId Id of the device you want to retrieve information
* @return NAMain
* @throws NetatmoException If fail to call the API, e.g. server error or deserializing
*/
public NAMain getOwnedStationData(String deviceId) throws NetatmoException {
ListBodyResponse<NAMain> answer = getStationsData(deviceId, false).getBody();
if (answer != null) {
NAMain station = answer.getElement(deviceId);
if (station != null) {
return station;
}
}
throw new NetatmoException("Unexpected answer searching device '%s' : not found.", deviceId);
}
public Collection<NAMain> getFavoriteAndGuestStationsData() throws NetatmoException {
ListBodyResponse<NAMain> answer = getStationsData(null, true).getBody();
return answer != null ? answer.getElements() : List.of();
}
public @Nullable Object getMeasures(String deviceId, @Nullable String moduleId, @Nullable String scale, public @Nullable Object getMeasures(String deviceId, @Nullable String moduleId, @Nullable String scale,
String apiDescriptor) throws NetatmoException { String apiDescriptor) throws NetatmoException {
MeasureBodyElem<?> result = getMeasure(deviceId, moduleId, scale, apiDescriptor); MeasureBodyElem<?> result = getMeasure(deviceId, moduleId, scale, apiDescriptor);

View File

@ -73,14 +73,12 @@ public class NetatmoDiscoveryService extends AbstractDiscoveryService implements
if (readFriends) { if (readFriends) {
WeatherApi weatherApi = localHandler.getRestManager(WeatherApi.class); WeatherApi weatherApi = localHandler.getRestManager(WeatherApi.class);
if (weatherApi != null) { // Search favorite stations if (weatherApi != null) { // Search favorite stations
ListBodyResponse<NAMain> body = weatherApi.getStationsData(null, true).getBody(); weatherApi.getFavoriteAndGuestStationsData().stream().filter(NAMain::isReadOnly)
if (body != null) { .forEach(station -> {
body.getElements().stream().filter(NAMain::isReadOnly).forEach(station -> { ThingUID bridgeUID = createThing(station, apiBridgeUID);
ThingUID bridgeUID = createThing(station, apiBridgeUID); station.getModules().values().stream()
station.getModules().values().stream() .forEach(module -> createThing(module, bridgeUID));
.forEach(module -> createThing(module, bridgeUID)); });
});
}
} }
} }
HomeApi homeApi = localHandler.getRestManager(HomeApi.class); HomeApi homeApi = localHandler.getRestManager(HomeApi.class);

View File

@ -28,12 +28,21 @@ import org.openhab.binding.netatmo.internal.handler.CommonInterface;
public class DeviceCapability extends Capability { public class DeviceCapability extends Capability {
private static final int DATA_AGE_LIMIT_S = 3600; private static final int DATA_AGE_LIMIT_S = 3600;
/**
* Whether the device is owned or not by the user (a favorite station or a guest station is not owned by the user).
* It will be updated when handling the result of the getstationsdata API.
* It must be initialized to false to be sure that the first call to the API will not fail for a favorite/guest
* weather stations.
*/
protected boolean owned;
public DeviceCapability(CommonInterface handler) { public DeviceCapability(CommonInterface handler) {
super(handler); super(handler);
} }
@Override @Override
protected void updateNAMain(NAMain newData) { protected void updateNAMain(NAMain newData) {
owned = !newData.isReadOnly();
if (firstLaunch) { if (firstLaunch) {
newData.getPlace().ifPresent(place -> { newData.getPlace().ifPresent(place -> {
place.getCity().map(city -> properties.put(PROPERTY_CITY, city)); place.getCity().map(city -> properties.put(PROPERTY_CITY, city));

View File

@ -39,7 +39,7 @@ public class WeatherCapability extends RestCapability<WeatherApi> {
@Override @Override
protected List<NAObject> updateReadings(WeatherApi api) { protected List<NAObject> updateReadings(WeatherApi api) {
try { try {
return List.of(api.getStationData(handler.getId())); return List.of(owned ? api.getOwnedStationData(handler.getId()) : api.getStationData(handler.getId()));
} catch (NetatmoException e) { } catch (NetatmoException e) {
logger.warn("Error retrieving weather data '{}' : {}", handler.getId(), e.getMessage()); logger.warn("Error retrieving weather data '{}' : {}", handler.getId(), e.getMessage());
} }