diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java index deabb7fb7..344dc6ab1 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java @@ -13,6 +13,7 @@ package org.openhab.binding.hdpowerview.internal; import java.time.Instant; +import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; @@ -32,15 +33,23 @@ import org.openhab.binding.hdpowerview.internal.api.requests.ShadeStop; import org.openhab.binding.hdpowerview.internal.api.responses.FirmwareVersion; import org.openhab.binding.hdpowerview.internal.api.responses.FirmwareVersions; import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections; +import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections.SceneCollection; import org.openhab.binding.hdpowerview.internal.api.responses.Scenes; +import org.openhab.binding.hdpowerview.internal.api.responses.Scenes.Scene; import org.openhab.binding.hdpowerview.internal.api.responses.ScheduledEvents; +import org.openhab.binding.hdpowerview.internal.api.responses.ScheduledEvents.ScheduledEvent; import org.openhab.binding.hdpowerview.internal.api.responses.Shade; import org.openhab.binding.hdpowerview.internal.api.responses.Shades; +import org.openhab.binding.hdpowerview.internal.api.responses.Shades.ShadeData; import org.openhab.binding.hdpowerview.internal.api.responses.Survey; +import org.openhab.binding.hdpowerview.internal.exceptions.HubInvalidResponseException; +import org.openhab.binding.hdpowerview.internal.exceptions.HubMaintenanceException; +import org.openhab.binding.hdpowerview.internal.exceptions.HubProcessingException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.Gson; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import com.google.gson.JsonParser; @@ -133,22 +142,26 @@ public class HDPowerViewWebTargets { * Fetches a JSON package with firmware information for the hub. * * @return FirmwareVersions class instance - * @throws JsonParseException if there is a JSON parsing error + * @throws HubInvalidResponseException if response is invalid * @throws HubProcessingException if there is any processing error * @throws HubMaintenanceException if the hub is down for maintenance */ public FirmwareVersions getFirmwareVersions() - throws JsonParseException, HubProcessingException, HubMaintenanceException { + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { String json = invoke(HttpMethod.GET, firmwareVersion, null, null); - FirmwareVersion firmwareVersion = gson.fromJson(json, FirmwareVersion.class); - if (firmwareVersion == null) { - throw new JsonParseException("Missing firmware response"); + try { + FirmwareVersion firmwareVersion = gson.fromJson(json, FirmwareVersion.class); + if (firmwareVersion == null) { + throw new HubInvalidResponseException("Missing firmware response"); + } + FirmwareVersions firmwareVersions = firmwareVersion.firmware; + if (firmwareVersions == null) { + throw new HubInvalidResponseException("Missing 'firmware' element"); + } + return firmwareVersions; + } catch (JsonParseException e) { + throw new HubInvalidResponseException("Error parsing firmware response", e); } - FirmwareVersions firmwareVersions = firmwareVersion.firmware; - if (firmwareVersions == null) { - throw new JsonParseException("Missing 'firmware' element"); - } - return firmwareVersions; } /** @@ -156,13 +169,25 @@ public class HDPowerViewWebTargets { * a Shades class instance * * @return Shades class instance - * @throws JsonParseException if there is a JSON parsing error + * @throws HubInvalidResponseException if response is invalid * @throws HubProcessingException if there is any processing error * @throws HubMaintenanceException if the hub is down for maintenance */ - public @Nullable Shades getShades() throws JsonParseException, HubProcessingException, HubMaintenanceException { + public Shades getShades() throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { String json = invoke(HttpMethod.GET, shades, null, null); - return gson.fromJson(json, Shades.class); + try { + Shades shades = gson.fromJson(json, Shades.class); + if (shades == null) { + throw new HubInvalidResponseException("Missing shades response"); + } + List shadeData = shades.shadeData; + if (shadeData == null) { + throw new HubInvalidResponseException("Missing 'shades.shadeData' element"); + } + return shades; + } catch (JsonParseException e) { + throw new HubInvalidResponseException("Error parsing shades response", e); + } } /** @@ -170,45 +195,64 @@ public class HDPowerViewWebTargets { * * @param shadeId id of the shade to be moved * @param position instance of ShadePosition containing the new position - * @return Shade class instance (with new position) + * @return ShadeData class instance (with new position) + * @throws HubInvalidResponseException if response is invalid * @throws HubProcessingException if there is any processing error * @throws HubMaintenanceException if the hub is down for maintenance */ - public @Nullable Shade moveShade(int shadeId, ShadePosition position) - throws JsonParseException, HubProcessingException, HubMaintenanceException { + public ShadeData moveShade(int shadeId, ShadePosition position) + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { String jsonRequest = gson.toJson(new ShadeMove(position)); String jsonResponse = invoke(HttpMethod.PUT, shades + Integer.toString(shadeId), null, jsonRequest); - return gson.fromJson(jsonResponse, Shade.class); + return shadeDataFromJson(jsonResponse); + } + + private ShadeData shadeDataFromJson(String json) throws HubInvalidResponseException { + try { + Shade shade = gson.fromJson(json, Shade.class); + if (shade == null) { + throw new HubInvalidResponseException("Missing shade response"); + } + ShadeData shadeData = shade.shade; + if (shadeData == null) { + throw new HubInvalidResponseException("Missing 'shade.shade' element"); + } + return shadeData; + } catch (JsonParseException e) { + throw new HubInvalidResponseException("Error parsing shade response", e); + } } /** * Instructs the hub to stop movement of a specific shade * * @param shadeId id of the shade to be stopped - * @return Shade class instance (new position cannot be relied upon) + * @return ShadeData class instance (new position cannot be relied upon) + * @throws HubInvalidResponseException if response is invalid * @throws HubProcessingException if there is any processing error * @throws HubMaintenanceException if the hub is down for maintenance */ - public @Nullable Shade stopShade(int shadeId) - throws JsonParseException, HubProcessingException, HubMaintenanceException { + public ShadeData stopShade(int shadeId) + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { String jsonRequest = gson.toJson(new ShadeStop()); String jsonResponse = invoke(HttpMethod.PUT, shades + Integer.toString(shadeId), null, jsonRequest); - return gson.fromJson(jsonResponse, Shade.class); + return shadeDataFromJson(jsonResponse); } /** * Instructs the hub to calibrate a specific shade * * @param shadeId id of the shade to be calibrated - * @return Shade class instance + * @return ShadeData class instance + * @throws HubInvalidResponseException if response is invalid * @throws HubProcessingException if there is any processing error * @throws HubMaintenanceException if the hub is down for maintenance */ - public @Nullable Shade calibrateShade(int shadeId) - throws JsonParseException, HubProcessingException, HubMaintenanceException { + public ShadeData calibrateShade(int shadeId) + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { String jsonRequest = gson.toJson(new ShadeCalibrate()); String jsonResponse = invoke(HttpMethod.PUT, shades + Integer.toString(shadeId), null, jsonRequest); - return gson.fromJson(jsonResponse, Shade.class); + return shadeDataFromJson(jsonResponse); } /** @@ -216,13 +260,25 @@ public class HDPowerViewWebTargets { * a Scenes class instance * * @return Scenes class instance - * @throws JsonParseException if there is a JSON parsing error + * @throws HubInvalidResponseException if response is invalid * @throws HubProcessingException if there is any processing error * @throws HubMaintenanceException if the hub is down for maintenance */ - public @Nullable Scenes getScenes() throws JsonParseException, HubProcessingException, HubMaintenanceException { + public Scenes getScenes() throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { String json = invoke(HttpMethod.GET, scenes, null, null); - return gson.fromJson(json, Scenes.class); + try { + Scenes scenes = gson.fromJson(json, Scenes.class); + if (scenes == null) { + throw new HubInvalidResponseException("Missing scenes response"); + } + List sceneData = scenes.sceneData; + if (sceneData == null) { + throw new HubInvalidResponseException("Missing 'scenes.sceneData' element"); + } + return scenes; + } catch (JsonParseException e) { + throw new HubInvalidResponseException("Error parsing scenes response", e); + } } /** @@ -241,14 +297,26 @@ public class HDPowerViewWebTargets { * a SceneCollections class instance * * @return SceneCollections class instance - * @throws JsonParseException if there is a JSON parsing error + * @throws HubInvalidResponseException if response is invalid * @throws HubProcessingException if there is any processing error * @throws HubMaintenanceException if the hub is down for maintenance */ - public @Nullable SceneCollections getSceneCollections() - throws JsonParseException, HubProcessingException, HubMaintenanceException { + public SceneCollections getSceneCollections() + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { String json = invoke(HttpMethod.GET, sceneCollections, null, null); - return gson.fromJson(json, SceneCollections.class); + try { + SceneCollections sceneCollections = gson.fromJson(json, SceneCollections.class); + if (sceneCollections == null) { + throw new HubInvalidResponseException("Missing sceneCollections response"); + } + List sceneCollectionData = sceneCollections.sceneCollectionData; + if (sceneCollectionData == null) { + throw new HubInvalidResponseException("Missing 'sceneCollections.sceneCollectionData' element"); + } + return sceneCollections; + } catch (JsonParseException e) { + throw new HubInvalidResponseException("Error parsing sceneCollections response", e); + } } /** @@ -268,14 +336,26 @@ public class HDPowerViewWebTargets { * a ScheduledEvents class instance * * @return ScheduledEvents class instance - * @throws JsonParseException if there is a JSON parsing error + * @throws HubInvalidResponseException if response is invalid * @throws HubProcessingException if there is any processing error * @throws HubMaintenanceException if the hub is down for maintenance */ - public @Nullable ScheduledEvents getScheduledEvents() - throws JsonParseException, HubProcessingException, HubMaintenanceException { + public ScheduledEvents getScheduledEvents() + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { String json = invoke(HttpMethod.GET, scheduledEvents, null, null); - return gson.fromJson(json, ScheduledEvents.class); + try { + ScheduledEvents scheduledEvents = gson.fromJson(json, ScheduledEvents.class); + if (scheduledEvents == null) { + throw new HubInvalidResponseException("Missing scheduledEvents response"); + } + List scheduledEventData = scheduledEvents.scheduledEventData; + if (scheduledEventData == null) { + throw new HubInvalidResponseException("Missing 'scheduledEvents.scheduledEventData' element"); + } + return scheduledEvents; + } catch (JsonParseException e) { + throw new HubInvalidResponseException("Error parsing scheduledEvents response", e); + } } /** @@ -283,19 +363,26 @@ public class HDPowerViewWebTargets { * * @param scheduledEventId id of the scheduled event to be enabled or disabled * @param enable true to enable scheduled event, false to disable - * @throws JsonParseException if there is a JSON parsing error - * @throws JsonSyntaxException if there is a JSON syntax error + * @throws HubInvalidResponseException if response is invalid * @throws HubProcessingException if there is any processing error * @throws HubMaintenanceException if the hub is down for maintenance */ public void enableScheduledEvent(int scheduledEventId, boolean enable) - throws JsonParseException, HubProcessingException, HubMaintenanceException { + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { String uri = scheduledEvents + "/" + scheduledEventId; - String json = invoke(HttpMethod.GET, uri, null, null); - JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject(); - JsonObject scheduledEventObject = jsonObject.get("scheduledEvent").getAsJsonObject(); - scheduledEventObject.addProperty("enabled", enable); - invoke(HttpMethod.PUT, uri, null, jsonObject.toString()); + String jsonResponse = invoke(HttpMethod.GET, uri, null, null); + try { + JsonObject jsonObject = JsonParser.parseString(jsonResponse).getAsJsonObject(); + JsonElement scheduledEventElement = jsonObject.get("scheduledEvent"); + if (scheduledEventElement == null) { + throw new HubInvalidResponseException("Missing 'scheduledEvent' element"); + } + JsonObject scheduledEventObject = scheduledEventElement.getAsJsonObject(); + scheduledEventObject.addProperty("enabled", enable); + invoke(HttpMethod.PUT, uri, null, jsonObject.toString()); + } catch (JsonParseException | IllegalStateException e) { + throw new HubInvalidResponseException("Error parsing scheduledEvent response", e); + } } /** @@ -366,15 +453,15 @@ public class HDPowerViewWebTargets { * in a Shade class instance * * @param shadeId id of the shade to be fetched - * @return Shade class instance - * @throws JsonParseException if there is a JSON parsing error + * @return ShadeData class instance + * @throws HubInvalidResponseException if response is invalid * @throws HubProcessingException if there is any processing error * @throws HubMaintenanceException if the hub is down for maintenance */ - public @Nullable Shade getShade(int shadeId) - throws JsonParseException, HubProcessingException, HubMaintenanceException { - String json = invoke(HttpMethod.GET, shades + Integer.toString(shadeId), null, null); - return gson.fromJson(json, Shade.class); + public ShadeData getShade(int shadeId) + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { + String jsonResponse = invoke(HttpMethod.GET, shades + Integer.toString(shadeId), null, null); + return shadeDataFromJson(jsonResponse); } /** @@ -383,16 +470,16 @@ public class HDPowerViewWebTargets { * and wraps it in a Shade class instance * * @param shadeId id of the shade to be refreshed - * @return Shade class instance - * @throws JsonParseException if there is a JSON parsing error + * @return ShadeData class instance + * @throws HubInvalidResponseException if response is invalid * @throws HubProcessingException if there is any processing error * @throws HubMaintenanceException if the hub is down for maintenance */ - public @Nullable Shade refreshShadePosition(int shadeId) + public ShadeData refreshShadePosition(int shadeId) throws JsonParseException, HubProcessingException, HubMaintenanceException { - String json = invoke(HttpMethod.GET, shades + Integer.toString(shadeId), + String jsonResponse = invoke(HttpMethod.GET, shades + Integer.toString(shadeId), Query.of("refresh", Boolean.toString(true)), null); - return gson.fromJson(json, Shade.class); + return shadeDataFromJson(jsonResponse); } /** @@ -403,15 +490,23 @@ public class HDPowerViewWebTargets { * * @param shadeId id of the shade to be surveyed * @return Survey class instance - * @throws JsonParseException if there is a JSON parsing error + * @throws HubInvalidResponseException if response is invalid * @throws HubProcessingException if there is any processing error * @throws HubMaintenanceException if the hub is down for maintenance */ - public @Nullable Survey getShadeSurvey(int shadeId) - throws JsonParseException, HubProcessingException, HubMaintenanceException { - String json = invoke(HttpMethod.GET, shades + Integer.toString(shadeId), + public Survey getShadeSurvey(int shadeId) + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { + String jsonResponse = invoke(HttpMethod.GET, shades + Integer.toString(shadeId), Query.of("survey", Boolean.toString(true)), null); - return gson.fromJson(json, Survey.class); + try { + Survey survey = gson.fromJson(jsonResponse, Survey.class); + if (survey == null) { + throw new HubInvalidResponseException("Missing survey response"); + } + return survey; + } catch (JsonParseException e) { + throw new HubInvalidResponseException("Error parsing survey response", e); + } } /** @@ -420,15 +515,15 @@ public class HDPowerViewWebTargets { * and wraps it in a Shade class instance * * @param shadeId id of the shade to be refreshed - * @return Shade class instance - * @throws JsonParseException if there is a JSON parsing error + * @return ShadeData class instance + * @throws HubInvalidResponseException if response is invalid * @throws HubProcessingException if there is any processing error * @throws HubMaintenanceException if the hub is down for maintenance */ - public @Nullable Shade refreshShadeBatteryLevel(int shadeId) - throws JsonParseException, HubProcessingException, HubMaintenanceException { - String json = invoke(HttpMethod.GET, shades + Integer.toString(shadeId), + public ShadeData refreshShadeBatteryLevel(int shadeId) + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { + String jsonResponse = invoke(HttpMethod.GET, shades + Integer.toString(shadeId), Query.of("updateBatteryLevel", Boolean.toString(true)), null); - return gson.fromJson(json, Shade.class); + return shadeDataFromJson(jsonResponse); } } diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/SurveyData.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/SurveyData.java new file mode 100644 index 000000000..bfb5301ba --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/SurveyData.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2010-2022 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.hdpowerview.internal.api; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +import com.google.gson.annotations.SerializedName; + +/** + * Survey data of a single Shade, as returned by an HD PowerView hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class SurveyData { + @SerializedName("neighbor_id") + public int neighborId; + public int rssi; + + @Override + public String toString() { + return String.format("{neighbor id:%d, rssi:%d}", neighborId, rssi); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Survey.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Survey.java index 636f8b4c9..268e035c7 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Survey.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Survey.java @@ -17,6 +17,7 @@ import java.util.StringJoiner; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.hdpowerview.internal.api.SurveyData; import com.google.gson.annotations.SerializedName; @@ -33,17 +34,6 @@ public class Survey { @SerializedName("survey") public List surveyData; - public static class SurveyData { - @SerializedName("neighbor_id") - public int neighborId; - public int rssi; - - @Override - public String toString() { - return String.format("{neighbor id:%d, rssi:%d}", neighborId, rssi); - } - } - @Override public String toString() { List surveyData = this.surveyData; diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/discovery/HDPowerViewShadeDiscoveryService.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/discovery/HDPowerViewShadeDiscoveryService.java index ad1070902..0eecec137 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/discovery/HDPowerViewShadeDiscoveryService.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/discovery/HDPowerViewShadeDiscoveryService.java @@ -21,13 +21,14 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants; import org.openhab.binding.hdpowerview.internal.HDPowerViewWebTargets; -import org.openhab.binding.hdpowerview.internal.HubMaintenanceException; -import org.openhab.binding.hdpowerview.internal.HubProcessingException; import org.openhab.binding.hdpowerview.internal.api.responses.Shades; import org.openhab.binding.hdpowerview.internal.api.responses.Shades.ShadeData; import org.openhab.binding.hdpowerview.internal.config.HDPowerViewShadeConfiguration; import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase; import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase.Capabilities; +import org.openhab.binding.hdpowerview.internal.exceptions.HubException; +import org.openhab.binding.hdpowerview.internal.exceptions.HubMaintenanceException; +import org.openhab.binding.hdpowerview.internal.exceptions.HubProcessingException; import org.openhab.binding.hdpowerview.internal.handler.HDPowerViewHubHandler; import org.openhab.core.config.discovery.AbstractDiscoveryService; import org.openhab.core.config.discovery.DiscoveryResultBuilder; @@ -35,8 +36,6 @@ import org.openhab.core.thing.ThingUID; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.gson.JsonParseException; - /** * Discovers an HD PowerView Shade from an existing hub * @@ -89,7 +88,7 @@ public class HDPowerViewShadeDiscoveryService extends AbstractDiscoveryService { throw new HubProcessingException("Web targets not initialized"); } Shades shades = webTargets.getShades(); - if (shades != null && shades.shadeData != null) { + if (shades.shadeData != null) { ThingUID bridgeUID = hub.getThing().getUID(); List shadesData = shades.shadeData; if (shadesData != null) { @@ -116,10 +115,10 @@ public class HDPowerViewShadeDiscoveryService extends AbstractDiscoveryService { } } } - } catch (HubProcessingException | JsonParseException e) { - logger.warn("Unexpected error: {}", e.getMessage()); } catch (HubMaintenanceException e) { // exceptions are logged in HDPowerViewWebTargets + } catch (HubException e) { + logger.warn("Unexpected error: {}", e.getMessage()); } stopScan(); }; diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/exceptions/HubException.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/exceptions/HubException.java new file mode 100644 index 000000000..188ca133e --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/exceptions/HubException.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2010-2022 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.hdpowerview.internal.exceptions; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link HubException} is a generic custom exception for the HD PowerView Hub + * with the intent of being derived into specific exception classes. + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class HubException extends Exception { + + private static final long serialVersionUID = 4052375893291196875L; + + public HubException(String message) { + super(message); + } + + public HubException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/exceptions/HubInvalidResponseException.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/exceptions/HubInvalidResponseException.java new file mode 100644 index 000000000..3305835f3 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/exceptions/HubInvalidResponseException.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2010-2022 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.hdpowerview.internal.exceptions; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link HubInvalidResponseException} is a custom exception for the HD PowerView Hub + * which is thrown when a response does not adhere to a defined contract. + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class HubInvalidResponseException extends HubProcessingException { + + private static final long serialVersionUID = -2293572741003905474L; + + public HubInvalidResponseException(String message) { + super(message); + } + + public HubInvalidResponseException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HubMaintenanceException.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/exceptions/HubMaintenanceException.java similarity index 86% rename from bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HubMaintenanceException.java rename to bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/exceptions/HubMaintenanceException.java index 047fb40a6..b854d43ba 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HubMaintenanceException.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/exceptions/HubMaintenanceException.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.hdpowerview.internal; +package org.openhab.binding.hdpowerview.internal.exceptions; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -20,7 +20,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; * @author Andrew Fiddian-Green - Initial contribution */ @NonNullByDefault -public class HubMaintenanceException extends Exception { +public class HubMaintenanceException extends HubException { private static final long serialVersionUID = -708582495003057343L; diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HubProcessingException.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/exceptions/HubProcessingException.java similarity index 77% rename from bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HubProcessingException.java rename to bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/exceptions/HubProcessingException.java index ade2ceaf6..e8ae40a64 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HubProcessingException.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/exceptions/HubProcessingException.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.hdpowerview.internal; +package org.openhab.binding.hdpowerview.internal.exceptions; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -20,11 +20,15 @@ import org.eclipse.jdt.annotation.NonNullByDefault; * @author Andrew Fiddian-Green - Initial contribution */ @NonNullByDefault -public class HubProcessingException extends Exception { +public class HubProcessingException extends HubException { private static final long serialVersionUID = 4307088023775166450L; public HubProcessingException(String message) { super(message); } + + public HubProcessingException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java index 464cc2300..8b3d2c60e 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java @@ -34,8 +34,6 @@ import org.eclipse.jetty.client.HttpClient; import org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants; import org.openhab.binding.hdpowerview.internal.HDPowerViewTranslationProvider; import org.openhab.binding.hdpowerview.internal.HDPowerViewWebTargets; -import org.openhab.binding.hdpowerview.internal.HubMaintenanceException; -import org.openhab.binding.hdpowerview.internal.HubProcessingException; import org.openhab.binding.hdpowerview.internal.api.Firmware; import org.openhab.binding.hdpowerview.internal.api.responses.FirmwareVersions; import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections; @@ -48,6 +46,10 @@ import org.openhab.binding.hdpowerview.internal.api.responses.Shades; import org.openhab.binding.hdpowerview.internal.api.responses.Shades.ShadeData; import org.openhab.binding.hdpowerview.internal.config.HDPowerViewHubConfiguration; import org.openhab.binding.hdpowerview.internal.config.HDPowerViewShadeConfiguration; +import org.openhab.binding.hdpowerview.internal.exceptions.HubException; +import org.openhab.binding.hdpowerview.internal.exceptions.HubInvalidResponseException; +import org.openhab.binding.hdpowerview.internal.exceptions.HubMaintenanceException; +import org.openhab.binding.hdpowerview.internal.exceptions.HubProcessingException; import org.openhab.core.library.CoreItemFactory; import org.openhab.core.library.types.OnOffType; import org.openhab.core.thing.Bridge; @@ -66,8 +68,6 @@ import org.openhab.core.types.RefreshType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.gson.JsonParseException; - /** * The {@link HDPowerViewHubHandler} is responsible for handling commands, which * are sent to one of the channels. @@ -147,7 +147,7 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler { } } catch (HubMaintenanceException e) { // exceptions are logged in HDPowerViewWebTargets - } catch (NumberFormatException | HubProcessingException e) { + } catch (NumberFormatException | HubException e) { logger.debug("Unexpected error {}", e.getMessage()); } } @@ -267,17 +267,23 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler { // Scheduled events should also have their current state updated if event has been // enabled or disabled through app or other integration. updateScheduledEventStates(scheduledEvents); - } catch (JsonParseException e) { - logger.warn("Bridge returned a bad JSON response: {}", e.getMessage()); - } catch (HubProcessingException e) { - logger.warn("Error connecting to bridge: {}", e.getMessage()); - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, e.getMessage()); + } catch (HubInvalidResponseException e) { + Throwable cause = e.getCause(); + if (cause == null) { + logger.warn("Bridge returned a bad JSON response: {}", e.getMessage()); + } else { + logger.warn("Bridge returned a bad JSON response: {} -> {}", e.getMessage(), cause.getMessage()); + } } catch (HubMaintenanceException e) { // exceptions are logged in HDPowerViewWebTargets + } catch (HubException e) { + logger.warn("Error connecting to bridge: {}", e.getMessage()); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, e.getMessage()); } } - private void updateFirmwareProperties() throws JsonParseException, HubProcessingException, HubMaintenanceException { + private void updateFirmwareProperties() + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { if (firmwareVersions != null) { return; } @@ -306,20 +312,16 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler { updateProperties(properties); } - private void pollShades() throws JsonParseException, HubProcessingException, HubMaintenanceException { + private void pollShades() throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { HDPowerViewWebTargets webTargets = this.webTargets; if (webTargets == null) { throw new ProcessingException("Web targets not initialized"); } Shades shades = webTargets.getShades(); - if (shades == null) { - throw new JsonParseException("Missing 'shades' element"); - } - List shadesData = shades.shadeData; if (shadesData == null) { - throw new JsonParseException("Missing 'shades.shadeData' element"); + throw new HubInvalidResponseException("Missing 'shades.shadeData' element"); } updateStatus(ThingStatus.ONLINE); @@ -349,20 +351,17 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler { thingHandler.onReceiveUpdate(shadeData); } - private List fetchScenes() throws JsonParseException, HubProcessingException, HubMaintenanceException { + private List fetchScenes() + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { HDPowerViewWebTargets webTargets = this.webTargets; if (webTargets == null) { throw new ProcessingException("Web targets not initialized"); } Scenes scenes = webTargets.getScenes(); - if (scenes == null) { - throw new JsonParseException("Missing 'scenes' element"); - } - List sceneData = scenes.sceneData; if (sceneData == null) { - throw new JsonParseException("Missing 'scenes.sceneData' element"); + throw new HubInvalidResponseException("Missing 'scenes.sceneData' element"); } logger.debug("Received data for {} scenes", sceneData.size()); @@ -370,7 +369,7 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler { } private List updateSceneChannels() - throws JsonParseException, HubProcessingException, HubMaintenanceException { + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { List scenes = fetchScenes(); if (scenes.size() == sceneCache.size() && sceneCache.containsAll(scenes)) { @@ -445,20 +444,16 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler { } private List fetchSceneCollections() - throws JsonParseException, HubProcessingException, HubMaintenanceException { + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { HDPowerViewWebTargets webTargets = this.webTargets; if (webTargets == null) { throw new ProcessingException("Web targets not initialized"); } SceneCollections sceneCollections = webTargets.getSceneCollections(); - if (sceneCollections == null) { - throw new JsonParseException("Missing 'sceneCollections' element"); - } - List sceneCollectionData = sceneCollections.sceneCollectionData; if (sceneCollectionData == null) { - throw new JsonParseException("Missing 'sceneCollections.sceneCollectionData' element"); + throw new HubInvalidResponseException("Missing 'sceneCollections.sceneCollectionData' element"); } logger.debug("Received data for {} sceneCollections", sceneCollectionData.size()); @@ -466,7 +461,7 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler { } private List updateSceneCollectionChannels() - throws JsonParseException, HubProcessingException, HubMaintenanceException { + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { List sceneCollections = fetchSceneCollections(); if (sceneCollections.size() == sceneCollectionCache.size() @@ -502,20 +497,16 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler { } private List fetchScheduledEvents() - throws JsonParseException, HubProcessingException, HubMaintenanceException { + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { HDPowerViewWebTargets webTargets = this.webTargets; if (webTargets == null) { throw new ProcessingException("Web targets not initialized"); } ScheduledEvents scheduledEvents = webTargets.getScheduledEvents(); - if (scheduledEvents == null) { - throw new JsonParseException("Missing 'scheduledEvents' element"); - } - List scheduledEventData = scheduledEvents.scheduledEventData; if (scheduledEventData == null) { - throw new JsonParseException("Missing 'scheduledEvents.scheduledEventData' element"); + throw new HubInvalidResponseException("Missing 'scheduledEvents.scheduledEventData' element"); } logger.debug("Received data for {} scheduledEvents", scheduledEventData.size()); @@ -524,7 +515,7 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler { private List updateScheduledEventChannels(List scenes, List sceneCollections) - throws JsonParseException, HubProcessingException, HubMaintenanceException { + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { List scheduledEvents = fetchScheduledEvents(); if (scheduledEvents.size() == scheduledEventCache.size() && scheduledEventCache.containsAll(scheduledEvents)) { diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewShadeHandler.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewShadeHandler.java index e5e9f7cee..6b42bf7d0 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewShadeHandler.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewShadeHandler.java @@ -25,17 +25,18 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants; import org.openhab.binding.hdpowerview.internal.HDPowerViewWebTargets; -import org.openhab.binding.hdpowerview.internal.HubMaintenanceException; -import org.openhab.binding.hdpowerview.internal.HubProcessingException; import org.openhab.binding.hdpowerview.internal.api.CoordinateSystem; import org.openhab.binding.hdpowerview.internal.api.Firmware; import org.openhab.binding.hdpowerview.internal.api.ShadePosition; -import org.openhab.binding.hdpowerview.internal.api.responses.Shade; import org.openhab.binding.hdpowerview.internal.api.responses.Shades.ShadeData; import org.openhab.binding.hdpowerview.internal.api.responses.Survey; import org.openhab.binding.hdpowerview.internal.config.HDPowerViewShadeConfiguration; import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase; import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase.Capabilities; +import org.openhab.binding.hdpowerview.internal.exceptions.HubException; +import org.openhab.binding.hdpowerview.internal.exceptions.HubInvalidResponseException; +import org.openhab.binding.hdpowerview.internal.exceptions.HubMaintenanceException; +import org.openhab.binding.hdpowerview.internal.exceptions.HubProcessingException; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.PercentType; @@ -54,8 +55,6 @@ import org.openhab.core.types.UnDefType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.gson.JsonParseException; - /** * Handles commands for an HD PowerView Shade * @@ -171,21 +170,26 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler { } try { handleShadeCommand(channelId, command, webTargets, shadeId); - } catch (JsonParseException e) { - logger.warn("Bridge returned a bad JSON response: {}", e.getMessage()); - } catch (HubProcessingException e) { + } catch (HubInvalidResponseException e) { + Throwable cause = e.getCause(); + if (cause == null) { + logger.warn("Bridge returned a bad JSON response: {}", e.getMessage()); + } else { + logger.warn("Bridge returned a bad JSON response: {} -> {}", e.getMessage(), cause.getMessage()); + } + } catch (HubMaintenanceException e) { + // exceptions are logged in HDPowerViewWebTargets + } catch (HubException e) { // ScheduledFutures will be cancelled by dispose(), naturally causing InterruptedException in invoke() // for any ongoing requests. Logging this would only cause confusion. if (!isDisposing) { logger.warn("Unexpected error: {}", e.getMessage()); } - } catch (HubMaintenanceException e) { - // exceptions are logged in HDPowerViewWebTargets } } private void handleShadeCommand(String channelId, Command command, HDPowerViewWebTargets webTargets, int shadeId) - throws HubProcessingException, HubMaintenanceException { + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { switch (channelId) { case CHANNEL_SHADE_POSITION: if (command instanceof PercentType) { @@ -417,53 +421,36 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler { } private void moveShade(CoordinateSystem coordSys, int newPercent, HDPowerViewWebTargets webTargets, int shadeId) - throws HubProcessingException, HubMaintenanceException { + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { ShadePosition newPosition = null; // (try to) read the positions from the hub - Shade shade = webTargets.getShade(shadeId); - if (shade != null) { - ShadeData shadeData = shade.shade; - if (shadeData != null) { - updateCapabilities(shadeData); - newPosition = shadeData.positions; - } - } + ShadeData shadeData = webTargets.getShade(shadeId); + updateCapabilities(shadeData); + newPosition = shadeData.positions; // if no positions returned, then create a new position if (newPosition == null) { newPosition = new ShadePosition(); } Capabilities capabilities = getCapabilitiesOrDefault(); // set the new position value, and write the positions to the hub - shade = webTargets.moveShade(shadeId, newPosition.setPosition(capabilities, coordSys, newPercent)); - if (shade != null) { - updateShadePositions(shade); - } + shadeData = webTargets.moveShade(shadeId, newPosition.setPosition(capabilities, coordSys, newPercent)); + updateShadePositions(shadeData); } private void stopShade(HDPowerViewWebTargets webTargets, int shadeId) - throws HubProcessingException, HubMaintenanceException { - Shade shade = webTargets.stopShade(shadeId); - if (shade != null) { - updateShadePositions(shade); - } + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { + updateShadePositions(webTargets.stopShade(shadeId)); // Positions in response from stop motion is not updated to to actual positions yet, // so we need to request hard refresh. requestRefreshShadePosition(); } private void calibrateShade(HDPowerViewWebTargets webTargets, int shadeId) - throws HubProcessingException, HubMaintenanceException { - Shade shade = webTargets.calibrateShade(shadeId); - if (shade != null) { - updateShadePositions(shade); - } + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { + updateShadePositions(webTargets.calibrateShade(shadeId)); } - private void updateShadePositions(Shade shade) { - ShadeData shadeData = shade.shade; - if (shadeData == null) { - return; - } + private void updateShadePositions(ShadeData shadeData) { ShadePosition shadePosition = shadeData.positions; if (shadePosition == null) { return; @@ -532,44 +519,46 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler { if (webTargets == null) { throw new HubProcessingException("Web targets not initialized"); } - Shade shade; + ShadeData shadeData; switch (kind) { case POSITION: - shade = webTargets.refreshShadePosition(shadeId); + shadeData = webTargets.refreshShadePosition(shadeId); break; case SURVEY: Survey survey = webTargets.getShadeSurvey(shadeId); - if (survey != null && survey.surveyData != null) { + if (survey.surveyData != null) { logger.debug("Survey response for shade {}: {}", survey.shadeId, survey.toString()); } else { logger.warn("No response from shade {} survey", shadeId); } return; case BATTERY_LEVEL: - shade = webTargets.refreshShadeBatteryLevel(shadeId); + shadeData = webTargets.refreshShadeBatteryLevel(shadeId); break; default: throw new NotSupportedException("Unsupported refresh kind " + kind.toString()); } - if (shade != null) { - ShadeData shadeData = shade.shade; - if (shadeData != null) { - if (Boolean.TRUE.equals(shadeData.timedOut)) { - logger.warn("Shade {} wireless refresh time out", shadeId); - } else if (kind == RefreshKind.POSITION) { - updateShadePositions(shade); - updateHardProperties(shadeData); - } - } + if (Boolean.TRUE.equals(shadeData.timedOut)) { + logger.warn("Shade {} wireless refresh time out", shadeId); + } else if (kind == RefreshKind.POSITION) { + updateShadePositions(shadeData); + updateHardProperties(shadeData); } - } catch (HubProcessingException e) { + } catch (HubInvalidResponseException e) { + Throwable cause = e.getCause(); + if (cause == null) { + logger.warn("Bridge returned a bad JSON response: {}", e.getMessage()); + } else { + logger.warn("Bridge returned a bad JSON response: {} -> {}", e.getMessage(), cause.getMessage()); + } + } catch (HubMaintenanceException e) { + // exceptions are logged in HDPowerViewWebTargets + } catch (HubException e) { // ScheduledFutures will be cancelled by dispose(), naturally causing InterruptedException in invoke() // for any ongoing requests. Logging this would only cause confusion. if (!isDisposing) { logger.warn("Unexpected error: {}", e.getMessage()); } - } catch (HubMaintenanceException e) { - // exceptions are logged in HDPowerViewWebTargets } } } diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/HDPowerViewJUnitTests.java b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/HDPowerViewJUnitTests.java index 8dfbed2f0..229468ecb 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/HDPowerViewJUnitTests.java +++ b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/HDPowerViewJUnitTests.java @@ -26,18 +26,18 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jetty.client.HttpClient; import org.junit.jupiter.api.Test; import org.openhab.binding.hdpowerview.internal.HDPowerViewWebTargets; -import org.openhab.binding.hdpowerview.internal.HubMaintenanceException; -import org.openhab.binding.hdpowerview.internal.HubProcessingException; import org.openhab.binding.hdpowerview.internal.api.ShadePosition; import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections; import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections.SceneCollection; import org.openhab.binding.hdpowerview.internal.api.responses.Scenes; import org.openhab.binding.hdpowerview.internal.api.responses.Scenes.Scene; -import org.openhab.binding.hdpowerview.internal.api.responses.Shade; import org.openhab.binding.hdpowerview.internal.api.responses.Shades; import org.openhab.binding.hdpowerview.internal.api.responses.Shades.ShadeData; import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase; import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase.Capabilities; +import org.openhab.binding.hdpowerview.internal.exceptions.HubException; +import org.openhab.binding.hdpowerview.internal.exceptions.HubMaintenanceException; +import org.openhab.binding.hdpowerview.internal.exceptions.HubProcessingException; import org.openhab.core.library.types.PercentType; import org.openhab.core.types.State; import org.openhab.core.types.UnDefType; @@ -120,30 +120,28 @@ public class HDPowerViewJUnitTests { try { shadesX = webTargets.getShades(); assertNotNull(shadesX); - if (shadesX != null) { - List shadesData = shadesX.shadeData; - assertNotNull(shadesData); + List shadesData = shadesX.shadeData; + assertNotNull(shadesData); - if (shadesData != null) { - assertTrue(!shadesData.isEmpty()); - ShadeData shadeData; - shadeData = shadesData.get(0); - assertNotNull(shadeData); - assertTrue(shadeData.getName().length() > 0); - shadePos = shadeData.positions; - assertNotNull(shadePos); - ShadeData shadeZero = shadesData.get(0); - assertNotNull(shadeZero); - shadeId = shadeZero.id; - assertNotEquals(0, shadeId); + if (shadesData != null) { + assertTrue(!shadesData.isEmpty()); + ShadeData shadeData; + shadeData = shadesData.get(0); + assertNotNull(shadeData); + assertTrue(shadeData.getName().length() > 0); + shadePos = shadeData.positions; + assertNotNull(shadePos); + ShadeData shadeZero = shadesData.get(0); + assertNotNull(shadeZero); + shadeId = shadeZero.id; + assertNotEquals(0, shadeId); - for (ShadeData shadexData : shadesData) { - String shadeName = shadexData.getName(); - assertNotNull(shadeName); - } + for (ShadeData shadexData : shadesData) { + String shadeName = shadexData.getName(); + assertNotNull(shadeName); } } - } catch (JsonParseException | HubProcessingException | HubMaintenanceException e) { + } catch (HubException e) { fail(e.getMessage()); } @@ -153,90 +151,71 @@ public class HDPowerViewJUnitTests { Scenes scenes = webTargets.getScenes(); assertNotNull(scenes); - if (scenes != null) { - List scenesData = scenes.sceneData; - assertNotNull(scenesData); + List scenesData = scenes.sceneData; + assertNotNull(scenesData); - if (scenesData != null) { - assertTrue(!scenesData.isEmpty()); - Scene sceneZero = scenesData.get(0); - assertNotNull(sceneZero); - sceneId = sceneZero.id; - assertTrue(sceneId > 0); + if (scenesData != null) { + assertTrue(!scenesData.isEmpty()); + Scene sceneZero = scenesData.get(0); + assertNotNull(sceneZero); + sceneId = sceneZero.id; + assertTrue(sceneId > 0); - for (Scene scene : scenesData) { - String sceneName = scene.getName(); - assertNotNull(sceneName); - } + for (Scene scene : scenesData) { + String sceneName = scene.getName(); + assertNotNull(sceneName); } } - } catch (JsonParseException | HubProcessingException | HubMaintenanceException e) { + } catch (HubException e) { fail(e.getMessage()); } // ==== refresh a specific shade ==== - Shade shade = null; + ShadeData shadeData = null; try { assertNotEquals(0, shadeId); - shade = webTargets.refreshShadePosition(shadeId); - assertNotNull(shade); - } catch (HubProcessingException | HubMaintenanceException e) { + shadeData = webTargets.refreshShadePosition(shadeId); + } catch (HubException e) { fail(e.getMessage()); } // ==== move a specific shade ==== try { assertNotEquals(0, shadeId); - assertNotNull(shade); - if (shade != null) { - ShadeData shadeData = shade.shade; - assertNotNull(shadeData); - if (shadeData != null) { - ShadePosition positions = shadeData.positions; - assertNotNull(positions); + if (shadeData != null) { + ShadePosition positions = shadeData.positions; + assertNotNull(positions); + Integer capabilitiesValue = shadeData.capabilities; + assertNotNull(capabilitiesValue); - if (positions != null) { - Integer capabilitiesValue = shadeData.capabilities; - assertNotNull(capabilitiesValue); + if (positions != null && capabilitiesValue != null) { + Capabilities capabilities = db.getCapabilities(capabilitiesValue.intValue()); - if (capabilitiesValue != null) { - Capabilities capabilities = db.getCapabilities(capabilitiesValue.intValue()); + State pos = positions.getState(capabilities, PRIMARY_ZERO_IS_CLOSED); + assertEquals(PercentType.class, pos.getClass()); - State pos = positions.getState(capabilities, PRIMARY_ZERO_IS_CLOSED); - assertEquals(PercentType.class, pos.getClass()); + int position = ((PercentType) pos).intValue(); + position = position + ((position <= 10) ? 5 : -5); - int position = ((PercentType) pos).intValue(); - position = position + ((position <= 10) ? 5 : -5); + ShadePosition targetPosition = new ShadePosition().setPosition(capabilities, + PRIMARY_ZERO_IS_CLOSED, position); + assertNotNull(targetPosition); - ShadePosition targetPosition = new ShadePosition().setPosition(capabilities, - PRIMARY_ZERO_IS_CLOSED, position); - assertNotNull(targetPosition); + if (allowShadeMovementCommands) { + webTargets.moveShade(shadeId, targetPosition); - if (allowShadeMovementCommands) { - webTargets.moveShade(shadeId, targetPosition); - - Shade newShade = webTargets.getShade(shadeId); - assertNotNull(newShade); - if (newShade != null) { - ShadeData newData = newShade.shade; - assertNotNull(newData); - if (newData != null) { - ShadePosition actualPosition = newData.positions; - assertNotNull(actualPosition); - if (actualPosition != null) { - assertEquals( - targetPosition.getState(capabilities, PRIMARY_ZERO_IS_CLOSED), - actualPosition.getState(capabilities, PRIMARY_ZERO_IS_CLOSED)); - } - } - } - } + ShadeData newData = webTargets.getShade(shadeId); + ShadePosition actualPosition = newData.positions; + assertNotNull(actualPosition); + if (actualPosition != null) { + assertEquals(targetPosition.getState(capabilities, PRIMARY_ZERO_IS_CLOSED), + actualPosition.getState(capabilities, PRIMARY_ZERO_IS_CLOSED)); } } } } - } catch (HubProcessingException | HubMaintenanceException e) { + } catch (HubException e) { fail(e.getMessage()); } @@ -255,7 +234,7 @@ public class HDPowerViewJUnitTests { try { assertNotNull(sceneId); webTargets.stopShade(shadeId); - } catch (HubProcessingException | HubMaintenanceException e) { + } catch (HubException e) { fail(e.getMessage()); } }