mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[hdpowerview] Eliminate nightly crash dump in OH3 (#10118)
* [hdpowerview] refactor from jax-rs to http client * [hdpowerview] adopt proposals of code reviewer * [hdpowerview] adopt additional proposals of code reviewer * [hdpowerview] provide exception class name Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
This commit is contained in:
parent
e828baccca
commit
596b261d47
@ -14,14 +14,14 @@ package org.openhab.binding.hdpowerview.internal;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import javax.ws.rs.client.ClientBuilder;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.binding.hdpowerview.internal.discovery.HDPowerViewShadeDiscoveryService;
|
||||
import org.openhab.binding.hdpowerview.internal.handler.HDPowerViewHubHandler;
|
||||
import org.openhab.binding.hdpowerview.internal.handler.HDPowerViewShadeHandler;
|
||||
import org.openhab.core.config.discovery.DiscoveryService;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
@ -41,11 +41,12 @@ import org.osgi.service.component.annotations.Reference;
|
||||
@NonNullByDefault
|
||||
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.hdpowerview")
|
||||
public class HDPowerViewHandlerFactory extends BaseThingHandlerFactory {
|
||||
private final ClientBuilder clientBuilder;
|
||||
|
||||
private final HttpClient httpClient;
|
||||
|
||||
@Activate
|
||||
public HDPowerViewHandlerFactory(@Reference ClientBuilder clientBuilder) {
|
||||
this.clientBuilder = clientBuilder;
|
||||
public HDPowerViewHandlerFactory(@Reference HttpClientFactory httpClientFactory) {
|
||||
this.httpClient = httpClientFactory.getCommonHttpClient();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -58,7 +59,7 @@ public class HDPowerViewHandlerFactory extends BaseThingHandlerFactory {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
if (thingTypeUID.equals(HDPowerViewBindingConstants.THING_TYPE_HUB)) {
|
||||
HDPowerViewHubHandler handler = new HDPowerViewHubHandler((Bridge) thing, clientBuilder);
|
||||
HDPowerViewHubHandler handler = new HDPowerViewHubHandler((Bridge) thing, httpClient);
|
||||
registerService(new HDPowerViewShadeDiscoveryService(handler));
|
||||
return handler;
|
||||
} else if (thingTypeUID.equals(HDPowerViewBindingConstants.THING_TYPE_SHADE)) {
|
||||
|
@ -13,17 +13,18 @@
|
||||
package org.openhab.binding.hdpowerview.internal;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import javax.ws.rs.ProcessingException;
|
||||
import javax.ws.rs.client.Client;
|
||||
import javax.ws.rs.client.Entity;
|
||||
import javax.ws.rs.client.Invocation;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.util.StringContentProvider;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.openhab.binding.hdpowerview.internal.api.ShadePosition;
|
||||
import org.openhab.binding.hdpowerview.internal.api.requests.ShadeMove;
|
||||
import org.openhab.binding.hdpowerview.internal.api.requests.ShadeStop;
|
||||
@ -45,14 +46,6 @@ import com.google.gson.JsonParseException;
|
||||
@NonNullByDefault
|
||||
public class HDPowerViewWebTargets {
|
||||
|
||||
private static final String PUT = "PUT";
|
||||
private static final String GET = "GET";
|
||||
private static final String SCENE_ID = "sceneId";
|
||||
private static final String ID = "id";
|
||||
private static final String REFRESH = "refresh";
|
||||
private static final String CONN_HDR = "Connection";
|
||||
private static final String CONN_VAL = "close"; // versus "keep-alive"
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(HDPowerViewWebTargets.class);
|
||||
|
||||
/*
|
||||
@ -64,128 +57,159 @@ public class HDPowerViewWebTargets {
|
||||
private final int maintenancePeriod = 300;
|
||||
private Instant maintenanceScheduledEnd = Instant.now().minusSeconds(2 * maintenancePeriod);
|
||||
|
||||
private WebTarget base;
|
||||
private WebTarget shades;
|
||||
private WebTarget shade;
|
||||
private WebTarget sceneActivate;
|
||||
private WebTarget scenes;
|
||||
private final String base;
|
||||
private final String shades;
|
||||
private final String sceneActivate;
|
||||
private final String scenes;
|
||||
|
||||
private final Gson gson = new Gson();
|
||||
private final HttpClient httpClient;
|
||||
|
||||
/**
|
||||
* private helper class for passing http url query parameters
|
||||
*/
|
||||
private static class Query {
|
||||
private final String key;
|
||||
private final String value;
|
||||
|
||||
private Query(String key, String value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static Query of(String key, String value) {
|
||||
return new Query(key, value);
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the web targets
|
||||
*
|
||||
* @param client the Javax RS client (the binding)
|
||||
*
|
||||
* @param httpClient the HTTP client (the binding)
|
||||
* @param ipAddress the IP address of the server (the hub)
|
||||
*/
|
||||
public HDPowerViewWebTargets(Client client, String ipAddress) {
|
||||
base = client.target("http://" + ipAddress + "/api");
|
||||
shades = base.path("shades/");
|
||||
shade = base.path("shades/{id}");
|
||||
sceneActivate = base.path("scenes");
|
||||
scenes = base.path("scenes/");
|
||||
public HDPowerViewWebTargets(HttpClient httpClient, String ipAddress) {
|
||||
base = "http://" + ipAddress + "/api/";
|
||||
shades = base + "shades/";
|
||||
sceneActivate = base + "scenes";
|
||||
scenes = base + "scenes/";
|
||||
this.httpClient = httpClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a JSON package that describes all shades in the hub, and wraps it in
|
||||
* a Shades class instance
|
||||
*
|
||||
*
|
||||
* @return Shades class instance
|
||||
* @throws JsonParseException if there is a JSON parsing error
|
||||
* @throws ProcessingException if there is any processing error
|
||||
* @throws HubProcessingException if there is any processing error
|
||||
* @throws HubMaintenanceException if the hub is down for maintenance
|
||||
*/
|
||||
public @Nullable Shades getShades() throws JsonParseException, ProcessingException, HubMaintenanceException {
|
||||
String json = invoke(shades.request().header(CONN_HDR, CONN_VAL).buildGet(), shades, null);
|
||||
public @Nullable Shades getShades() throws JsonParseException, HubProcessingException, HubMaintenanceException {
|
||||
String json = invoke(HttpMethod.GET, shades, null, null);
|
||||
return gson.fromJson(json, Shades.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs the hub to move a specific shade
|
||||
*
|
||||
*
|
||||
* @param shadeId id of the shade to be moved
|
||||
* @param position instance of ShadePosition containing the new position
|
||||
* @throws ProcessingException if there is any processing error
|
||||
* @throws HubProcessingException if there is any processing error
|
||||
* @throws HubMaintenanceException if the hub is down for maintenance
|
||||
*/
|
||||
public void moveShade(int shadeId, ShadePosition position) throws ProcessingException, HubMaintenanceException {
|
||||
WebTarget target = shade.resolveTemplate(ID, shadeId);
|
||||
public void moveShade(int shadeId, ShadePosition position) throws HubProcessingException, HubMaintenanceException {
|
||||
String json = gson.toJson(new ShadeMove(shadeId, position));
|
||||
invoke(target.request().header(CONN_HDR, CONN_VAL)
|
||||
.buildPut(Entity.entity(json, MediaType.APPLICATION_JSON_TYPE)), target, json);
|
||||
return;
|
||||
invoke(HttpMethod.PUT, shades + Integer.toString(shadeId), null, json);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a JSON package that describes all scenes in the hub, and wraps it in
|
||||
* a Scenes class instance
|
||||
*
|
||||
*
|
||||
* @return Scenes class instance
|
||||
* @throws JsonParseException if there is a JSON parsing error
|
||||
* @throws ProcessingException if there is any processing error
|
||||
* @throws HubProcessingException if there is any processing error
|
||||
* @throws HubMaintenanceException if the hub is down for maintenance
|
||||
*/
|
||||
public @Nullable Scenes getScenes() throws JsonParseException, ProcessingException, HubMaintenanceException {
|
||||
String json = invoke(scenes.request().header(CONN_HDR, CONN_VAL).buildGet(), scenes, null);
|
||||
public @Nullable Scenes getScenes() throws JsonParseException, HubProcessingException, HubMaintenanceException {
|
||||
String json = invoke(HttpMethod.GET, scenes, null, null);
|
||||
return gson.fromJson(json, Scenes.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs the hub to execute a specific scene
|
||||
*
|
||||
*
|
||||
* @param sceneId id of the scene to be executed
|
||||
* @throws ProcessingException if there is any processing error
|
||||
* @throws HubProcessingException if there is any processing error
|
||||
* @throws HubMaintenanceException if the hub is down for maintenance
|
||||
*/
|
||||
public void activateScene(int sceneId) throws ProcessingException, HubMaintenanceException {
|
||||
WebTarget target = sceneActivate.queryParam(SCENE_ID, sceneId);
|
||||
invoke(target.request().header(CONN_HDR, CONN_VAL).buildGet(), target, null);
|
||||
public void activateScene(int sceneId) throws HubProcessingException, HubMaintenanceException {
|
||||
invoke(HttpMethod.GET, sceneActivate, Query.of("sceneId", Integer.toString(sceneId)), null);
|
||||
}
|
||||
|
||||
private synchronized String invoke(Invocation invocation, WebTarget target, @Nullable String jsonCommand)
|
||||
throws ProcessingException, HubMaintenanceException {
|
||||
/**
|
||||
* Invoke a call on the hub server to retrieve information or send a command
|
||||
*
|
||||
* @param method GET or PUT
|
||||
* @param url the host url to be called
|
||||
* @param query the http query parameter
|
||||
* @param jsonCommand the request command content (as a json string)
|
||||
* @return the response content (as a json string)
|
||||
* @throws HubProcessingException
|
||||
* @throws HubMaintenanceException
|
||||
* @throws HubProcessingException
|
||||
*/
|
||||
private synchronized String invoke(HttpMethod method, String url, @Nullable Query query,
|
||||
@Nullable String jsonCommand) throws HubMaintenanceException, HubProcessingException {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("API command {} {}", jsonCommand == null ? GET : PUT, target.getUri());
|
||||
logger.trace("API command {} {}", method, url);
|
||||
if (jsonCommand != null) {
|
||||
logger.trace("JSON command = {}", jsonCommand);
|
||||
}
|
||||
}
|
||||
Response response;
|
||||
Request request = httpClient.newRequest(url).method(method).header("Connection", "close").accept("*/*");
|
||||
if (query != null) {
|
||||
request.param(query.getKey(), query.getValue());
|
||||
}
|
||||
if (jsonCommand != null) {
|
||||
request.header(HttpHeader.CONTENT_TYPE, "application/json").content(new StringContentProvider(jsonCommand));
|
||||
}
|
||||
ContentResponse response;
|
||||
try {
|
||||
response = invocation.invoke();
|
||||
} catch (ProcessingException e) {
|
||||
response = request.send();
|
||||
} catch (InterruptedException | TimeoutException | ExecutionException e) {
|
||||
if (Instant.now().isBefore(maintenanceScheduledEnd)) {
|
||||
// throw "softer" exception during maintenance window
|
||||
logger.debug("Hub still undergoing maintenance");
|
||||
throw new HubMaintenanceException("Hub still undergoing maintenance");
|
||||
}
|
||||
throw e;
|
||||
throw new HubProcessingException(String.format("%s: \"%s\"", e.getClass().getName(), e.getMessage()));
|
||||
}
|
||||
int statusCode = response.getStatus();
|
||||
if (statusCode == 423) {
|
||||
if (statusCode == HttpStatus.LOCKED_423) {
|
||||
// set end of maintenance window, and throw a "softer" exception
|
||||
maintenanceScheduledEnd = Instant.now().plusSeconds(maintenancePeriod);
|
||||
logger.debug("Hub undergoing maintenance");
|
||||
if (response.hasEntity()) {
|
||||
response.readEntity(String.class);
|
||||
}
|
||||
response.close();
|
||||
throw new HubMaintenanceException("Hub undergoing maintenance");
|
||||
}
|
||||
if (statusCode != 200) {
|
||||
logger.warn("Hub returned HTTP error '{}'", statusCode);
|
||||
if (response.hasEntity()) {
|
||||
response.readEntity(String.class);
|
||||
}
|
||||
response.close();
|
||||
throw new ProcessingException(String.format("HTTP %d error", statusCode));
|
||||
if (statusCode != HttpStatus.OK_200) {
|
||||
logger.warn("Hub returned HTTP {} {}", statusCode, response.getReason());
|
||||
throw new HubProcessingException(String.format("HTTP %d error", statusCode));
|
||||
}
|
||||
if (!response.hasEntity()) {
|
||||
String jsonResponse = response.getContentAsString();
|
||||
if ("".equals(jsonResponse)) {
|
||||
logger.warn("Hub returned no content");
|
||||
response.close();
|
||||
throw new ProcessingException("Missing response entity");
|
||||
throw new HubProcessingException("Missing response entity");
|
||||
}
|
||||
String jsonResponse = response.readEntity(String.class);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("JSON response = {}", jsonResponse);
|
||||
}
|
||||
@ -195,15 +219,16 @@ public class HDPowerViewWebTargets {
|
||||
/**
|
||||
* Fetches a JSON package that describes a specific shade in the hub, and wraps it
|
||||
* in a Shade class instance
|
||||
*
|
||||
*
|
||||
* @param shadeId id of the shade to be fetched
|
||||
* @return Shade class instance
|
||||
* @throws ProcessingException if there is any processing error
|
||||
* @throws JsonParseException if there is a JSON parsing error
|
||||
* @throws HubProcessingException if there is any processing error
|
||||
* @throws HubMaintenanceException if the hub is down for maintenance
|
||||
*/
|
||||
public @Nullable Shade getShade(int shadeId) throws ProcessingException, HubMaintenanceException {
|
||||
WebTarget target = shade.resolveTemplate(ID, shadeId);
|
||||
String json = invoke(target.request().header(CONN_HDR, CONN_VAL).buildGet(), target, null);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -211,30 +236,29 @@ public class HDPowerViewWebTargets {
|
||||
* Instructs the hub to do a hard refresh (discovery on the hubs RF network) on
|
||||
* a specific shade; fetches a JSON package that describes that shade, and wraps
|
||||
* it in a Shade class instance
|
||||
*
|
||||
*
|
||||
* @param shadeId id of the shade to be refreshed
|
||||
* @return Shade class instance
|
||||
* @throws ProcessingException if there is any processing error
|
||||
* @throws JsonParseException if there is a JSON parsing error
|
||||
* @throws HubProcessingException if there is any processing error
|
||||
* @throws HubMaintenanceException if the hub is down for maintenance
|
||||
*/
|
||||
public @Nullable Shade refreshShade(int shadeId) throws ProcessingException, HubMaintenanceException {
|
||||
WebTarget target = shade.resolveTemplate(ID, shadeId).queryParam(REFRESH, true);
|
||||
String json = invoke(target.request().header(CONN_HDR, CONN_VAL).buildGet(), target, null);
|
||||
public @Nullable Shade refreshShade(int shadeId)
|
||||
throws JsonParseException, HubProcessingException, HubMaintenanceException {
|
||||
String json = invoke(HttpMethod.GET, shades + Integer.toString(shadeId),
|
||||
Query.of("refresh", Boolean.toString(true)), null);
|
||||
return gson.fromJson(json, Shade.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells the hub to stop movement of a specific shade
|
||||
*
|
||||
*
|
||||
* @param shadeId id of the shade to be stopped
|
||||
* @throws ProcessingException if there is any processing error
|
||||
* @throws HubProcessingException if there is any processing error
|
||||
* @throws HubMaintenanceException if the hub is down for maintenance
|
||||
*/
|
||||
public void stopShade(int shadeId) throws ProcessingException, HubMaintenanceException {
|
||||
WebTarget target = shade.resolveTemplate(ID, shadeId);
|
||||
public void stopShade(int shadeId) throws HubProcessingException, HubMaintenanceException {
|
||||
String json = gson.toJson(new ShadeStop(shadeId));
|
||||
invoke(target.request().header(CONN_HDR, CONN_VAL)
|
||||
.buildPut(Entity.entity(json, MediaType.APPLICATION_JSON_TYPE)), target, json);
|
||||
return;
|
||||
invoke(HttpMethod.PUT, shades + Integer.toString(shadeId), null, json);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2021 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;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link HubProcessingException} is a custom exception for the HD PowerView hub
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HubProcessingException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 4307088023775166450L;
|
||||
|
||||
public HubProcessingException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
@ -17,13 +17,12 @@ import java.util.List;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.ws.rs.ProcessingException;
|
||||
|
||||
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;
|
||||
@ -85,7 +84,7 @@ public class HDPowerViewShadeDiscoveryService extends AbstractDiscoveryService {
|
||||
try {
|
||||
HDPowerViewWebTargets webTargets = hub.getWebTargets();
|
||||
if (webTargets == null) {
|
||||
throw new ProcessingException("Web targets not initialized");
|
||||
throw new HubProcessingException("Web targets not initialized");
|
||||
}
|
||||
Shades shades = webTargets.getShades();
|
||||
if (shades != null && shades.shadeData != null) {
|
||||
@ -107,7 +106,7 @@ public class HDPowerViewShadeDiscoveryService extends AbstractDiscoveryService {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ProcessingException | JsonParseException e) {
|
||||
} catch (HubProcessingException | JsonParseException e) {
|
||||
logger.warn("Unexpected error: {}", e.getMessage());
|
||||
} catch (HubMaintenanceException e) {
|
||||
// exceptions are logged in HDPowerViewWebTargets
|
||||
|
@ -21,13 +21,14 @@ import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.ws.rs.ProcessingException;
|
||||
import javax.ws.rs.client.ClientBuilder;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
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.Scenes;
|
||||
import org.openhab.binding.hdpowerview.internal.api.responses.Scenes.Scene;
|
||||
import org.openhab.binding.hdpowerview.internal.api.responses.Shades;
|
||||
@ -63,7 +64,7 @@ import com.google.gson.JsonParseException;
|
||||
public class HDPowerViewHubHandler extends BaseBridgeHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(HDPowerViewHubHandler.class);
|
||||
private final ClientBuilder clientBuilder;
|
||||
private final HttpClient httpClient;
|
||||
|
||||
private long refreshInterval;
|
||||
private long hardRefreshInterval;
|
||||
@ -75,9 +76,9 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler {
|
||||
private final ChannelTypeUID sceneChannelTypeUID = new ChannelTypeUID(HDPowerViewBindingConstants.BINDING_ID,
|
||||
HDPowerViewBindingConstants.CHANNELTYPE_SCENE_ACTIVATE);
|
||||
|
||||
public HDPowerViewHubHandler(Bridge bridge, ClientBuilder clientBuilder) {
|
||||
public HDPowerViewHubHandler(Bridge bridge, HttpClient httpClient) {
|
||||
super(bridge);
|
||||
this.clientBuilder = clientBuilder;
|
||||
this.httpClient = httpClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -98,7 +99,7 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler {
|
||||
webTargets.activateScene(Integer.parseInt(channelUID.getId()));
|
||||
} catch (HubMaintenanceException e) {
|
||||
// exceptions are logged in HDPowerViewWebTargets
|
||||
} catch (NumberFormatException | ProcessingException e) {
|
||||
} catch (NumberFormatException | HubProcessingException e) {
|
||||
logger.debug("Unexpected error {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
@ -116,7 +117,7 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
webTargets = new HDPowerViewWebTargets(clientBuilder.build(), host);
|
||||
webTargets = new HDPowerViewWebTargets(httpClient, host);
|
||||
refreshInterval = config.refresh;
|
||||
hardRefreshInterval = config.hardRefresh;
|
||||
schedulePoll();
|
||||
@ -178,7 +179,7 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler {
|
||||
pollScenes();
|
||||
} catch (JsonParseException e) {
|
||||
logger.warn("Bridge returned a bad JSON response: {}", e.getMessage());
|
||||
} catch (ProcessingException e) {
|
||||
} catch (HubProcessingException e) {
|
||||
logger.warn("Error connecting to bridge: {}", e.getMessage());
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, e.getMessage());
|
||||
} catch (HubMaintenanceException e) {
|
||||
@ -186,7 +187,7 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private void pollShades() throws JsonParseException, ProcessingException, HubMaintenanceException {
|
||||
private void pollShades() throws JsonParseException, HubProcessingException, HubMaintenanceException {
|
||||
HDPowerViewWebTargets webTargets = this.webTargets;
|
||||
if (webTargets == null) {
|
||||
throw new ProcessingException("Web targets not initialized");
|
||||
@ -229,7 +230,7 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler {
|
||||
thingHandler.onReceiveUpdate(shadeData);
|
||||
}
|
||||
|
||||
private void pollScenes() throws JsonParseException, ProcessingException, HubMaintenanceException {
|
||||
private void pollScenes() throws JsonParseException, HubProcessingException, HubMaintenanceException {
|
||||
HDPowerViewWebTargets webTargets = this.webTargets;
|
||||
if (webTargets == null) {
|
||||
throw new ProcessingException("Web targets not initialized");
|
||||
|
@ -19,12 +19,11 @@ import static org.openhab.binding.hdpowerview.internal.api.CoordinateSystem.*;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.ws.rs.ProcessingException;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
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.ActuatorClass;
|
||||
import org.openhab.binding.hdpowerview.internal.api.CoordinateSystem;
|
||||
import org.openhab.binding.hdpowerview.internal.api.ShadePosition;
|
||||
@ -128,7 +127,7 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
|
||||
|
||||
/**
|
||||
* Update the state of the channels based on the ShadeData provided
|
||||
*
|
||||
*
|
||||
* @param shadeData the ShadeData to be used; may be null
|
||||
*/
|
||||
protected void onReceiveUpdate(@Nullable ShadeData shadeData) {
|
||||
@ -157,11 +156,11 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
|
||||
try {
|
||||
HDPowerViewHubHandler bridge;
|
||||
if ((bridge = getBridgeHandler()) == null) {
|
||||
throw new ProcessingException("Missing bridge handler");
|
||||
throw new HubProcessingException("Missing bridge handler");
|
||||
}
|
||||
HDPowerViewWebTargets webTargets = bridge.getWebTargets();
|
||||
if (webTargets == null) {
|
||||
throw new ProcessingException("Web targets not initialized");
|
||||
throw new HubProcessingException("Web targets not initialized");
|
||||
}
|
||||
int shadeId = getShadeId();
|
||||
|
||||
@ -190,7 +189,7 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
|
||||
webTargets.moveShade(shadeId,
|
||||
ShadePosition.create(ZERO_IS_CLOSED, primaryPercent, ZERO_IS_OPEN, newPercent));
|
||||
}
|
||||
} catch (ProcessingException | NumberFormatException e) {
|
||||
} catch (HubProcessingException | NumberFormatException e) {
|
||||
logger.warn("Unexpected error: {}", e.getMessage());
|
||||
return;
|
||||
} catch (HubMaintenanceException e) {
|
||||
@ -211,16 +210,16 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
|
||||
try {
|
||||
HDPowerViewHubHandler bridge;
|
||||
if ((bridge = getBridgeHandler()) == null) {
|
||||
throw new ProcessingException("Missing bridge handler");
|
||||
throw new HubProcessingException("Missing bridge handler");
|
||||
}
|
||||
HDPowerViewWebTargets webTargets = bridge.getWebTargets();
|
||||
if (webTargets == null) {
|
||||
throw new ProcessingException("Web targets not initialized");
|
||||
throw new HubProcessingException("Web targets not initialized");
|
||||
}
|
||||
int shadeId = getShadeId();
|
||||
webTargets.stopShade(shadeId);
|
||||
requestRefreshShade();
|
||||
} catch (ProcessingException | NumberFormatException e) {
|
||||
} catch (HubProcessingException | NumberFormatException e) {
|
||||
logger.warn("Unexpected error: {}", e.getMessage());
|
||||
return;
|
||||
} catch (HubMaintenanceException e) {
|
||||
@ -242,11 +241,11 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
|
||||
try {
|
||||
HDPowerViewHubHandler bridge;
|
||||
if ((bridge = getBridgeHandler()) == null) {
|
||||
throw new ProcessingException("Missing bridge handler");
|
||||
throw new HubProcessingException("Missing bridge handler");
|
||||
}
|
||||
HDPowerViewWebTargets webTargets = bridge.getWebTargets();
|
||||
if (webTargets == null) {
|
||||
throw new ProcessingException("Web targets not initialized");
|
||||
throw new HubProcessingException("Web targets not initialized");
|
||||
}
|
||||
int shadeId = getShadeId();
|
||||
Shade shade = webTargets.refreshShade(shadeId);
|
||||
@ -258,7 +257,7 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ProcessingException | NumberFormatException e) {
|
||||
} catch (HubProcessingException | NumberFormatException e) {
|
||||
logger.warn("Unexpected error: {}", e.getMessage());
|
||||
} catch (HubMaintenanceException e) {
|
||||
// exceptions are logged in HDPowerViewWebTargets
|
||||
|
@ -22,15 +22,13 @@ import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.ws.rs.ProcessingException;
|
||||
import javax.ws.rs.client.Client;
|
||||
import javax.ws.rs.client.ClientBuilder;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
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.CoordinateSystem;
|
||||
import org.openhab.binding.hdpowerview.internal.api.ShadePosition;
|
||||
import org.openhab.binding.hdpowerview.internal.api.responses.Scenes;
|
||||
@ -76,7 +74,7 @@ public class HDPowerViewJUnitTests {
|
||||
|
||||
/**
|
||||
* Run a series of ONLINE tests on the communication with a hub
|
||||
*
|
||||
*
|
||||
* @param hubIPAddress must be a valid hub IP address to run the
|
||||
* tests on; or an INVALID IP address to
|
||||
* suppress the tests
|
||||
@ -99,10 +97,18 @@ public class HDPowerViewJUnitTests {
|
||||
boolean allowShadeMovementCommands = false;
|
||||
|
||||
if (VALID_IP_V4_ADDRESS.matcher(hubIPAddress).matches()) {
|
||||
// initialize stuff
|
||||
Client client = ClientBuilder.newClient();
|
||||
// ==== initialize stuff ====
|
||||
HttpClient client = new HttpClient();
|
||||
assertNotNull(client);
|
||||
// client.register(new Logger());
|
||||
|
||||
// ==== start the client ====
|
||||
try {
|
||||
client.start();
|
||||
assertTrue(client.isStarted());
|
||||
} catch (Exception e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
|
||||
HDPowerViewWebTargets webTargets = new HDPowerViewWebTargets(client, hubIPAddress);
|
||||
assertNotNull(webTargets);
|
||||
|
||||
@ -180,7 +186,7 @@ public class HDPowerViewJUnitTests {
|
||||
String shadeName = shadexData.getName();
|
||||
assertNotNull(shadeName);
|
||||
}
|
||||
} catch (JsonParseException | ProcessingException | HubMaintenanceException e) {
|
||||
} catch (JsonParseException | HubProcessingException | HubMaintenanceException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
|
||||
@ -203,7 +209,7 @@ public class HDPowerViewJUnitTests {
|
||||
String sceneName = scene.getName();
|
||||
assertNotNull(sceneName);
|
||||
}
|
||||
} catch (JsonParseException | ProcessingException | HubMaintenanceException e) {
|
||||
} catch (JsonParseException | HubProcessingException | HubMaintenanceException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
|
||||
@ -214,7 +220,7 @@ public class HDPowerViewJUnitTests {
|
||||
assertNotEquals(0, shadeId);
|
||||
shade = webTargets.refreshShade(shadeId);
|
||||
assertNotNull(shade);
|
||||
} catch (ProcessingException | HubMaintenanceException e) {
|
||||
} catch (HubProcessingException | HubMaintenanceException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
|
||||
@ -245,7 +251,7 @@ public class HDPowerViewJUnitTests {
|
||||
if (allowShadeMovementCommands) {
|
||||
webTargets.moveShade(shadeId, newPos);
|
||||
}
|
||||
} catch (ProcessingException | HubMaintenanceException e) {
|
||||
} catch (HubProcessingException | HubMaintenanceException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
|
||||
@ -254,7 +260,26 @@ public class HDPowerViewJUnitTests {
|
||||
try {
|
||||
assertNotNull(sceneId);
|
||||
webTargets.activateScene(sceneId);
|
||||
} catch (ProcessingException | HubMaintenanceException e) {
|
||||
} catch (HubProcessingException | HubMaintenanceException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// ==== test stop command ====
|
||||
if (allowShadeMovementCommands) {
|
||||
try {
|
||||
assertNotNull(sceneId);
|
||||
webTargets.stopShade(shadeId);
|
||||
} catch (HubProcessingException | HubMaintenanceException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// ==== stop the client ====
|
||||
if (client.isRunning()) {
|
||||
try {
|
||||
client.stop();
|
||||
} catch (Exception e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user