mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 23:22:02 +01:00
[renault] Add channel for pausing/resuming charging (#14527)
* Adding Pause-Resume Endpoint Signed-off-by: fifipil909 <vincent.pilate@gmail.com>
This commit is contained in:
parent
505a651992
commit
8e9bc3124e
@ -37,6 +37,7 @@ You require your MyRenault credential, locale and VIN for your MyRenault registe
|
|||||||
| batterylevel | Number | State of the battery in % | Yes |
|
| batterylevel | Number | State of the battery in % | Yes |
|
||||||
| batterystatusupdated | DateTime | Timestamp of the last battery status update | Yes |
|
| batterystatusupdated | DateTime | Timestamp of the last battery status update | Yes |
|
||||||
| chargingmode | String | Charging mode. always_charging or schedule_mode | No |
|
| chargingmode | String | Charging mode. always_charging or schedule_mode | No |
|
||||||
|
| pause | Switch | Pause the charge. | No |
|
||||||
| chargingstatus | String | Charging status | Yes |
|
| chargingstatus | String | Charging status | Yes |
|
||||||
| chargingremainingtime | Number:Time | Charging time remaining | Yes |
|
| chargingremainingtime | Number:Time | Charging time remaining | Yes |
|
||||||
| plugstatus | String | Status of charging plug | 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.
|
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.
|
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.
|
The Kamereon API Key changes periodically, which causes a communication error.
|
||||||
To fix this error update the API Key in the bindings configuration.
|
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.
|
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="poweroutlet" item=RenaultCar_PlugStatus
|
||||||
Default icon="switch" item=RenaultCar_ChargingStatus
|
Default icon="switch" item=RenaultCar_ChargingStatus
|
||||||
Selection icon="switch" item=RenaultCar_ChargingMode mappings=[SCHEDULE_MODE="Schedule mode",ALWAYS_CHARGING="Instant charge"]
|
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 item=RenaultCar_ChargingTimeRemaining
|
||||||
Default icon="pressure" item=RenaultCar_EstimatedRange
|
Default icon="pressure" item=RenaultCar_EstimatedRange
|
||||||
Default icon="pressure" item=RenaultCar_Odometer
|
Default icon="pressure" item=RenaultCar_Odometer
|
||||||
|
@ -34,6 +34,7 @@ public class RenaultBindingConstants {
|
|||||||
public static final String CHANNEL_BATTERY_LEVEL = "batterylevel";
|
public static final String CHANNEL_BATTERY_LEVEL = "batterylevel";
|
||||||
public static final String CHANNEL_BATTERY_STATUS_UPDATED = "batterystatusupdated";
|
public static final String CHANNEL_BATTERY_STATUS_UPDATED = "batterystatusupdated";
|
||||||
public static final String CHANNEL_CHARGING_MODE = "chargingmode";
|
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_STATUS = "chargingstatus";
|
||||||
public static final String CHANNEL_CHARGING_REMAINING_TIME = "chargingremainingtime";
|
public static final String CHANNEL_CHARGING_REMAINING_TIME = "chargingremainingtime";
|
||||||
public static final String CHANNEL_ESTIMATED_RANGE = "estimatedrange";
|
public static final String CHANNEL_ESTIMATED_RANGE = "estimatedrange";
|
||||||
|
@ -45,6 +45,7 @@ public class Car {
|
|||||||
private boolean disableHvac = false;
|
private boolean disableHvac = false;
|
||||||
private boolean disableLockStatus = false;
|
private boolean disableLockStatus = false;
|
||||||
|
|
||||||
|
private boolean pausemode = false;
|
||||||
private ChargingStatus chargingStatus = ChargingStatus.UNKNOWN;
|
private ChargingStatus chargingStatus = ChargingStatus.UNKNOWN;
|
||||||
private ChargingMode chargingMode = ChargingMode.UNKNOWN;
|
private ChargingMode chargingMode = ChargingMode.UNKNOWN;
|
||||||
private PlugStatus plugStatus = PlugStatus.UNKNOWN;
|
private PlugStatus plugStatus = PlugStatus.UNKNOWN;
|
||||||
@ -298,6 +299,10 @@ public class Car {
|
|||||||
return chargingMode;
|
return chargingMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getPauseMode() {
|
||||||
|
return pausemode;
|
||||||
|
}
|
||||||
|
|
||||||
public @Nullable Integer getChargingRemainingTime() {
|
public @Nullable Integer getChargingRemainingTime() {
|
||||||
return chargingRemainingTime;
|
return chargingRemainingTime;
|
||||||
}
|
}
|
||||||
@ -346,6 +351,10 @@ public class Car {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPauseMode(boolean pausemode) {
|
||||||
|
this.pausemode = pausemode;
|
||||||
|
}
|
||||||
|
|
||||||
private @Nullable JsonObject getAttributes(JsonObject responseJson)
|
private @Nullable JsonObject getAttributes(JsonObject responseJson)
|
||||||
throws IllegalStateException, ClassCastException {
|
throws IllegalStateException, ClassCastException {
|
||||||
if (responseJson.get("data") != null && responseJson.get("data").getAsJsonObject().get("attributes") != null) {
|
if (responseJson.get("data") != null && responseJson.get("data").getAsJsonObject().get("attributes") != null) {
|
||||||
|
@ -274,6 +274,16 @@ public class MyRenaultHttpSession {
|
|||||||
"{\"data\":{\"type\":\"ChargeMode\",\"attributes\":{\"action\":\"" + apiMode + "\"}}}");
|
"{\"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)
|
private void postKamereonRequest(final String path, final String content)
|
||||||
throws RenaultForbiddenException, RenaultNotImplementedException, RenaultActionException {
|
throws RenaultForbiddenException, RenaultNotImplementedException, RenaultActionException {
|
||||||
Request request = httpClient.newRequest(this.constants.getKamereonRootUrl() + path).method(HttpMethod.POST)
|
Request request = httpClient.newRequest(this.constants.getKamereonRootUrl() + path).method(HttpMethod.POST)
|
||||||
|
@ -205,6 +205,32 @@ public class RenaultHandler extends BaseThingHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
if (command instanceof RefreshType) {
|
if (command instanceof RefreshType) {
|
||||||
reschedulePollingJob();
|
reschedulePollingJob();
|
||||||
|
@ -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.UNKNOWN = Unknown
|
||||||
channel-type.renault.chargingmode.state.option.SCHEDULE_MODE = Schedule mode
|
channel-type.renault.chargingmode.state.option.SCHEDULE_MODE = Schedule mode
|
||||||
channel-type.renault.chargingmode.state.option.ALWAYS_CHARGING = Instant charge
|
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.chargingremainingtime.label = Charging Time Remaining
|
||||||
channel-type.renault.chargingstatus.label = Charging Status
|
channel-type.renault.chargingstatus.label = Charging Status
|
||||||
channel-type.renault.chargingstatus.state.option.NOT_IN_CHARGE = Not charging
|
channel-type.renault.chargingstatus.state.option.NOT_IN_CHARGE = Not charging
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
<channel id="plugstatus" typeId="plugstatus"/>
|
<channel id="plugstatus" typeId="plugstatus"/>
|
||||||
<channel id="chargingstatus" typeId="chargingstatus"/>
|
<channel id="chargingstatus" typeId="chargingstatus"/>
|
||||||
<channel id="chargingmode" typeId="chargingmode"/>
|
<channel id="chargingmode" typeId="chargingmode"/>
|
||||||
|
<channel id="pause" typeId="pause"/>
|
||||||
<channel id="chargingremainingtime" typeId="chargingremainingtime"/>
|
<channel id="chargingremainingtime" typeId="chargingremainingtime"/>
|
||||||
<channel id="estimatedrange" typeId="estimatedrange"/>
|
<channel id="estimatedrange" typeId="estimatedrange"/>
|
||||||
<channel id="odometer" typeId="odometer"/>
|
<channel id="odometer" typeId="odometer"/>
|
||||||
@ -148,6 +149,12 @@
|
|||||||
</options>
|
</options>
|
||||||
</state>
|
</state>
|
||||||
</channel-type>
|
</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">
|
<channel-type id="chargingremainingtime">
|
||||||
<item-type>Number:Time</item-type>
|
<item-type>Number:Time</item-type>
|
||||||
<label>Charging Time Remaining</label>
|
<label>Charging Time Remaining</label>
|
||||||
|
Loading…
Reference in New Issue
Block a user