diff --git a/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/api/MyRenaultHttpSession.java b/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/api/MyRenaultHttpSession.java index 98de8383e..ac74fbe5e 100644 --- a/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/api/MyRenaultHttpSession.java +++ b/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/api/MyRenaultHttpSession.java @@ -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; } diff --git a/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/api/exceptions/RenaultAPIGatewayException.java b/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/api/exceptions/RenaultAPIGatewayException.java new file mode 100644 index 000000000..32a59df81 --- /dev/null +++ b/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/api/exceptions/RenaultAPIGatewayException.java @@ -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); + } +} diff --git a/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/handler/RenaultHandler.java b/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/handler/RenaultHandler.java index 5f2420a70..bfc76b719 100644 --- a/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/handler/RenaultHandler.java +++ b/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/handler/RenaultHandler.java @@ -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);