diff --git a/bundles/org.openhab.binding.renault/README.md b/bundles/org.openhab.binding.renault/README.md index e2cc4102f..864c1ff22 100644 --- a/bundles/org.openhab.binding.renault/README.md +++ b/bundles/org.openhab.binding.renault/README.md @@ -61,6 +61,10 @@ The "externaltemperature" only works on a few cars. The "hvactargettemperature" is used by the hvacstatus ON command for pre-conditioning the car. This seams to only allow values 19, 20 and 21 or else the pre-conditioning command will not work. +The Kamereon API Key changes periodically, which causes a communication error. +To fix this error update the API Key in the bindings configuration. +The new key value can hopefully be found in the renault-api project: [KAMEREON_APIKEY value](https://github.com/hacf-fr/renault-api/blob/main/src/renault_api/const.py) or in the openHAB forums. + ## Example @@ -88,9 +92,16 @@ sitemap renaultcar label="Renault Car" { ![Sitemap](doc/sitemap.png) -If you do not have a smart charger and want to limit the charge of the battery you can set up an active 15 minute charge schedule in the MyRenault App. -Then create a Dimmer item "RenaultCar_ChargeLimit" and set it to 80% for example. This rule will change the RenaultCar_ChargingMode to schedule_mode when the limit is reached. -This stops charging after the battery level reaches the charge limit. +If you want to limit the charge of the car battery to less than 100%, this can be done as follows. + + * Set up an active dummy charge schedule in the MyRenault App. + + * Create a Dimmer item "RenaultCar_ChargeLimit" and set it to 80% for example. + + * Add the ChargeRenaultCarLimit rule using the code below. + +The rule will change the RenaultCar_ChargingMode to schedule_mode when the limit is reached. +This stops charging after the battery level goes over the charge limit. ChargeRenaultCarLimit Code @@ -101,31 +112,35 @@ triggers: configuration: itemName: RenaultCar_BatteryLevel type: core.ItemStateUpdateTrigger - - id: "3" + - id: "2" configuration: itemName: RenaultCar_ChargeLimit type: core.ItemStateUpdateTrigger - - id: "4" + - id: "3" configuration: itemName: RenaultCar_PlugStatus type: core.ItemStateUpdateTrigger conditions: [] actions: - inputs: {} - id: "2" + id: "4" configuration: type: application/vnd.openhab.dsl.rule - script: >- + script: > if ( RenaultCar_PlugStatus.state.toString == 'PLUGGED' ) { if ( RenaultCar_BatteryLevel.state as Number >= RenaultCar_ChargeLimit.state as Number ) { - if (RenaultCar_ChargingMode.state.toString == 'ALWAYS_CHARGING' ) { + if (RenaultCar_ChargingMode.state.toString != 'SCHEDULE_MODE' ) { RenaultCar_ChargingMode.sendCommand("SCHEDULE_MODE") } } else { - if (RenaultCar_ChargingMode.state.toString == 'SCHEDULE_MODE' ) { + if (RenaultCar_ChargingMode.state.toString != 'ALWAYS_CHARGING' ) { RenaultCar_ChargingMode.sendCommand("ALWAYS_CHARGING") } } + } else { + if (RenaultCar_ChargingMode.state.toString != 'ALWAYS_CHARGING' ) { + RenaultCar_ChargingMode.sendCommand("ALWAYS_CHARGING") + } } type: script.ScriptAction diff --git a/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/RenaultConfiguration.java b/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/RenaultConfiguration.java index 55e7656e1..f6c90520c 100644 --- a/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/RenaultConfiguration.java +++ b/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/RenaultConfiguration.java @@ -28,4 +28,5 @@ public class RenaultConfiguration { public String vin = ""; public int refreshInterval = 10; public int updateDelay = 30; + public String kamereonApiKey = ""; } diff --git a/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/api/Constants.java b/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/api/Constants.java index 588931d34..bdaf370dd 100644 --- a/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/api/Constants.java +++ b/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/api/Constants.java @@ -26,13 +26,11 @@ public class Constants { private static final String GIGYA_URL_EU = "https://accounts.eu1.gigya.com"; private static final String GIGYA_URL_US = "https://accounts.us1.gigya.com"; - private static final String KAMEREON_APIKEY = "VAX7XYKGfa92yMvXculCkEFyfZbuM7Ss"; private static final String KAMEREON_URL_EU = "https://api-wired-prod-1-euw1.wrd-aws.com"; private static final String KAMEREON_URL_US = "https://api-wired-prod-1-usw2.wrd-aws.com"; private String gigyaApiKey = "gigya-api-key"; private String gigyaRootUrl = "gigya-root-url"; - private String kamereonApiKey = "kamereon-api-key"; private String kamereonRootUrl = "kamereon-root-url"; public Constants(final String locale) { @@ -41,181 +39,150 @@ public class Constants { gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3__3ER_6lFvXEXHTP_faLtq6eEdbKDXd9F5GoKwzRyZq37ZQ-db7mXcLzR1Jtls5sn"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "cs_CZ": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_oRlKr5PCVL_sPWUZdJ8c5NOl5Ej8nIZw7VKG7S9Rg36UkDszFzfHfxCaUAUU5or2"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "da_DK": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_5x-2C8b1R4MJPQXkwTPdIqgBpcw653Dakw_ZaEneQRkTBdg9UW9Qg_5G-tMNrTMc"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "de_DE": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_7PLksOyBRkHv126x5WhHb-5pqC1qFR8pQjxSeLB6nhAnPERTUlwnYoznHSxwX668"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "de_AT": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3__B4KghyeUb0GlpU62ZXKrjSfb7CPzwBS368wioftJUL5qXE0Z_sSy0rX69klXuHy"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "de_CH": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_UyiWZs_1UXYCUqK_1n7l7l44UiI_9N9hqwtREV0-UYA_5X7tOV-VKvnGxPBww4q2"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "en_GB": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_e8d4g4SE_Fo8ahyHwwP7ohLGZ79HKNN2T8NjQqoNnk6Epj6ilyYwKdHUyCw3wuxz"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "en_IE": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_Xn7tuOnT9raLEXuwSI1_sFFZNEJhSD0lv3gxkwFtGI-RY4AgiePBiJ9EODh8d9yo"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "es_ES": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_DyMiOwEaxLcPdBTu63Gv3hlhvLaLbW3ufvjHLeuU8U5bx3zx19t5rEKq7KMwk9f1"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "es_MX": gigyaRootUrl = GIGYA_URL_US; gigyaApiKey = "3_BFzR-2wfhMhUs5OCy3R8U8IiQcHS-81vF8bteSe8eFrboMTjEWzbf4pY1aHQ7cW0"; kamereonRootUrl = KAMEREON_URL_US; - kamereonApiKey = KAMEREON_APIKEY; break; case "fi_FI": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_xSRCLDYhk1SwSeYQLI3DmA8t-etfAfu5un51fws125ANOBZHgh8Lcc4ReWSwaqNY"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "fr_FR": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_4LKbCcMMcvjDm3X89LU4z4mNKYKdl_W0oD9w-Jvih21WqgJKtFZAnb9YdUgWT9_a"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "fr_BE": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_ZK9x38N8pzEvdiG7ojWHeOAAej43APkeJ5Av6VbTkeoOWR4sdkRc-wyF72HzUB8X"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "fr_CH": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_h3LOcrKZ9mTXxMI9clb2R1VGAWPke6jMNqMw4yYLz4N7PGjYyD0hqRgIFAIHusSn"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "fr_LU": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_zt44Wl_wT9mnqn-BHrR19PvXj3wYRPQKLcPbGWawlatFR837KdxSZZStbBTDaqnb"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "hr_HR": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_HcDC5GGZ89NMP1jORLhYNNCcXt7M3thhZ85eGrcQaM2pRwrgrzcIRWEYi_36cFj9"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "hu_HU": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_nGDWrkSGZovhnVFv5hdIxyuuCuJGZfNmlRGp7-5kEn9yb0bfIfJqoDa2opHOd3Mu"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "it_IT": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_js8th3jdmCWV86fKR3SXQWvXGKbHoWFv8NAgRbH7FnIBsi_XvCpN_rtLcI07uNuq"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "it_CH": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_gHkmHaGACxSLKXqD_uDDx415zdTw7w8HXAFyvh0qIP0WxnHPMF2B9K_nREJVSkGq"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "nl_NL": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_ZIOtjqmP0zaHdEnPK7h1xPuBYgtcOyUxbsTY8Gw31Fzy7i7Ltjfm-hhPh23fpHT5"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "nl_BE": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_yachztWczt6i1pIMhLIH9UA6DXK6vXXuCDmcsoA4PYR0g35RvLPDbp49YribFdpC"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "no_NO": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_QrPkEJr69l7rHkdCVls0owC80BB4CGz5xw_b0gBSNdn3pL04wzMBkcwtbeKdl1g9"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "pl_PL": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_2YBjydYRd1shr6bsZdrvA9z7owvSg3W5RHDYDp6AlatXw9hqx7nVoanRn8YGsBN8"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "pt_PT": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3__afxovspi2-Ip1E5kNsAgc4_35lpLAKCF6bq4_xXj2I2bFPjIWxAOAQJlIkreKTD"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "ro_RO": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_WlBp06vVHuHZhiDLIehF8gchqbfegDJADPQ2MtEsrc8dWVuESf2JCITRo5I2CIxs"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "ru_RU": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_N_ecy4iDyoRtX8v5xOxewwZLKXBjRgrEIv85XxI0KJk8AAdYhJIi17LWb086tGXR"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "sk_SK": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_e8d4g4SE_Fo8ahyHwwP7ohLGZ79HKNN2T8NjQqoNnk6Epj6ilyYwKdHUyCw3wuxz"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "sl_SI": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_QKt0ADYxIhgcje4F3fj9oVidHsx3JIIk-GThhdyMMQi8AJR0QoHdA62YArVjbZCt"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; case "sv_SE": gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3_EN5Hcnwanu9_Dqot1v1Aky1YelT5QqG4TxveO0EgKFWZYu03WkeB9FKuKKIWUXIS"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; - break; default: gigyaRootUrl = GIGYA_URL_EU; gigyaApiKey = "3__B4KghyeUb0GlpU62ZXKrjSfb7CPzwBS368wioftJUL5qXE0Z_sSy0rX69klXuHy"; kamereonRootUrl = KAMEREON_URL_EU; - kamereonApiKey = KAMEREON_APIKEY; break; } } @@ -228,10 +195,6 @@ public class Constants { return gigyaRootUrl; } - public String getKamereonApiKey() { - return kamereonApiKey; - } - public String getKamereonRootUrl() { return kamereonRootUrl; } 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 f2539c81f..fa8f0c069 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 @@ -240,7 +240,7 @@ public class MyRenaultHttpSession { + "/kamereon/kca/car-adapter/v1/cars/" + config.vin + "/actions/hvac-start?country=" + getCountry(config)) .method(HttpMethod.POST).header("Content-type", "application/vnd.api+json") - .header("apikey", this.constants.getKamereonApiKey()) + .header("apikey", this.config.kamereonApiKey) .header("x-kamereon-authorization", "Bearer " + kamereonToken).header("x-gigya-id_token", jwt); request.content(new StringContentProvider( "{\"data\":{\"type\":\"HvacStart\",\"attributes\":{\"action\":\"start\",\"targetTemperature\":\"" @@ -274,7 +274,7 @@ public class MyRenaultHttpSession { + "/kamereon/kca/car-adapter/v1/cars/" + config.vin + "/actions/charge-mode?country=" + getCountry(config)) .method(HttpMethod.POST).header("Content-type", "application/vnd.api+json") - .header("apikey", this.constants.getKamereonApiKey()) + .header("apikey", this.config.kamereonApiKey) .header("x-kamereon-authorization", "Bearer " + kamereonToken).header("x-gigya-id_token", jwt); final String apiMode = ChargingMode.SCHEDULE_MODE.equals(mode) ? CHARGING_MODE_SCHEDULE : CHARGING_MODE_ALWAYS; @@ -305,7 +305,7 @@ public class MyRenaultHttpSession { private @Nullable JsonObject getKamereonResponse(String path) throws RenaultForbiddenException, RenaultUpdateException, RenaultNotImplementedException { Request request = httpClient.newRequest(this.constants.getKamereonRootUrl() + path).method(HttpMethod.GET) - .header("Content-type", "application/vnd.api+json").header("apikey", this.constants.getKamereonApiKey()) + .header("Content-type", "application/vnd.api+json").header("apikey", this.config.kamereonApiKey) .header("x-kamereon-authorization", "Bearer " + kamereonToken).header("x-gigya-id_token", jwt); try { ContentResponse response = request.send(); diff --git a/bundles/org.openhab.binding.renault/src/main/resources/OH-INF/i18n/renault.properties b/bundles/org.openhab.binding.renault/src/main/resources/OH-INF/i18n/renault.properties index 7d900722f..9e5b4213c 100644 --- a/bundles/org.openhab.binding.renault/src/main/resources/OH-INF/i18n/renault.properties +++ b/bundles/org.openhab.binding.renault/src/main/resources/OH-INF/i18n/renault.properties @@ -49,6 +49,8 @@ thing-type.config.renault.car.updateDelay.label = Update Delay thing-type.config.renault.car.updateDelay.description = How long to wait for commands to reach car and update to server in seconds. thing-type.config.renault.car.vin.label = VIN thing-type.config.renault.car.vin.description = Vehicle Identification Number +thing-type.config.renault.car.kamereonApiKey.label = Kamereon API Key +thing-type.config.renault.car.kamereonApiKey.description = Access code for MyRenault Services # channel types diff --git a/bundles/org.openhab.binding.renault/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.renault/src/main/resources/OH-INF/thing/thing-types.xml index bede45cbb..04152e6c5 100644 --- a/bundles/org.openhab.binding.renault/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.renault/src/main/resources/OH-INF/thing/thing-types.xml @@ -83,6 +83,11 @@ How long to wait for commands to reach car and update to server in seconds. 30 + + + Access code for MyRenault Services. + VAX7XYKGfa92yMvXculCkEFyfZbuM7Ss +