Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[renault] Add channel for pausing/resuming charging #14527

Merged
merged 7 commits into from
Mar 10, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions bundles/org.openhab.binding.renault/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand All @@ -59,6 +60,8 @@ 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" mat not working on some cars. as an example "chargingmode" do not work on Dacia Spring cars.
fifipil909 marked this conversation as resolved.
Show resolved Hide resolved

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.
Expand All @@ -77,6 +80,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_PauseMode
fifipil909 marked this conversation as resolved.
Show resolved Hide resolved
Default item=RenaultCar_ChargingTimeRemaining
Default icon="pressure" item=RenaultCar_EstimatedRange
Default icon="pressure" item=RenaultCar_Odometer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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_MODE = "pause";
fifipil909 marked this conversation as resolved.
Show resolved Hide resolved
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";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.library.types.OnOffType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -45,6 +46,7 @@ public class Car {
private boolean disableHvac = false;
private boolean disableLockStatus = false;

private OnOffType pausemode = OnOffType.OFF;
fifipil909 marked this conversation as resolved.
Show resolved Hide resolved
private ChargingStatus chargingStatus = ChargingStatus.UNKNOWN;
private ChargingMode chargingMode = ChargingMode.UNKNOWN;
private PlugStatus plugStatus = PlugStatus.UNKNOWN;
Expand Down Expand Up @@ -298,6 +300,10 @@ public ChargingMode getChargingMode() {
return chargingMode;
}

public OnOffType getPauseMode() {
fifipil909 marked this conversation as resolved.
Show resolved Hide resolved
return pausemode;
}

public @Nullable Integer getChargingRemainingTime() {
return chargingRemainingTime;
}
Expand Down Expand Up @@ -346,6 +352,10 @@ public void setChargeMode(ChargingMode mode) {
}
}

public void setPauseMode(OnOffType pausemode) {
fifipil909 marked this conversation as resolved.
Show resolved Hide resolved
this.pausemode = pausemode;
}

private @Nullable JsonObject getAttributes(JsonObject responseJson)
throws IllegalStateException, ClassCastException {
if (responseJson.get("data") != null && responseJson.get("data").getAsJsonObject().get("attributes") != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.openhab.binding.renault.internal.api.exceptions.RenaultForbiddenException;
import org.openhab.binding.renault.internal.api.exceptions.RenaultNotImplementedException;
import org.openhab.binding.renault.internal.api.exceptions.RenaultUpdateException;
import org.openhab.core.library.types.OnOffType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -274,6 +275,16 @@ public void actionChargeMode(ChargingMode mode)
"{\"data\":{\"type\":\"ChargeMode\",\"attributes\":{\"action\":\"" + apiMode + "\"}}}");
}

public void actionPause(OnOffType mode)
fifipil909 marked this conversation as resolved.
Show resolved Hide resolved
throws RenaultForbiddenException, RenaultNotImplementedException, RenaultActionException {

final String apiMode = OnOffType.ON.equals(mode) ? "pause" : "resume";
fifipil909 marked this conversation as resolved.
Show resolved Hide resolved
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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,30 @@ public void handleCommand(ChannelUID channelUID, Command command) {
}
}
break;
case RenaultBindingConstants.CHANNEL_PAUSE_MODE:
if (command instanceof RefreshType) {
reschedulePollingJob();
} else if (command instanceof OnOffType) {
try {
MyRenaultHttpSession httpSession = new MyRenaultHttpSession(this.config, httpClient);
try {
OnOffType newcommand = OnOffType.from(command.toString());
httpSession.initSesssion(car);
httpSession.actionPause(newcommand);
car.setPauseMode(newcommand);
updateState(CHANNEL_PAUSE_MODE, newcommand);
fifipil909 marked this conversation as resolved.
Show resolved Hide resolved
} catch (InterruptedException | RenaultForbiddenException | RenaultNotImplementedException
| RenaultActionException | RenaultException | RenaultUpdateException
| ExecutionException | TimeoutException e) {
logger.warn("Error My Renault Http Session.", e);
Thread.currentThread().interrupt();
jlaur marked this conversation as resolved.
Show resolved Hide resolved
}
} catch (IllegalArgumentException e) {
logger.warn("Invalid Pause Mode {}.", command.toString());
return;
}
}
break;
default:
if (command instanceof RefreshType) {
reschedulePollingJob();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"/>
Expand Down Expand Up @@ -148,6 +149,12 @@
</options>
</state>
</channel-type>
<channel-type id="pause">
<item-type>Switch</item-type>
<label>Pause Charge</label>
fifipil909 marked this conversation as resolved.
Show resolved Hide resolved
<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>
Expand Down