[renault] Improve handling of HTTP 502 responses. (#14586)

Signed-off-by: Doug Culnane <doug@culnane.net>
This commit is contained in:
Doug Culnane 2023-03-13 07:51:27 +01:00 committed by GitHub
parent 9aa72abd82
commit b3d3d20b8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 29 deletions

View File

@ -26,6 +26,7 @@ import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.util.Fields;
import org.openhab.binding.renault.internal.RenaultConfiguration;
import org.openhab.binding.renault.internal.api.Car.ChargingMode;
import org.openhab.binding.renault.internal.api.exceptions.RenaultAPIGatewayException;
import org.openhab.binding.renault.internal.api.exceptions.RenaultActionException;
import org.openhab.binding.renault.internal.api.exceptions.RenaultException;
import org.openhab.binding.renault.internal.api.exceptions.RenaultForbiddenException;
@ -202,8 +203,8 @@ public class MyRenaultHttpSession {
}
}
public void getVehicle(Car car)
throws RenaultForbiddenException, RenaultUpdateException, RenaultNotImplementedException {
public void getVehicle(Car car) throws RenaultForbiddenException, RenaultUpdateException,
RenaultNotImplementedException, RenaultAPIGatewayException {
JsonObject responseJson = getKamereonResponse("/commerce/v1/accounts/" + kamereonaccountId + "/vehicles/"
+ config.vin + "/details?country=" + getCountry(config));
if (responseJson != null) {
@ -211,8 +212,8 @@ public class MyRenaultHttpSession {
}
}
public void getBatteryStatus(Car car)
throws RenaultForbiddenException, RenaultUpdateException, RenaultNotImplementedException {
public void getBatteryStatus(Car car) throws RenaultForbiddenException, RenaultUpdateException,
RenaultNotImplementedException, RenaultAPIGatewayException {
JsonObject responseJson = getKamereonResponse("/commerce/v1/accounts/" + kamereonaccountId
+ "/kamereon/kca/car-adapter/v2/cars/" + config.vin + "/battery-status?country=" + getCountry(config));
if (responseJson != null) {
@ -220,8 +221,8 @@ public class MyRenaultHttpSession {
}
}
public void getHvacStatus(Car car)
throws RenaultForbiddenException, RenaultUpdateException, RenaultNotImplementedException {
public void getHvacStatus(Car car) throws RenaultForbiddenException, RenaultUpdateException,
RenaultNotImplementedException, RenaultAPIGatewayException {
JsonObject responseJson = getKamereonResponse("/commerce/v1/accounts/" + kamereonaccountId
+ "/kamereon/kca/car-adapter/v1/cars/" + config.vin + "/hvac-status?country=" + getCountry(config));
if (responseJson != null) {
@ -229,8 +230,8 @@ public class MyRenaultHttpSession {
}
}
public void getCockpit(Car car)
throws RenaultForbiddenException, RenaultUpdateException, RenaultNotImplementedException {
public void getCockpit(Car car) throws RenaultForbiddenException, RenaultUpdateException,
RenaultNotImplementedException, RenaultAPIGatewayException {
JsonObject responseJson = getKamereonResponse("/commerce/v1/accounts/" + kamereonaccountId
+ "/kamereon/kca/car-adapter/v2/cars/" + config.vin + "/cockpit?country=" + getCountry(config));
if (responseJson != null) {
@ -238,8 +239,8 @@ public class MyRenaultHttpSession {
}
}
public void getLocation(Car car)
throws RenaultForbiddenException, RenaultUpdateException, RenaultNotImplementedException {
public void getLocation(Car car) throws RenaultForbiddenException, RenaultUpdateException,
RenaultNotImplementedException, RenaultAPIGatewayException {
JsonObject responseJson = getKamereonResponse("/commerce/v1/accounts/" + kamereonaccountId
+ "/kamereon/kca/car-adapter/v1/cars/" + config.vin + "/location?country=" + getCountry(config));
if (responseJson != null) {
@ -247,8 +248,8 @@ public class MyRenaultHttpSession {
}
}
public void getLockStatus(Car car)
throws RenaultForbiddenException, RenaultUpdateException, RenaultNotImplementedException {
public void getLockStatus(Car car) throws RenaultForbiddenException, RenaultUpdateException,
RenaultNotImplementedException, RenaultAPIGatewayException {
JsonObject responseJson = getKamereonResponse("/commerce/v1/accounts/" + kamereonaccountId
+ "/kamereon/kca/car-adapter/v1/cars/" + config.vin + "/lock-status?country=" + getCountry(config));
if (responseJson != null) {
@ -256,8 +257,8 @@ public class MyRenaultHttpSession {
}
}
public void actionHvacOn(double hvacTargetTemperature)
throws RenaultForbiddenException, RenaultNotImplementedException, RenaultActionException {
public void actionHvacOn(double hvacTargetTemperature) throws RenaultForbiddenException,
RenaultNotImplementedException, RenaultActionException, RenaultAPIGatewayException {
final String path = "/commerce/v1/accounts/" + kamereonaccountId + "/kamereon/kca/car-adapter/v1/cars/"
+ config.vin + "/actions/hvac-start?country=" + getCountry(config);
postKamereonRequest(path,
@ -265,8 +266,8 @@ public class MyRenaultHttpSession {
+ hvacTargetTemperature + "\"}}}");
}
public void actionChargeMode(ChargingMode mode)
throws RenaultForbiddenException, RenaultNotImplementedException, RenaultActionException {
public void actionChargeMode(ChargingMode mode) throws RenaultForbiddenException, RenaultNotImplementedException,
RenaultActionException, RenaultAPIGatewayException {
final String apiMode = ChargingMode.SCHEDULE_MODE.equals(mode) ? CHARGING_MODE_SCHEDULE : CHARGING_MODE_ALWAYS;
final String path = "/commerce/v1/accounts/" + kamereonaccountId + "/kamereon/kca/car-adapter/v1/cars/"
+ config.vin + "/actions/charge-mode?country=" + getCountry(config);
@ -274,8 +275,8 @@ public class MyRenaultHttpSession {
"{\"data\":{\"type\":\"ChargeMode\",\"attributes\":{\"action\":\"" + apiMode + "\"}}}");
}
public void actionPause(boolean mode)
throws RenaultForbiddenException, RenaultNotImplementedException, RenaultActionException {
public void actionPause(boolean mode) throws RenaultForbiddenException, RenaultNotImplementedException,
RenaultActionException, RenaultAPIGatewayException {
final String apiMode = mode ? "pause" : "resume";
final String path = "/commerce/v1/accounts/" + kamereonaccountId + "/kamereon/kcm/v1/vehicles/" + config.vin
@ -284,8 +285,8 @@ public class MyRenaultHttpSession {
"{\"data\":{\"type\":\"ChargePauseResume\",\"attributes\":{\"action\":\"" + apiMode + "\"}}}");
}
private void postKamereonRequest(final String path, final String content)
throws RenaultForbiddenException, RenaultNotImplementedException, RenaultActionException {
private void postKamereonRequest(final String path, final String content) throws RenaultForbiddenException,
RenaultNotImplementedException, RenaultActionException, RenaultAPIGatewayException {
Request request = httpClient.newRequest(this.constants.getKamereonRootUrl() + path).method(HttpMethod.POST)
.header("Content-type", "application/vnd.api+json").header("apikey", this.config.kamereonApiKey)
.header("x-kamereon-authorization", "Bearer " + kamereonToken).header("x-gigya-id_token", jwt)
@ -302,8 +303,8 @@ public class MyRenaultHttpSession {
}
}
private @Nullable JsonObject getKamereonResponse(String path)
throws RenaultForbiddenException, RenaultNotImplementedException, RenaultUpdateException {
private @Nullable JsonObject getKamereonResponse(String path) throws RenaultForbiddenException,
RenaultNotImplementedException, RenaultUpdateException, RenaultAPIGatewayException {
Request request = httpClient.newRequest(this.constants.getKamereonRootUrl() + path).method(HttpMethod.GET)
.header("Content-type", "application/vnd.api+json").header("apikey", this.config.kamereonApiKey)
.header("x-kamereon-authorization", "Bearer " + kamereonToken).header("x-gigya-id_token", jwt);
@ -336,7 +337,7 @@ public class MyRenaultHttpSession {
}
private void checkResponse(ContentResponse response)
throws RenaultForbiddenException, RenaultNotImplementedException {
throws RenaultForbiddenException, RenaultNotImplementedException, RenaultAPIGatewayException {
switch (response.getStatus()) {
case HttpStatus.FORBIDDEN_403:
throw new RenaultForbiddenException(
@ -346,7 +347,7 @@ public class MyRenaultHttpSession {
case HttpStatus.NOT_IMPLEMENTED_501:
throw new RenaultNotImplementedException("Kamereon request not implemented");
case HttpStatus.BAD_GATEWAY_502:
throw new RenaultNotImplementedException("Kamereon request failed");
throw new RenaultAPIGatewayException("Kamereon request failed");
default:
break;
}

View File

@ -0,0 +1,31 @@
/**
* Copyright (c) 2010-2023 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.renault.internal.api.exceptions;
import org.eclipse.jdt.annotation.NonNullByDefault;
/**
* Exception thrown while trying to access the My Renault service which
* is unavailable temporarily
*
* @author Doug Culnane - Initial contribution
*/
@NonNullByDefault
public class RenaultAPIGatewayException extends RenaultException {
private static final long serialVersionUID = 1L;
public RenaultAPIGatewayException(String message) {
super(message);
}
}

View File

@ -37,6 +37,7 @@ import org.openhab.binding.renault.internal.RenaultConfiguration;
import org.openhab.binding.renault.internal.api.Car;
import org.openhab.binding.renault.internal.api.Car.ChargingMode;
import org.openhab.binding.renault.internal.api.MyRenaultHttpSession;
import org.openhab.binding.renault.internal.api.exceptions.RenaultAPIGatewayException;
import org.openhab.binding.renault.internal.api.exceptions.RenaultActionException;
import org.openhab.binding.renault.internal.api.exceptions.RenaultException;
import org.openhab.binding.renault.internal.api.exceptions.RenaultForbiddenException;
@ -292,7 +293,7 @@ public class RenaultHandler extends BaseThingHandler {
} catch (RenaultNotImplementedException e) {
logger.warn("Disabling unsupported HVAC status update.");
car.setDisableHvac(true);
} catch (RenaultForbiddenException | RenaultUpdateException e) {
} catch (RenaultForbiddenException | RenaultUpdateException | RenaultAPIGatewayException e) {
logger.warn("Error updating HVAC status.", e);
}
}
@ -315,7 +316,8 @@ public class RenaultHandler extends BaseThingHandler {
} catch (RenaultNotImplementedException e) {
logger.warn("Disabling unsupported location update.");
car.setDisableLocation(true);
} catch (IllegalArgumentException | RenaultForbiddenException | RenaultUpdateException e) {
} catch (IllegalArgumentException | RenaultForbiddenException | RenaultUpdateException
| RenaultAPIGatewayException e) {
logger.warn("Error updating location.", e);
}
}
@ -332,7 +334,7 @@ public class RenaultHandler extends BaseThingHandler {
} catch (RenaultNotImplementedException e) {
logger.warn("Disabling unsupported cockpit status update.");
car.setDisableCockpit(true);
} catch (RenaultForbiddenException | RenaultUpdateException e) {
} catch (RenaultForbiddenException | RenaultUpdateException | RenaultAPIGatewayException e) {
logger.warn("Error updating cockpit status.", e);
}
}
@ -370,7 +372,7 @@ public class RenaultHandler extends BaseThingHandler {
} catch (RenaultNotImplementedException e) {
logger.warn("Disabling unsupported battery update.");
car.setDisableBattery(true);
} catch (RenaultForbiddenException | RenaultUpdateException e) {
} catch (RenaultForbiddenException | RenaultUpdateException | RenaultAPIGatewayException e) {
logger.warn("Error updating battery status.", e);
}
}
@ -391,7 +393,8 @@ public class RenaultHandler extends BaseThingHandler {
updateState(CHANNEL_LOCKED, UnDefType.UNDEF);
break;
}
} catch (RenaultNotImplementedException e) {
} catch (RenaultNotImplementedException | RenaultAPIGatewayException e) {
// If not supported API returns a Bad Gateway for this call.
updateState(CHANNEL_LOCKED, UnDefType.UNDEF);
logger.warn("Disabling unsupported lock status update.");
car.setDisableLockStatus(true);