From 87bede36db05037a7a48bdc750b7122d4b87b8aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20L=27hopital?= Date: Mon, 25 Sep 2023 19:21:55 +0200 Subject: [PATCH] [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 --- .../binding/netatmo/internal/api/HomeApi.java | 8 +-- .../internal/api/data/NetatmoConstants.java | 23 ++++++++ .../netatmo/internal/api/dto/NAError.java | 32 ++++++++++ .../internal/api/dto/NAHomeStatus.java | 6 ++ .../handler/capability/Capability.java | 58 +++++++++++-------- .../capability/ChannelHelperCapability.java | 9 +++ .../handler/capability/HomeCapability.java | 17 ++++-- .../capability/SecurityCapability.java | 2 +- .../resources/OH-INF/i18n/netatmo.properties | 7 +++ 9 files changed, 127 insertions(+), 35 deletions(-) create mode 100644 bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/NAError.java diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/HomeApi.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/HomeApi.java index 39adb3e6a..092821b15 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/HomeApi.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/HomeApi.java @@ -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 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 { diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/data/NetatmoConstants.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/data/NetatmoConstants.java index 38de0898c..5f7cbae1e 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/data/NetatmoConstants.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/data/NetatmoConstants.java @@ -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; + } + } } diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/NAError.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/NAError.java new file mode 100644 index 000000000..cdc36e8b9 --- /dev/null +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/NAError.java @@ -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; + } +} diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/NAHomeStatus.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/NAHomeStatus.java index f13e2d976..59861c4dd 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/NAHomeStatus.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/NAHomeStatus.java @@ -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 errors = List.of(); public Optional getHomeStatus() { return Optional.ofNullable(home); } + + public List getErrors() { + return errors; + } } diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/Capability.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/Capability.java index e21f5f39d..5799e9507 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/Capability.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/Capability.java @@ -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 } diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/ChannelHelperCapability.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/ChannelHelperCapability.java index 04f0e0563..deed510bb 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/ChannelHelperCapability.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/ChannelHelperCapability.java @@ -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); + } + } } diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/HomeCapability.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/HomeCapability.java index 537c1dfa6..f9e281ab5 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/HomeCapability.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/HomeCapability.java @@ -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 { 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 updateReadings(HomeApi api) { List result = new ArrayList<>(); @@ -115,10 +121,11 @@ public class HomeCapability extends RestCapability { 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()); } diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/SecurityCapability.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/SecurityCapability.java index 3cecf7f63..f412ce57b 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/SecurityCapability.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/SecurityCapability.java @@ -116,7 +116,7 @@ class SecurityCapability extends RestCapability { return; } handler.getActiveChildren(FeatureArea.SECURITY).filter(child -> child.getId().equals(objectId)) - .forEach(child -> child.setNewData(homeEvent.ignoringForThingUpdate())); + .forEach(child -> child.setNewData(homeEvent)); } @Override diff --git a/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/i18n/netatmo.properties b/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/i18n/netatmo.properties index c67f080b4..239d43971 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/i18n/netatmo.properties +++ b/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/i18n/netatmo.properties @@ -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