[Netatmo] Fix duplicate id on single home (#14765)

* Solve duplicate id on single home
* Solving "Handler DeviceHandler of thing netatmo:welcome:compte:maison:camera tried accessing its bridge although the handler was already disposed."

Signed-off-by: clinique <gael@lhopital.org>
This commit is contained in:
Gaël L'hopital 2023-04-09 22:21:22 +02:00 committed by GitHub
parent 5fd7a0a15d
commit ca667e39c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 50 additions and 31 deletions

View File

@ -121,13 +121,12 @@ public interface CommonInterface {
.filter(channel -> ChannelKind.STATE.equals(channel.getKind()) && isLinked(channel.getUID()));
}
default Optional<CommonInterface> getHomeHandler() {
CommonInterface bridgeHandler = getBridgeHandler();
if (bridgeHandler != null) {
return bridgeHandler.getCapabilities().get(HomeCapability.class).isPresent() ? Optional.of(bridgeHandler)
: Optional.empty();
default Optional<CommonInterface> recurseUpToHomeHandler(@Nullable CommonInterface handler) {
if (handler == null) {
return Optional.empty();
}
return Optional.empty();
return handler.getCapabilities().get(HomeCapability.class).isPresent() ? Optional.of(handler)
: recurseUpToHomeHandler(handler.getBridgeHandler());
}
default List<CommonInterface> getActiveChildren() {
@ -146,7 +145,8 @@ public interface CommonInterface {
}
default <T extends RestCapability<?>> Optional<T> getHomeCapability(Class<T> clazz) {
return getHomeHandler().map(handler -> handler.getCapabilities().get(clazz)).orElse(Optional.empty());
return recurseUpToHomeHandler(this).map(handler -> handler.getCapabilities().get(clazz))
.orElse(Optional.empty());
}
default void setNewData(NAObject newData) {

View File

@ -36,7 +36,7 @@ public class AlarmEventCapability extends HomeSecurityThingCapability {
@Override
public List<NAObject> updateReadings() {
return securityCapability.map(cap -> cap.getDeviceLastEvent(handler.getId(), moduleType.apiName))
return getSecurityCapability().map(cap -> cap.getDeviceLastEvent(handler.getId(), moduleType.apiName))
.map(event -> List.of((NAObject) event)).orElse(List.of());
}
}

View File

@ -14,7 +14,6 @@ package org.openhab.binding.netatmo.internal.handler.capability;
import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*;
import static org.openhab.binding.netatmo.internal.utils.ChannelTypeUtils.*;
import static org.openhab.binding.netatmo.internal.utils.ChannelTypeUtils.toStringType;
import java.util.ArrayList;
import java.util.List;
@ -71,7 +70,7 @@ public class CameraCapability extends HomeSecurityThingCapability {
String newVpnUrl = newData.getVpnUrl();
if (newVpnUrl != null && !newVpnUrl.equals(vpnUrl)) {
// This will also decrease the number of requests emitted toward Netatmo API.
localUrl = newData.isLocal() ? securityCapability.map(cap -> cap.ping(newVpnUrl)).orElse(null) : null;
localUrl = newData.isLocal() ? getSecurityCapability().map(cap -> cap.ping(newVpnUrl)).orElse(null) : null;
cameraHelper.setUrls(newVpnUrl, localUrl);
eventHelper.setUrls(newVpnUrl, localUrl);
}
@ -107,14 +106,15 @@ public class CameraCapability extends HomeSecurityThingCapability {
// The channel should get triggered at last (after super and sub methods), because this allows rules to access
// the new updated data from the other channels.
final String eventType = event.getEventType().name();
handler.getHomeHandler().ifPresent(homeHandler -> homeHandler.triggerChannel(CHANNEL_HOME_EVENT, eventType));
handler.recurseUpToHomeHandler(handler)
.ifPresent(homeHandler -> homeHandler.triggerChannel(CHANNEL_HOME_EVENT, eventType));
handler.triggerChannel(CHANNEL_HOME_EVENT, eventType);
}
@Override
public void handleCommand(String channelName, Command command) {
if (command instanceof OnOffType && CHANNEL_MONITORING.equals(channelName)) {
securityCapability.ifPresent(cap -> cap.changeStatus(localUrl, OnOffType.ON.equals(command)));
getSecurityCapability().ifPresent(cap -> cap.changeStatus(localUrl, OnOffType.ON.equals(command)));
} else {
super.handleCommand(channelName, command);
}
@ -123,7 +123,7 @@ public class CameraCapability extends HomeSecurityThingCapability {
@Override
protected void beforeNewData() {
super.beforeNewData();
securityCapability.ifPresent(cap -> {
getSecurityCapability().ifPresent(cap -> {
NAObjectMap<HomeDataPerson> persons = cap.getPersons();
descriptionProvider.setStateOptions(personChannelUID, persons.values().stream()
.map(p -> new StateOption(p.getId(), p.getName())).collect(Collectors.toList()));
@ -133,7 +133,7 @@ public class CameraCapability extends HomeSecurityThingCapability {
@Override
public List<NAObject> updateReadings() {
List<NAObject> result = new ArrayList<>();
securityCapability.ifPresent(cap -> {
getSecurityCapability().ifPresent(cap -> {
HomeEvent event = cap.getDeviceLastEvent(handler.getId(), moduleType.apiName);
if (event != null) {
result.add(event);

View File

@ -47,7 +47,7 @@ public class HomeCapability extends RestCapability<HomeApi> {
private final Logger logger = LoggerFactory.getLogger(HomeCapability.class);
private final Set<FeatureArea> featureAreas = new HashSet<>();
private final NetatmoDescriptionProvider descriptionProvider;
private Set<String> homeIds = Set.of();
private final Set<String> homeIds = new HashSet<>();
public HomeCapability(CommonInterface handler, NetatmoDescriptionProvider descriptionProvider) {
super(handler, HomeApi.class);
@ -58,7 +58,19 @@ public class HomeCapability extends RestCapability<HomeApi> {
public void initialize() {
super.initialize();
HomeConfiguration config = handler.getConfiguration().as(HomeConfiguration.class);
homeIds = Set.of(config.getId(), config.energyId, config.securityId);
homeIds.add(config.getId());
if (!config.energyId.isBlank()) {
homeIds.add(config.energyId);
}
if (!config.securityId.isBlank()) {
homeIds.add(config.securityId);
}
}
@Override
public void dispose() {
homeIds.clear();
super.dispose();
}
@Override

View File

@ -36,8 +36,8 @@ public class HomeSecurityThingCapability extends Capability {
protected final EventChannelHelper eventHelper;
private Optional<WebhookServlet> webhook = Optional.empty();
protected Optional<SecurityCapability> securityCapability = Optional.empty();
protected Optional<HomeCapability> homeCapability = Optional.empty();
private Optional<SecurityCapability> securityCapability = Optional.empty();
private Optional<HomeCapability> homeCapability = Optional.empty();
public HomeSecurityThingCapability(CommonInterface handler, NetatmoDescriptionProvider descriptionProvider,
List<ChannelHelper> channelHelpers) {
@ -49,16 +49,23 @@ public class HomeSecurityThingCapability extends Capability {
eventHelper.setModuleType(moduleType);
}
@Override
public void initialize() {
super.initialize();
securityCapability = handler.getHomeCapability(SecurityCapability.class);
homeCapability = handler.getHomeCapability(HomeCapability.class);
ApiBridgeHandler accountHandler = handler.getAccountHandler();
if (accountHandler != null) {
webhook = accountHandler.getWebHookServlet();
webhook.ifPresent(servlet -> servlet.registerDataListener(handler.getId(), this));
protected Optional<SecurityCapability> getSecurityCapability() {
if (securityCapability.isEmpty()) {
securityCapability = handler.getHomeCapability(SecurityCapability.class);
ApiBridgeHandler accountHandler = handler.getAccountHandler();
if (accountHandler != null) {
webhook = accountHandler.getWebHookServlet();
webhook.ifPresent(servlet -> servlet.registerDataListener(handler.getId(), this));
}
}
return securityCapability;
}
protected Optional<HomeCapability> getHomeCapability() {
if (homeCapability.isEmpty()) {
homeCapability = handler.getHomeCapability(HomeCapability.class);
}
return homeCapability;
}
@Override

View File

@ -56,7 +56,7 @@ public class PersonCapability extends HomeSecurityThingCapability {
@Override
protected void beforeNewData() {
super.beforeNewData();
securityCapability.ifPresent(cap -> {
getSecurityCapability().ifPresent(cap -> {
Stream<HomeDataModule> cameras = cap.getModules().values().stream()
.filter(module -> module.getType() == ModuleType.WELCOME);
descriptionProvider.setStateOptions(cameraChannelUID,
@ -67,7 +67,7 @@ public class PersonCapability extends HomeSecurityThingCapability {
@Override
public void handleCommand(String channelName, Command command) {
if ((command instanceof OnOffType) && CHANNEL_PERSON_AT_HOME.equals(channelName)) {
securityCapability.ifPresent(cap -> cap.setPersonAway(handler.getId(), OnOffType.OFF.equals(command)));
getSecurityCapability().ifPresent(cap -> cap.setPersonAway(handler.getId(), OnOffType.OFF.equals(command)));
}
}
@ -88,7 +88,7 @@ public class PersonCapability extends HomeSecurityThingCapability {
@Override
public List<NAObject> updateReadings() {
List<NAObject> result = new ArrayList<>();
securityCapability.ifPresent(cap -> {
getSecurityCapability().ifPresent(cap -> {
HomeEvent event = cap.getLastPersonEvent(handler.getId());
if (event != null) {
result.add(event);

View File

@ -62,6 +62,6 @@ public class PresenceCapability extends CameraCapability {
}
private void changeFloodlightMode(FloodLightMode mode) {
securityCapability.ifPresent(cap -> cap.changeFloodlightMode(handler.getId(), mode));
getSecurityCapability().ifPresent(cap -> cap.changeFloodlightMode(handler.getId(), mode));
}
}