[netatmo] Handling camera ping timeouts (#13487)
* Solves #13486 Signed-off-by: clinique <gael@lhopital.org>
This commit is contained in:
parent
2519ec7236
commit
e14ce7d9eb
|
@ -21,6 +21,7 @@ import java.util.stream.Collectors;
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import javax.ws.rs.core.UriBuilder;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
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.data.NetatmoConstants.FloodLightMode;
|
import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.FloodLightMode;
|
||||||
import org.openhab.binding.netatmo.internal.api.dto.Home;
|
import org.openhab.binding.netatmo.internal.api.dto.Home;
|
||||||
|
@ -28,6 +29,8 @@ import org.openhab.binding.netatmo.internal.api.dto.HomeEvent;
|
||||||
import org.openhab.binding.netatmo.internal.api.dto.HomeEvent.NAEventsDataResponse;
|
import org.openhab.binding.netatmo.internal.api.dto.HomeEvent.NAEventsDataResponse;
|
||||||
import org.openhab.binding.netatmo.internal.api.dto.Ping;
|
import org.openhab.binding.netatmo.internal.api.dto.Ping;
|
||||||
import org.openhab.binding.netatmo.internal.handler.ApiBridgeHandler;
|
import org.openhab.binding.netatmo.internal.handler.ApiBridgeHandler;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for all Security related endpoints
|
* Base class for all Security related endpoints
|
||||||
|
@ -36,6 +39,8 @@ import org.openhab.binding.netatmo.internal.handler.ApiBridgeHandler;
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class SecurityApi extends RestManager {
|
public class SecurityApi extends RestManager {
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(SecurityApi.class);
|
||||||
|
|
||||||
public SecurityApi(ApiBridgeHandler apiClient) {
|
public SecurityApi(ApiBridgeHandler apiClient) {
|
||||||
super(apiClient, FeatureArea.SECURITY);
|
super(apiClient, FeatureArea.SECURITY);
|
||||||
}
|
}
|
||||||
|
@ -91,10 +96,14 @@ public class SecurityApi extends RestManager {
|
||||||
throw new NetatmoException("home should not be null");
|
throw new NetatmoException("home should not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String ping(String vpnUrl) throws NetatmoException {
|
public @Nullable String ping(String vpnUrl) {
|
||||||
UriBuilder uriBuilder = UriBuilder.fromUri(vpnUrl).path(PATH_COMMAND).path(SUB_PATH_PING);
|
UriBuilder uriBuilder = UriBuilder.fromUri(vpnUrl).path(PATH_COMMAND).path(SUB_PATH_PING);
|
||||||
Ping response = get(uriBuilder, Ping.class);
|
try {
|
||||||
return response.getStatus();
|
return get(uriBuilder, Ping.class).getStatus();
|
||||||
|
} catch (NetatmoException e) {
|
||||||
|
logger.debug("Pinging {} failed : {}", vpnUrl, e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void changeStatus(String localCameraURL, boolean setOn) throws NetatmoException {
|
public void changeStatus(String localCameraURL, boolean setOn) throws NetatmoException {
|
||||||
|
|
|
@ -155,7 +155,9 @@ public interface CommonInterface {
|
||||||
finalReason = thingStatusReason;
|
finalReason = thingStatusReason;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!newData.isIgnoredForThingUpdate()) {
|
// Prevent turning ONLINE myself if in the meantime something turned account OFFLINE
|
||||||
|
ApiBridgeHandler accountHandler = getAccountHandler();
|
||||||
|
if (accountHandler != null && accountHandler.isConnected() && !newData.isIgnoredForThingUpdate()) {
|
||||||
setThingStatus(finalReason == null ? ThingStatus.ONLINE : ThingStatus.OFFLINE, ThingStatusDetail.NONE,
|
setThingStatus(finalReason == null ? ThingStatus.ONLINE : ThingStatus.OFFLINE, ThingStatusDetail.NONE,
|
||||||
finalReason);
|
finalReason);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ public class CameraCapability extends HomeSecurityThingCapability {
|
||||||
private final ChannelUID personChannelUID;
|
private final ChannelUID personChannelUID;
|
||||||
|
|
||||||
protected @Nullable String localUrl;
|
protected @Nullable String localUrl;
|
||||||
|
protected @Nullable String vpnUrl;
|
||||||
|
|
||||||
public CameraCapability(CommonInterface handler, NetatmoDescriptionProvider descriptionProvider,
|
public CameraCapability(CommonInterface handler, NetatmoDescriptionProvider descriptionProvider,
|
||||||
List<ChannelHelper> channelHelpers) {
|
List<ChannelHelper> channelHelpers) {
|
||||||
|
@ -62,12 +63,15 @@ public class CameraCapability extends HomeSecurityThingCapability {
|
||||||
@Override
|
@Override
|
||||||
public void updateHomeStatusModule(HomeStatusModule newData) {
|
public void updateHomeStatusModule(HomeStatusModule newData) {
|
||||||
super.updateHomeStatusModule(newData);
|
super.updateHomeStatusModule(newData);
|
||||||
String vpnUrl = newData.getVpnUrl();
|
// Per documentation vpn_url expires every 3 hours and on camera reboot. So useless to reping it if not changed
|
||||||
if (vpnUrl != null) {
|
String newVpnUrl = newData.getVpnUrl();
|
||||||
localUrl = newData.isLocal() ? securityCapability.map(cap -> cap.ping(vpnUrl)).orElse(null) : null;
|
if (newVpnUrl != null && !newVpnUrl.equals(vpnUrl)) {
|
||||||
cameraHelper.setUrls(vpnUrl, localUrl);
|
// This will also decrease the number of requests emitted toward Netatmo API.
|
||||||
eventHelper.setUrls(vpnUrl, localUrl);
|
localUrl = newData.isLocal() ? securityCapability.map(cap -> cap.ping(newVpnUrl)).orElse(null) : null;
|
||||||
|
cameraHelper.setUrls(newVpnUrl, localUrl);
|
||||||
|
eventHelper.setUrls(newVpnUrl, localUrl);
|
||||||
}
|
}
|
||||||
|
vpnUrl = newVpnUrl;
|
||||||
if (!SdCardStatus.SD_CARD_WORKING.equals(newData.getSdStatus())
|
if (!SdCardStatus.SD_CARD_WORKING.equals(newData.getSdStatus())
|
||||||
|| !AlimentationStatus.ALIM_CORRECT_POWER.equals(newData.getAlimStatus())) {
|
|| !AlimentationStatus.ALIM_CORRECT_POWER.equals(newData.getAlimStatus())) {
|
||||||
statusReason = String.format("%s, %s", newData.getSdStatus(), newData.getAlimStatus());
|
statusReason = String.format("%s, %s", newData.getSdStatus(), newData.getAlimStatus());
|
||||||
|
|
|
@ -145,12 +145,7 @@ class SecurityCapability extends RestCapability<SecurityApi> {
|
||||||
|
|
||||||
public @Nullable String ping(String vpnUrl) {
|
public @Nullable String ping(String vpnUrl) {
|
||||||
return getApi().map(api -> {
|
return getApi().map(api -> {
|
||||||
try {
|
return api.ping(vpnUrl);
|
||||||
return api.ping(vpnUrl);
|
|
||||||
} catch (NetatmoException e) {
|
|
||||||
logger.warn("Error pinging camera '{}' : {}", vpnUrl, e.getMessage());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).orElse(null);
|
}).orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue