[netatmo] Correct Discovery service (#12869)

* Correct Discovery service
* Enhancing weather station module handling

Signed-off-by: clinique <gael@lhopital.org>
This commit is contained in:
Gaël L'hopital 2022-06-05 19:14:04 +02:00 committed by GitHub
parent f5e5b5189a
commit 5a2ec07876
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -12,9 +12,10 @@
*/ */
package org.openhab.binding.netatmo.internal.discovery; package org.openhab.binding.netatmo.internal.discovery;
import static java.util.Comparator.*;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
@ -26,6 +27,7 @@ import org.openhab.binding.netatmo.internal.api.NetatmoException;
import org.openhab.binding.netatmo.internal.api.WeatherApi; import org.openhab.binding.netatmo.internal.api.WeatherApi;
import org.openhab.binding.netatmo.internal.api.data.ModuleType; import org.openhab.binding.netatmo.internal.api.data.ModuleType;
import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.FeatureArea; import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.FeatureArea;
import org.openhab.binding.netatmo.internal.api.dto.HomeDataModule;
import org.openhab.binding.netatmo.internal.api.dto.NAMain; import org.openhab.binding.netatmo.internal.api.dto.NAMain;
import org.openhab.binding.netatmo.internal.api.dto.NAModule; import org.openhab.binding.netatmo.internal.api.dto.NAModule;
import org.openhab.binding.netatmo.internal.config.NAThingConfiguration; import org.openhab.binding.netatmo.internal.config.NAThingConfiguration;
@ -48,13 +50,13 @@ import org.slf4j.LoggerFactory;
*/ */
@NonNullByDefault @NonNullByDefault
public class NetatmoDiscoveryService extends AbstractDiscoveryService implements ThingHandlerService, DiscoveryService { public class NetatmoDiscoveryService extends AbstractDiscoveryService implements ThingHandlerService, DiscoveryService {
private static final Set<ModuleType> SKIPPED_TYPES = Set.of(ModuleType.UNKNOWN, ModuleType.ACCOUNT);
private static final int DISCOVER_TIMEOUT_SECONDS = 3; private static final int DISCOVER_TIMEOUT_SECONDS = 3;
private final Logger logger = LoggerFactory.getLogger(NetatmoDiscoveryService.class); private final Logger logger = LoggerFactory.getLogger(NetatmoDiscoveryService.class);
private @Nullable ApiBridgeHandler handler; private @Nullable ApiBridgeHandler handler;
public NetatmoDiscoveryService() { public NetatmoDiscoveryService() {
super(ModuleType.AS_SET.stream().filter(mt -> !SKIPPED_TYPES.contains(mt)).map(mt -> mt.thingTypeUID) super(ModuleType.AS_SET.stream().filter(mt -> !mt.apiName.isBlank()).map(mt -> mt.thingTypeUID)
.collect(Collectors.toSet()), DISCOVER_TIMEOUT_SECONDS); .collect(Collectors.toSet()), DISCOVER_TIMEOUT_SECONDS);
} }
@ -71,40 +73,47 @@ public class NetatmoDiscoveryService extends AbstractDiscoveryService implements
body.getElements().stream().forEach(homeCoach -> createThing(homeCoach, accountUID)); body.getElements().stream().forEach(homeCoach -> createThing(homeCoach, accountUID));
} }
} }
if (localHandler.getReadFriends()) { WeatherApi weatherApi = localHandler.getRestManager(WeatherApi.class);
WeatherApi weatherApi = localHandler.getRestManager(WeatherApi.class); if (weatherApi != null) { // Search owned or favorite stations
if (weatherApi != null) { // Search favorite stations weatherApi.getFavoriteAndGuestStationsData().stream().forEach(station -> {
weatherApi.getFavoriteAndGuestStationsData().stream().filter(NAMain::isReadOnly) if (!station.isReadOnly() || localHandler.getReadFriends()) {
.forEach(station -> { ThingUID stationUID = createThing(station, accountUID);
ThingUID bridgeUID = createThing(station, accountUID); station.getModules().values().stream().forEach(module -> createThing(module, stationUID));
station.getModules().values().stream() }
.forEach(module -> createThing(module, bridgeUID)); });
});
}
} }
HomeApi homeApi = localHandler.getRestManager(HomeApi.class); HomeApi homeApi = localHandler.getRestManager(HomeApi.class);
if (homeApi != null) { // Search those who depend from a home if (homeApi != null) { // Search those depending from a home that has modules + not only weather modules
homeApi.getHomesData(null, null).stream().filter(h -> !h.getFeatures().isEmpty()).forEach(home -> { homeApi.getHomesData(null, null).stream()
ThingUID homeUID = createThing(home, accountUID); .filter(h -> !(h.getFeatures().isEmpty()
|| h.getFeatures().contains(FeatureArea.WEATHER) && h.getFeatures().size() == 1))
.forEach(home -> {
ThingUID homeUID = createThing(home, accountUID);
home.getKnownPersons().forEach(person -> createThing(person, homeUID)); home.getKnownPersons().forEach(person -> createThing(person, homeUID));
Map<String, ThingUID> bridgesUids = new HashMap<>(); Map<String, ThingUID> bridgesUids = new HashMap<>();
home.getRooms().values().stream().forEach(room -> { home.getRooms().values().stream().forEach(room -> {
room.getModuleIds().stream().map(id -> home.getModules().get(id)) room.getModuleIds().stream().map(id -> home.getModules().get(id))
.map(m -> m != null ? m.getType().feature : FeatureArea.NONE) .map(m -> m != null ? m.getType().feature : FeatureArea.NONE)
.filter(f -> FeatureArea.ENERGY.equals(f)).findAny() .filter(f -> FeatureArea.ENERGY.equals(f)).findAny()
.ifPresent(f -> bridgesUids.put(room.getId(), createThing(room, homeUID))); .ifPresent(f -> bridgesUids.put(room.getId(), createThing(room, homeUID)));
}); });
// Creating modules that have no bridge first // Creating modules that have no bridge first, avoiding weather station itself
home.getModules().values().stream().filter(module -> module.getBridge() == null) home.getModules().values().stream()
.forEach(device -> bridgesUids.put(device.getId(), createThing(device, homeUID))); .filter(module -> module.getType().feature != FeatureArea.WEATHER)
// Then the others .sorted(comparing(HomeDataModule::getBridge, nullsFirst(naturalOrder())))
home.getModules().values().stream().filter(module -> module.getBridge() != null).forEach( .forEach(module -> {
device -> createThing(device, bridgesUids.getOrDefault(device.getBridge(), homeUID))); String bridgeId = module.getBridge();
}); if (bridgeId == null) {
bridgesUids.put(module.getId(), createThing(module, homeUID));
} else {
createThing(module, bridgesUids.getOrDefault(bridgeId, homeUID));
}
});
});
} }
} catch (NetatmoException e) { } catch (NetatmoException e) {
logger.warn("Error during discovery process : {}", e.getMessage()); logger.warn("Error during discovery process : {}", e.getMessage());