]> git.basschouten.com Git - openhab-addons.git/commitdiff
[renault] Add channel for pausing/resuming charging (#14527)
authorfifipil909 <36625767+fifipil909@users.noreply.github.com>
Fri, 10 Mar 2023 22:32:24 +0000 (23:32 +0100)
committerGitHub <noreply@github.com>
Fri, 10 Mar 2023 22:32:24 +0000 (23:32 +0100)
* Adding Pause-Resume Endpoint

Signed-off-by: fifipil909 <vincent.pilate@gmail.com>
bundles/org.openhab.binding.renault/README.md
bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/RenaultBindingConstants.java
bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/api/Car.java
bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/api/MyRenaultHttpSession.java
bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/handler/RenaultHandler.java
bundles/org.openhab.binding.renault/src/main/resources/OH-INF/i18n/renault.properties
bundles/org.openhab.binding.renault/src/main/resources/OH-INF/thing/thing-types.xml

index 0f4eb18adc76fd571c49988edfa5fb612b9a199c..66352f2737752d67ffd1e4088f5feb1d6c603543 100644 (file)
@@ -37,6 +37,7 @@ You require your MyRenault credential, locale and VIN for your MyRenault registe
 | batterylevel           | Number             | State of the battery in %                       | Yes       |
 | batterystatusupdated   | DateTime           | Timestamp of the last battery status update     | Yes       |
 | chargingmode           | String             | Charging mode. always_charging or schedule_mode | No        |
+| pause                  | Switch             | Pause the charge.                               | No        |
 | chargingstatus         | String             | Charging status                                 | Yes       |
 | chargingremainingtime  | Number:Time        | Charging time remaining                         | Yes       |
 | plugstatus             | String             | Status of charging plug                         | Yes       |
@@ -59,6 +60,9 @@ 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 'pause' and 'chargingmode' may not work on some cars. 
+As an example, 'chargingmode' does not work on Dacia Spring cars.
+
 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.
@@ -77,6 +81,7 @@ sitemap renaultcar label="Renault Car" {
         Default icon="poweroutlet" item=RenaultCar_PlugStatus
         Default icon="switch" item=RenaultCar_ChargingStatus
         Selection icon="switch" item=RenaultCar_ChargingMode mappings=[SCHEDULE_MODE="Schedule mode",ALWAYS_CHARGING="Instant charge"]
+        Default icon="switch" item=RenaultCar_Pause
         Default item=RenaultCar_ChargingTimeRemaining
         Default icon="pressure" item=RenaultCar_EstimatedRange
         Default icon="pressure" item=RenaultCar_Odometer
index 3333eaee404196145d244728b8f513d182b9b2f9..a887217983dedf602ea9d166e7f4828d403220da 100644 (file)
@@ -34,6 +34,7 @@ public class RenaultBindingConstants {
     public static final String CHANNEL_BATTERY_LEVEL = "batterylevel";
     public static final String CHANNEL_BATTERY_STATUS_UPDATED = "batterystatusupdated";
     public static final String CHANNEL_CHARGING_MODE = "chargingmode";
+    public static final String CHANNEL_PAUSE = "pause";
     public static final String CHANNEL_CHARGING_STATUS = "chargingstatus";
     public static final String CHANNEL_CHARGING_REMAINING_TIME = "chargingremainingtime";
     public static final String CHANNEL_ESTIMATED_RANGE = "estimatedrange";
index e712ea3ef89e14f0c53c9bc845ae36ce0bccc172..0d08fa13aac1b4cc8a1ce8ca5db85b4812378d4c 100644 (file)
@@ -45,6 +45,7 @@ public class Car {
     private boolean disableHvac = false;
     private boolean disableLockStatus = false;
 
+    private boolean pausemode = false;
     private ChargingStatus chargingStatus = ChargingStatus.UNKNOWN;
     private ChargingMode chargingMode = ChargingMode.UNKNOWN;
     private PlugStatus plugStatus = PlugStatus.UNKNOWN;
@@ -298,6 +299,10 @@ public class Car {
         return chargingMode;
     }
 
+    public boolean getPauseMode() {
+        return pausemode;
+    }
+
     public @Nullable Integer getChargingRemainingTime() {
         return chargingRemainingTime;
     }
@@ -346,6 +351,10 @@ public class Car {
         }
     }
 
+    public void setPauseMode(boolean pausemode) {
+        this.pausemode = pausemode;
+    }
+
     private @Nullable JsonObject getAttributes(JsonObject responseJson)
             throws IllegalStateException, ClassCastException {
         if (responseJson.get("data") != null && responseJson.get("data").getAsJsonObject().get("attributes") != null) {
index 8d31d3b26e542f3035b04895da88eb0c6b411b05..98de8383e78f0778ebe364762c4bcf50c21eb9bf 100644 (file)
@@ -274,6 +274,16 @@ public class MyRenaultHttpSession {
                 "{\"data\":{\"type\":\"ChargeMode\",\"attributes\":{\"action\":\"" + apiMode + "\"}}}");
     }
 
+    public void actionPause(boolean mode)
+            throws RenaultForbiddenException, RenaultNotImplementedException, RenaultActionException {
+
+        final String apiMode = mode ? "pause" : "resume";
+        final String path = "/commerce/v1/accounts/" + kamereonaccountId + "/kamereon/kcm/v1/vehicles/" + config.vin
+                + "/charge/pause-resume?country=" + getCountry(config);
+        postKamereonRequest(path,
+                "{\"data\":{\"type\":\"ChargePauseResume\",\"attributes\":{\"action\":\"" + apiMode + "\"}}}");
+    }
+
     private void postKamereonRequest(final String path, final String content)
             throws RenaultForbiddenException, RenaultNotImplementedException, RenaultActionException {
         Request request = httpClient.newRequest(this.constants.getKamereonRootUrl() + path).method(HttpMethod.POST)
index 7484c173feb34189412a8f88fa8c9a89cafd4463..5f2420a70bd22a1eb7dcfe923d0b907a5d25778e 100644 (file)
@@ -205,6 +205,32 @@ public class RenaultHandler extends BaseThingHandler {
                     }
                 }
                 break;
+            case RenaultBindingConstants.CHANNEL_PAUSE:
+                if (command instanceof RefreshType) {
+                    reschedulePollingJob();
+                } else if (command instanceof OnOffType) {
+                    try {
+                        MyRenaultHttpSession httpSession = new MyRenaultHttpSession(this.config, httpClient);
+                        try {
+                            boolean pause = OnOffType.ON == command;
+                            httpSession.initSesssion(car);
+                            httpSession.actionPause(pause);
+                            car.setPauseMode(pause);
+                            updateState(CHANNEL_PAUSE, OnOffType.from(command.toString()));
+                        } catch (InterruptedException e) {
+                            logger.warn("Error My Renault Http Session.", e);
+                            Thread.currentThread().interrupt();
+                        } catch (RenaultForbiddenException | RenaultNotImplementedException | RenaultActionException
+                                | RenaultException | RenaultUpdateException | ExecutionException | TimeoutException e) {
+                            logger.warn("Error during action set pause.", e);
+                            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
+                        }
+                    } catch (IllegalArgumentException e) {
+                        logger.warn("Invalid Pause Mode {}.", command.toString());
+                        return;
+                    }
+                }
+                break;
             default:
                 if (command instanceof RefreshType) {
                     reschedulePollingJob();
index 72572fe32a04558d570a2b3b58fce8e665b43b14..789a0220685a990a0f0ce10257082543ce2bb480 100644 (file)
@@ -62,6 +62,7 @@ channel-type.renault.chargingmode.label = Charging Mode
 channel-type.renault.chargingmode.state.option.UNKNOWN = Unknown
 channel-type.renault.chargingmode.state.option.SCHEDULE_MODE = Schedule mode
 channel-type.renault.chargingmode.state.option.ALWAYS_CHARGING = Instant charge
+channel-type.renault.pause.label = Pause
 channel-type.renault.chargingremainingtime.label = Charging Time Remaining
 channel-type.renault.chargingstatus.label = Charging Status
 channel-type.renault.chargingstatus.state.option.NOT_IN_CHARGE = Not charging
index 3e517231be0bbb8431459965b0e9dea23c766150..5be829c2c9d48bfef57995eef2979510ba3f3e0e 100644 (file)
@@ -16,6 +16,7 @@
                        <channel id="plugstatus" typeId="plugstatus"/>
                        <channel id="chargingstatus" typeId="chargingstatus"/>
                        <channel id="chargingmode" typeId="chargingmode"/>
+                       <channel id="pause" typeId="pause"/>
                        <channel id="chargingremainingtime" typeId="chargingremainingtime"/>
                        <channel id="estimatedrange" typeId="estimatedrange"/>
                        <channel id="odometer" typeId="odometer"/>
                        </options>
                </state>
        </channel-type>
+       <channel-type id="pause">
+               <item-type>Switch</item-type>
+               <label>Pause Charge</label>
+               <description>Pause or resume the charge.</description>
+               <state readOnly="false"></state>
+       </channel-type>
        <channel-type id="chargingremainingtime">
                <item-type>Number:Time</item-type>
                <label>Charging Time Remaining</label>