[netatmo] Take in account errored modules/devices for Security/Energy areas (#15587)

* Netatmo binding has to take in account errored modules/devices provided by HomeStatus api.

---------

Signed-off-by: clinique <gael@lhopital.org>
This commit is contained in:
Gaël L'hopital 2023-09-25 19:21:55 +02:00 committed by GitHub
parent 9c22b7b9ed
commit 87bede36db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 127 additions and 35 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 java.util.Collection;
import java.util.Optional;
import java.util.Set;
import javax.ws.rs.core.UriBuilder;
@ -25,7 +26,6 @@ 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.dto.HomeData;
import org.openhab.binding.netatmo.internal.api.dto.NAHomeStatus;
import org.openhab.binding.netatmo.internal.api.dto.NAHomeStatus.HomeStatus;
import org.openhab.binding.netatmo.internal.api.dto.NAHomeStatus.NAHomeStatusResponse;
import org.openhab.binding.netatmo.internal.handler.ApiBridgeHandler;
@ -43,12 +43,10 @@ public class HomeApi extends RestManager {
super(apiClient, FeatureArea.NONE);
}
public @Nullable HomeStatus getHomeStatus(String homeId) throws NetatmoException {
public Optional<NAHomeStatus> getHomeStatus(String homeId) throws NetatmoException {
UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_HOMESTATUS, PARAM_HOME_ID, homeId);
NAHomeStatusResponse response = get(uriBuilder, NAHomeStatusResponse.class);
NAHomeStatus body = response.getBody();
return body != null ? body.getHomeStatus().orElse(null) : null;
return Optional.ofNullable(get(uriBuilder, NAHomeStatusResponse.class).getBody());
}
public @Nullable HomeData getHomeData(String homeId) throws NetatmoException {

View File

@ -431,4 +431,27 @@ public class NetatmoConstants {
@SerializedName("41")
DEVICE_IS_UNREACHABLE
}
public enum HomeStatusError {
@SerializedName("1")
UNKNOWN_ERROR("homestatus-unknown-error"),
@SerializedName("2")
INTERNAL_ERROR("homestatus-internal-error"),
@SerializedName("3")
PARSER_ERROR("homestatus-parser-error"),
@SerializedName("4")
COMMAND_UNKNOWN_NODE_MODULE_ERROR("homestatus-command-unknown"),
@SerializedName("5")
COMMAND_INVALID_PARAMS("homestatus-invalid-params"),
@SerializedName("6")
UNREACHABLE("device-not-connected"),
UNKNOWN("deserialization-unknow");
// Associated error message that can be found in properties files
public final String message;
HomeStatusError(String message) {
this.message = message;
}
}
}

View File

@ -0,0 +1,32 @@
/**
* Copyright (c) 2010-2023 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.netatmo.internal.api.dto;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.HomeStatusError;
/**
* The {@link NAError} class is the base class for errors returned by the Netatmo API
* regarding a given thing.
*
* @author Gaël L'hopital - Initial contribution
*
*/
@NonNullByDefault
public class NAError extends NAObject {
private HomeStatusError code = HomeStatusError.UNKNOWN;
public HomeStatusError getCode() {
return code;
}
}

View File

@ -12,6 +12,7 @@
*/
package org.openhab.binding.netatmo.internal.api.dto;
import java.util.List;
import java.util.Optional;
import org.eclipse.jdt.annotation.NonNullByDefault;
@ -56,8 +57,13 @@ public class NAHomeStatus {
}
private @Nullable HomeStatus home;
private List<NAError> errors = List.of();
public Optional<HomeStatus> getHomeStatus() {
return Optional.ofNullable(home);
}
public List<NAError> getErrors() {
return errors;
}
}

View File

