[hdpowerview] Refactor exception handling (#12049)

* Refactor exception handling.

Fixes #12048

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
This commit is contained in:
Jacob Laursen 2022-01-15 19:16:09 +01:00 committed by GitHub
parent ddfab66849
commit fee45a5b94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 414 additions and 263 deletions

View File

@ -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> 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<Scene> 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<SceneCollection> 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<ScheduledEvent> 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);
}
}

View File

@ -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);
}
}

View File

@ -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> 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> surveyData = this.surveyData;

View File

@ -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<ShadeData> 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();
};

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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<ShadeData> 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<Scene> fetchScenes() throws JsonParseException, HubProcessingException, HubMaintenanceException {
private List<Scene> 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<Scene> 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<Scene> updateSceneChannels()
throws JsonParseException, HubProcessingException, HubMaintenanceException {
throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException {
List<Scene> scenes = fetchScenes();
if (scenes.size() == sceneCache.size() && sceneCache.containsAll(scenes)) {
@ -445,20 +444,16 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler {
}
private List<SceneCollection> 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<SceneCollection> 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<SceneCollection> updateSceneCollectionChannels()
throws JsonParseException, HubProcessingException, HubMaintenanceException {
throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException {
List<SceneCollection> sceneCollections = fetchSceneCollections();
if (sceneCollections.size() == sceneCollectionCache.size()
@ -502,20 +497,16 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler {
}
private List<ScheduledEvent> 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<ScheduledEvent> 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<ScheduledEvent> updateScheduledEventChannels(List<Scene> scenes,
List<SceneCollection> sceneCollections)
throws JsonParseException, HubProcessingException, HubMaintenanceException {
throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException {
List<ScheduledEvent> scheduledEvents = fetchScheduledEvents();
if (scheduledEvents.size() == scheduledEventCache.size() && scheduledEventCache.containsAll(scheduledEvents)) {

View File

@ -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
}
}
}

View File

@ -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<ShadeData> shadesData = shadesX.shadeData;
assertNotNull(shadesData);
List<ShadeData> 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<Scene> scenesData = scenes.sceneData;
assertNotNull(scenesData);
List<Scene> 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());
}
}