@ -28,6 +28,7 @@ import org.openhab.binding.netatmo.internal.api.dto.Event;
import org.openhab.binding.netatmo.internal.api.dto.HomeData;
import org.openhab.binding.netatmo.internal.api.dto.HomeEvent;
import org.openhab.binding.netatmo.internal.api.dto.HomeStatusModule;
import org.openhab.binding.netatmo.internal.api.dto.NAError;
import org.openhab.binding.netatmo.internal.api.dto.NAHomeStatus.HomeStatus;
import org.openhab.binding.netatmo.internal.api.dto.NAMain;
import org.openhab.binding.netatmo.internal.api.dto.NAObject;
@ -63,32 +64,37 @@ public class Capability {
public final @Nullable String setNewData(NAObject newData) {
beforeNewData();
if (newData instanceof HomeData homeData) {
updateHomeData(homeData);
}
if (newData instanceof HomeStatus homeStatus) {
updateHomeStatus(homeStatus);
}
if (newData instanceof HomeStatusModule homeStatusModule) {
updateHomeStatusModule(homeStatusModule);
}
if (newData instanceof NAError error) {
updateErrors(error);
} else {
if (newData instanceof HomeData homeData) {
updateHomeData(homeData);
}
if (newData instanceof HomeStatus homeStatus) {
updateHomeStatus(homeStatus);
}
if (newData instanceof HomeStatusModule homeStatusModule) {
updateHomeStatusModule(homeStatusModule);
}
if (newData instanceof HomeEvent homeEvent) {
updateHomeEvent(homeEvent);
} else if (newData instanceof WebhookEvent webhookEvent && webhookEvent.getEventType().validFor(moduleType)) {
updateWebhookEvent(webhookEvent);
} else if (newData instanceof Event event) {
updateEvent(event);
}
if (newData instanceof HomeEvent homeEvent) {
updateHomeEvent(homeEvent);
} else if (newData instanceof WebhookEvent webhookEvent
&& webhookEvent.getEventType().validFor(moduleType)) {
updateWebhookEvent(webhookEvent);
} else if (newData instanceof Event event) {
updateEvent(event);
}
if (newData instanceof NAThing naThing) {
updateNAThing(naThing);
}
if (newData instanceof NAMain naMain) {
updateNAMain(naMain);
}
if (newData instanceof Device device) {
updateNADevice(device);
if (newData instanceof NAThing naThing) {
updateNAThing(naThing);
}
if (newData instanceof NAMain naMain) {
updateNAMain(naMain);
}
if (newData instanceof Device device) {
updateNADevice(device);
}
}
afterNewData(newData);
return statusReason;
@ -152,6 +158,10 @@ public class Capability {
// do nothing by default, can be overridden by subclasses
}
protected void updateErrors(NAError error) {
// do nothing by default, can be overridden by subclasses
}
public void initialize() {
// do nothing by default, can be overridden by subclasses
}

View File

@ -16,6 +16,7 @@ import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.netatmo.internal.api.dto.NAError;
import org.openhab.binding.netatmo.internal.api.dto.NAObject;
import org.openhab.binding.netatmo.internal.handler.CommonInterface;
import org.openhab.binding.netatmo.internal.handler.channelhelper.ChannelHelper;
@ -25,6 +26,7 @@ import org.openhab.core.types.State;
/**
* {@link ChannelHelperCapability} give the capability to dispatch incoming data across the channel helpers.
* This capability is common to all things
*
* @author Gaël L'hopital - Initial contribution
*
@ -56,4 +58,11 @@ public class ChannelHelperCapability extends Capability {
}
});
}
@Override
protected void updateErrors(NAError error) {
if (error.getId().equals(handler.getId())) {
statusReason = "@text/%s".formatted(error.getCode().message);
}
}
}

View File

@ -27,7 +27,7 @@ import org.openhab.binding.netatmo.internal.api.NetatmoException;
import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.FeatureArea;
import org.openhab.binding.netatmo.internal.api.dto.HomeData;
import org.openhab.binding.netatmo.internal.api.dto.Location;
import org.openhab.binding.netatmo.internal.api.dto.NAHomeStatus.HomeStatus;
import org.openhab.binding.netatmo.internal.api.dto.NAError;
import org.openhab.binding.netatmo.internal.api.dto.NAObject;
import org.openhab.binding.netatmo.internal.config.HomeConfiguration;
import org.openhab.binding.netatmo.internal.handler.CommonInterface;
@ -105,6 +105,12 @@ public class HomeCapability extends RestCapability<HomeApi> {
return featureAreas.contains(searched);
}
@Override
protected void updateErrors(NAError error) {
handler.getActiveChildren().stream().filter(handler -> handler.getId().equals(error.getId())).findFirst()
.ifPresent(handler -> handler.setNewData(error));
}
@Override
protected List<NAObject> updateReadings(HomeApi api) {
List<NAObject> result = new ArrayList<>();
@ -115,10 +121,11 @@ public class HomeCapability extends RestCapability<HomeApi> {
result.add(homeData);
featureAreas.addAll(homeData.getFeatures());
}
HomeStatus homeStatus = api.getHomeStatus(id);
if (homeStatus != null) {
result.add(homeStatus);
}
api.getHomeStatus(id).ifPresent(body -> {
body.getHomeStatus().ifPresent(homeStatus -> result.add(homeStatus));
result.addAll(body.getErrors());
});
} catch (NetatmoException e) {
logger.warn("Error getting Home informations : {}", e.getMessage());
}

View File

@ -116,7 +116,7 @@ class SecurityCapability extends RestCapability<SecurityApi> {
return;
}
handler.getActiveChildren(FeatureArea.SECURITY).filter(child -> child.getId().equals(objectId))
.forEach(child -> child.setNewData(homeEvent.ignoringForThingUpdate()));
.forEach(child -> child.setNewData(homeEvent));
}
@Override

View File

@ -462,6 +462,13 @@ status-bridge-offline = Bridge is not connected to Netatmo API
device-not-connected = Thing is not reachable
data-over-limit = Data seems quite old
request-time-out = Request timed out - will attempt reconnection later
deserialization-unknow = Deserialization lead to an unknown code
homestatus-unknown-error = Unknown error
homestatus-internal-error = Internal error
homestatus-parser-error = Parser error
homestatus-command-unknown = Command unknown node module error
homestatus-invalid-params = Command invalid params
# actions