# evcc Binding
This binding integrates [evcc - electric vehicle charging control](https://evcc.io), a project that provides a control center for electric vehicle charging.
-The binding requires evcc [version 0.111.0](https://github.com/evcc-io/evcc/releases/tag/0.111.0) or newer and is tested with this version.
+The binding requires evcc [version 0.117.0](https://github.com/evcc-io/evcc/releases/tag/0.117.0) or newer and is tested with this version.
You can easily install and upgrade evcc on openHABian using `sudo openhabian-config`.
| general#batteryCapacity | Number:Energy | R | Capacity of (home) battery. |
| general#batteryPower | Number:Power | R | Current power from battery. |
| general#batterySoC | Number:Dimensionless | R | Current State of Charge of battery. |
-| general#batteryPrioritySoC | Number:Dimensionless | R | State of State of Charge for which the battery has priority over charging the ev when charging mode is "pv". |
+| general#batteryPrioritySoC | Number:Dimensionless | RW | State of State of Charge for which the battery has priority over charging the ev when charging mode is "pv". |
| general#gridPower | Number:Power | R | Current power from grid (negative means feed-in) |
| general#homePower | Number:Power | R | Current power taken by home. |
| general#pvPower | Number:Power | R | Current power from photovoltaik. |
| loadpointN#chargedEnergy | Number:Energy | R | Energy charged since plugged-in |
| loadpointN#charging | Switch | R | Loadpoint is currently charging |
| loadpointN#enabled | Switch | R | Charging enabled (mode is not "off") |
-| loadpointN#hasVehicle | Switch | R | Whether vehicle is configured for loadpoint |
| loadpointN#maxCurrent | Number:ElectricCurrent | RW | Maximum amperage per connected phase with which the car should be charged |
| loadpointN#minCurrent | Number:ElectricCurrent | RW | Minimum amperage per connected phase with which the car should be charged |
| loadpointN#minSoC | Number:Dimensionless | RW | Charge immediately with maximum power up to the defined SoC, if the charge mode is not set to "off" |
| loadpointN#mode | String | RW | Charging mode: "off", "now", "minpv", "pv" |
| loadpointN#phases | Number | RW | The maximum number of phases which can be used |
+| loadpointN#targetEnergy | Number:Energy | RW | Amount of energy to charge the vehicle with |
| loadpointN#targetSoC | Number:Dimensionless | RW | Until which state of charge (SoC) should the vehicle be charged |
| loadpointN#targetTime | DateTime | RW | When the target SoC should be reached |
| loadpointN#targetTimeEnabled | Switch | RW | Target time for charging enabled |
Number:Energy evcc_loadpoint0_chargedEnergy "Charged energy [%.1f kWh]" <energy> {channel="evcc:device:demo:loadpoint0#chargedEnergy"}
Switch evcc_loadpoint0_charging "Currently charging [%s]" <battery> {channel="evcc:device:demo:loadpoint0#charging"}
Switch evcc_loadpoint0_enabled "Charging enabled [%s]" <switch> {channel="evcc:device:demo:loadpoint0#enabled"}
-Switch evcc_loadpoint0_hasVehicle "Vehicle configured [%s]" <switch> {channel="evcc:device:demo:loadpoint0#hasVehicle"}
Number:ElectricCurrent evcc_loadpoint0_maxCurrent "Maximum current [%.0f A]" <energy> {channel="evcc:device:demo:loadpoint0#maxCurrent"}
Number:ElectricCurrent evcc_loadpoint0_minCurrent "Minimum current [%.0f A]" <energy> {channel="evcc:device:demo:loadpoint0#minCurrent"}
Number:Dimensionless evcc_loadpoint0_minSoC "Minimum SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:loadpoint0#minSoC"}
String evcc_loadpoint0_mode "Mode [%s]" {channel="evcc:device:demo:loadpoint0#mode"}
Number evcc_loadpoint0_phases "Enabled phases [%d]" {channel="evcc:device:demo:loadpoint0#phases"}
+Number:Energy evcc_loadpoint0_targetEnergy "Target energy [%.1f kWh]" <batterylevel> {channel="evcc:device:demo:loadpoint0#targetEnergy"}
Number:Dimensionless evcc_loadpoint0_targetSoC "Target SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:loadpoint0#targetSoC"}
DateTime evcc_loadpoint0_targetTime "Target time [%1$td.%1$tm.%1$tY, %1$tH:%1$tM]" <time> {channel="evcc:device:demo:loadpoint0#targetTime"}
Switch evcc_loadpoint0_targetTimeEnabled "Target time enabled [%s]" <switch> {channel="evcc:device:demo:loadpoint0#targetTimeEnabled"}
}
Switch item=evcc_loadpoint0_mode mappings=["off"="Stop","now"="Now","minpv"="Min + PV", "pv"="Only PV"]
Text label="Charging settings" icon="settings" {
+ Setpoint item=evcc_loadpoint0_targetEnergy minValue=5 maxValue=100 step=5
Setpoint item=evcc_loadpoint0_targetSoC minValue=5 maxValue=100 step=5
Setpoint item=evcc_loadpoint0_minCurrent minValue=6 maxValue=96 step=2
Setpoint item=evcc_loadpoint0_maxCurrent minValue=6 maxValue=96 step=2
private static final String BINDING_ID = "evcc";
+ public static final String CHANNEL_GROUP_ID_GENERAL = "general";
+
// List of all Channel ids
public static final String CHANNEL_BATTERY_CAPACITY = "batteryCapacity";
public static final String CHANNEL_BATTERY_POWER = "batteryPower";
public static final String CHANNEL_LOADPOINT_CHARGING = "charging";
public static final String CHANNEL_LOADPOINT_CONNECTED = "vehicleConnected";
public static final String CHANNEL_LOADPOINT_CONNECTED_DURATION = "vehicleConnectedDuration";
- public static final String CHANNEL_LOADPOINT_ENABLED = "enabled";
public static final String CHANNEL_LOADPOINT_HAS_VEHICLE = "hasVehicle";
+ public static final String CHANNEL_LOADPOINT_ENABLED = "enabled";
public static final String CHANNEL_LOADPOINT_MAX_CURRENT = "maxCurrent";
public static final String CHANNEL_LOADPOINT_MIN_CURRENT = "minCurrent";
public static final String CHANNEL_LOADPOINT_MIN_SOC = "minSoC";
public static final String CHANNEL_LOADPOINT_MODE = "mode";
public static final String CHANNEL_LOADPOINT_PHASES = "phases";
+ public static final String CHANNEL_LOADPOINT_TARGET_ENERGY = "targetEnergy";
public static final String CHANNEL_LOADPOINT_TARGET_SOC = "targetSoC";
public static final String CHANNEL_LOADPOINT_TARGET_TIME = "targetTime";
/**
CHANNEL_LOADPOINT_CONNECTED_DURATION);
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_ENABLED = new ChannelTypeUID(BINDING_ID,
CHANNEL_LOADPOINT_ENABLED);
- public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_HAS_VEHICLE = new ChannelTypeUID(BINDING_ID,
- CHANNEL_LOADPOINT_HAS_VEHICLE);
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_MAX_CURRENT = new ChannelTypeUID(BINDING_ID,
CHANNEL_LOADPOINT_MAX_CURRENT);
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_MIN_CURRENT = new ChannelTypeUID(BINDING_ID,
CHANNEL_LOADPOINT_MODE);
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_PHASES = new ChannelTypeUID(BINDING_ID,
CHANNEL_LOADPOINT_PHASES);
+ public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_TARGET_ENERGY = new ChannelTypeUID(BINDING_ID,
+ CHANNEL_LOADPOINT_TARGET_ENERGY);
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_TARGET_SOC = new ChannelTypeUID(BINDING_ID,
CHANNEL_LOADPOINT_TARGET_SOC);
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_TARGET_TIME = new ChannelTypeUID(BINDING_ID,
import org.openhab.core.library.unit.MetricPrefix;
import org.openhab.core.library.unit.SIUnits;
import org.openhab.core.library.unit.Units;
-import org.openhab.core.thing.Channel;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingUID;
import org.openhab.core.thing.binding.BaseThingHandler;
import org.openhab.core.thing.binding.builder.ChannelBuilder;
-import org.openhab.core.thing.binding.builder.ThingBuilder;
import org.openhab.core.thing.type.ChannelTypeUID;
import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType;
private boolean gridConfigured = false;
private boolean pvConfigured = false;
- private float targetSoC = 100;
private boolean targetTimeEnabled = false;
private ZonedDateTime targetTimeZDT = ZonedDateTime.now().plusHours(12);
if (groupId == null) {
return;
}
+ String channelGroupId = channelUID.getGroupId();
String channelIdWithoutGroup = channelUID.getIdWithoutGroup();
- int loadpoint = Integer.parseInt(groupId.substring(9)) + 1;
EvccAPI evccAPI = this.evccAPI;
if (evccAPI == null) {
return;
}
try {
- switch (channelIdWithoutGroup) {
- case CHANNEL_LOADPOINT_MODE:
- if (command instanceof StringType) {
- evccAPI.setMode(loadpoint, command.toString());
- } else {
- logger.debug("Command has wrong type, StringType required!");
+ if (channelGroupId.equals(CHANNEL_GROUP_ID_GENERAL)) {
+ if (!channelIdWithoutGroup.equals(CHANNEL_BATTERY_PRIORITY_SOC)) {
+ return;
+ }
+ if (command instanceof QuantityType<?> qt) {
+ evccAPI.setBatteryPrioritySoC(qt.toUnit(Units.PERCENT).intValue());
+ } else if (command instanceof DecimalType dt) {
+ evccAPI.setBatteryPrioritySoC(dt.intValue());
+ } else {
+ logger.debug("Command has wrong type, QuantityType or DecimalType required!");
+ }
+ } else {
+ int loadpoint = Integer.parseInt(groupId.substring(9)) + 1;
+ switch (channelIdWithoutGroup) {
+ case CHANNEL_LOADPOINT_MODE -> {
+ if (command instanceof StringType) {
+ evccAPI.setMode(loadpoint, command.toString());
+ } else {
+ logger.debug("Command has wrong type, StringType required!");
+ }
}
- break;
- case CHANNEL_LOADPOINT_MIN_SOC:
- if (command instanceof QuantityType) {
- evccAPI.setMinSoC(loadpoint, ((QuantityType<?>) command).toUnit(Units.PERCENT).intValue());
- } else if (command instanceof DecimalType) {
- evccAPI.setMinSoC(loadpoint, ((DecimalType) command).intValue());
- } else {
- logger.debug("Command has wrong type, QuantityType or DecimalType required!");
+ case CHANNEL_LOADPOINT_MIN_SOC -> {
+ if (command instanceof QuantityType<?> qt) {
+ evccAPI.setMinSoC(loadpoint, qt.toUnit(Units.PERCENT).intValue());
+ } else if (command instanceof DecimalType dt) {
+ evccAPI.setMinSoC(loadpoint, dt.intValue());
+ } else {
+ logger.debug("Command has wrong type, QuantityType or DecimalType required!");
+ }
}
- break;
- case CHANNEL_LOADPOINT_TARGET_SOC:
- if (command instanceof QuantityType) {
- evccAPI.setTargetSoC(loadpoint,
- ((QuantityType<?>) command).toUnit(Units.PERCENT).intValue());
- } else if (command instanceof DecimalType) {
- evccAPI.setTargetSoC(loadpoint, ((DecimalType) command).intValue());
- } else {
- logger.debug("Command has wrong type, QuantityType or DecimalType required!");
+ case CHANNEL_LOADPOINT_TARGET_ENERGY -> {
+ if (command instanceof QuantityType<?> qt) {
+ evccAPI.setTargetEnergy(loadpoint, qt.toUnit(Units.WATT_HOUR).floatValue());
+ } else {
+ logger.debug("Command has wrong type, QuantityType required!");
+ }
}
- break;
- case CHANNEL_LOADPOINT_TARGET_TIME:
- if (command instanceof DateTimeType) {
- targetTimeZDT = ((DateTimeType) command).getZonedDateTime();
- ChannelUID channel = new ChannelUID(getThing().getUID(), "loadpoint" + loadpoint,
- CHANNEL_LOADPOINT_TARGET_TIME);
- updateState(channel, new DateTimeType(targetTimeZDT));
- if (targetTimeEnabled) {
- try {
- evccAPI.setTargetCharge(loadpoint, targetSoC, targetTimeZDT);
- } catch (DateTimeParseException e) {
- logger.debug("Failed to set target charge: ", e);
+ case CHANNEL_LOADPOINT_TARGET_SOC -> {
+ if (command instanceof QuantityType<?> qt) {
+ evccAPI.setTargetSoC(loadpoint, qt.toUnit(Units.PERCENT).intValue());
+ } else if (command instanceof DecimalType dt) {
+ evccAPI.setTargetSoC(loadpoint, dt.intValue());
+ } else {
+ logger.debug("Command has wrong type, QuantityType or DecimalType required!");
+ }
+ }
+ case CHANNEL_LOADPOINT_TARGET_TIME -> {
+ if (command instanceof DateTimeType dtt) {
+ targetTimeZDT = dtt.getZonedDateTime();
+ ChannelUID channel = new ChannelUID(getThing().getUID(), "loadpoint" + loadpoint,
+ CHANNEL_LOADPOINT_TARGET_TIME);
+ updateState(channel, new DateTimeType(targetTimeZDT));
+ if (targetTimeEnabled) {
+ try {
+ evccAPI.setTargetTime(loadpoint, targetTimeZDT);
+ } catch (DateTimeParseException e) {
+ logger.debug("Failed to set target charge: ", e);
+ }
}
+ } else {
+ logger.debug("Command has wrong type, DateTimeType required!");
}
- } else {
- logger.debug("Command has wrong type, DateTimeType required!");
}
- break;
- case CHANNEL_LOADPOINT_TARGET_TIME_ENABLED:
- if (command == OnOffType.ON) {
- evccAPI.setTargetCharge(loadpoint, targetSoC, targetTimeZDT);
- targetTimeEnabled = true;
- } else if (command == OnOffType.OFF) {
- evccAPI.unsetTargetCharge(loadpoint);
- targetTimeEnabled = false;
- } else {
- logger.debug("Command has wrong type, OnOffType required!");
+ case CHANNEL_LOADPOINT_TARGET_TIME_ENABLED -> {
+ if (command == OnOffType.ON) {
+ evccAPI.setTargetTime(loadpoint, targetTimeZDT);
+ targetTimeEnabled = true;
+ } else if (command == OnOffType.OFF) {
+ evccAPI.removeTargetTime(loadpoint);
+ targetTimeEnabled = false;
+ } else {
+ logger.debug("Command has wrong type, OnOffType required!");
+ }
}
- break;
- case CHANNEL_LOADPOINT_PHASES:
- if (command instanceof DecimalType) {
- evccAPI.setPhases(loadpoint, ((DecimalType) command).intValue());
- } else {
- logger.debug("Command has wrong type, DecimalType required!");
+ case CHANNEL_LOADPOINT_PHASES -> {
+ if (command instanceof DecimalType dt) {
+ evccAPI.setPhases(loadpoint, dt.intValue());
+ } else {
+ logger.debug("Command has wrong type, DecimalType required!");
+ }
+ }
+ case CHANNEL_LOADPOINT_MIN_CURRENT -> {
+ if (command instanceof QuantityType<?> qt) {
+ evccAPI.setMinCurrent(loadpoint, qt.toUnit(Units.AMPERE).intValue());
+ } else if (command instanceof DecimalType dt) {
+ evccAPI.setMinCurrent(loadpoint, dt.intValue());
+ } else {
+ logger.debug("Command has wrong type, QuantityType or DecimalType required!");
+ }
}
- break;
- case CHANNEL_LOADPOINT_MIN_CURRENT:
- if (command instanceof QuantityType) {
- evccAPI.setMinCurrent(loadpoint,
- ((QuantityType<?>) command).toUnit(Units.AMPERE).intValue());
- } else if (command instanceof DecimalType) {
- evccAPI.setMinCurrent(loadpoint, ((DecimalType) command).intValue());
- } else {
- logger.debug("Command has wrong type, QuantityType or DecimalType required!");
+ case CHANNEL_LOADPOINT_MAX_CURRENT -> {
+ if (command instanceof QuantityType<?> qt) {
+ evccAPI.setMaxCurrent(loadpoint, qt.toUnit(Units.AMPERE).intValue());
+ } else if (command instanceof DecimalType dt) {
+ evccAPI.setMaxCurrent(loadpoint, dt.intValue());
+ } else {
+ logger.debug("Command has wrong type, QuantityType or DecimalType required!");
+ }
}
- break;
- case CHANNEL_LOADPOINT_MAX_CURRENT:
- if (command instanceof QuantityType) {
- evccAPI.setMaxCurrent(loadpoint,
- ((QuantityType<?>) command).toUnit(Units.AMPERE).intValue());
- } else if (command instanceof DecimalType) {
- evccAPI.setMaxCurrent(loadpoint, ((DecimalType) command).intValue());
- } else {
- logger.debug("Command has wrong type, QuantityType or DecimalType required!");
+ default -> {
+ return;
}
- break;
- default:
- return;
+ }
}
} catch (EvccApiException e) {
Throwable cause = e.getCause();
// Utility functions
private void createChannelsGeneral() {
- final String channelGroup = "general";
if (batteryConfigured) {
- createChannel(CHANNEL_BATTERY_CAPACITY, channelGroup, CHANNEL_TYPE_UID_BATTERY_CAPACITY, "Number:Energy");
- createChannel(CHANNEL_BATTERY_POWER, channelGroup, CHANNEL_TYPE_UID_BATTERY_POWER, "Number:Power");
- createChannel(CHANNEL_BATTERY_SOC, channelGroup, CHANNEL_TYPE_UID_BATTERY_SOC, "Number:Dimensionless");
- createChannel(CHANNEL_BATTERY_PRIORITY_SOC, channelGroup, CHANNEL_TYPE_UID_BATTERY_PRIORITY_SOC,
+ createChannel(CHANNEL_BATTERY_CAPACITY, CHANNEL_GROUP_ID_GENERAL, CHANNEL_TYPE_UID_BATTERY_CAPACITY,
+ "Number:Energy");
+ createChannel(CHANNEL_BATTERY_POWER, CHANNEL_GROUP_ID_GENERAL, CHANNEL_TYPE_UID_BATTERY_POWER,
+ "Number:Power");
+ createChannel(CHANNEL_BATTERY_SOC, CHANNEL_GROUP_ID_GENERAL, CHANNEL_TYPE_UID_BATTERY_SOC,
+ "Number:Dimensionless");
+ createChannel(CHANNEL_BATTERY_PRIORITY_SOC, CHANNEL_GROUP_ID_GENERAL, CHANNEL_TYPE_UID_BATTERY_PRIORITY_SOC,
"Number:Dimensionless");
}
if (gridConfigured) {
- createChannel(CHANNEL_GRID_POWER, channelGroup, CHANNEL_TYPE_UID_GRID_POWER, "Number:Power");
+ createChannel(CHANNEL_GRID_POWER, CHANNEL_GROUP_ID_GENERAL, CHANNEL_TYPE_UID_GRID_POWER, "Number:Power");
}
- createChannel(CHANNEL_HOME_POWER, channelGroup, CHANNEL_TYPE_UID_HOME_POWER, "Number:Power");
+ createChannel(CHANNEL_HOME_POWER, CHANNEL_GROUP_ID_GENERAL, CHANNEL_TYPE_UID_HOME_POWER, "Number:Power");
if (pvConfigured) {
- createChannel(CHANNEL_PV_POWER, channelGroup, CHANNEL_TYPE_UID_PV_POWER, "Number:Power");
+ createChannel(CHANNEL_PV_POWER, CHANNEL_GROUP_ID_GENERAL, CHANNEL_TYPE_UID_PV_POWER, "Number:Power");
}
}
"Number:Time");
createChannel(CHANNEL_LOADPOINT_ENABLED, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_ENABLED,
CoreItemFactory.SWITCH);
- createChannel(CHANNEL_LOADPOINT_HAS_VEHICLE, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_HAS_VEHICLE,
- CoreItemFactory.SWITCH);
createChannel(CHANNEL_LOADPOINT_MAX_CURRENT, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_MAX_CURRENT,
"Number:ElectricCurrent");
createChannel(CHANNEL_LOADPOINT_MIN_CURRENT, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_MIN_CURRENT,
createChannel(CHANNEL_LOADPOINT_MODE, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_MODE, CoreItemFactory.STRING);
createChannel(CHANNEL_LOADPOINT_PHASES, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_PHASES,
CoreItemFactory.NUMBER);
+ createChannel(CHANNEL_LOADPOINT_TARGET_ENERGY, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_TARGET_ENERGY,
+ "Number:Energy");
createChannel(CHANNEL_LOADPOINT_TARGET_SOC, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_TARGET_SOC,
"Number:Dimensionless");
createChannel(CHANNEL_LOADPOINT_TARGET_TIME, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_TARGET_TIME,
"Number:Dimensionless");
createChannel(CHANNEL_LOADPOINT_VEHICLE_TITLE, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_TITLE,
CoreItemFactory.STRING);
+
+ removeChannel(CHANNEL_LOADPOINT_HAS_VEHICLE, channelGroup);
}
// Units and description for vars: https://docs.evcc.io/docs/reference/configuration/messaging/#msg
boolean batteryConfigured = this.batteryConfigured;
if (batteryConfigured) {
float batteryCapacity = result.getBatteryCapacity();
- channel = new ChannelUID(uid, "general", CHANNEL_BATTERY_CAPACITY);
+ channel = new ChannelUID(uid, CHANNEL_GROUP_ID_GENERAL, CHANNEL_BATTERY_CAPACITY);
updateState(channel, new QuantityType<>(batteryCapacity, Units.KILOWATT_HOUR));
float batteryPower = result.getBatteryPower();
- channel = new ChannelUID(uid, "general", CHANNEL_BATTERY_POWER);
+ channel = new ChannelUID(uid, CHANNEL_GROUP_ID_GENERAL, CHANNEL_BATTERY_POWER);
updateState(channel, new QuantityType<>(batteryPower, Units.WATT));
float batterySoC = result.getBatterySoC();
- channel = new ChannelUID(uid, "general", CHANNEL_BATTERY_SOC);
+ channel = new ChannelUID(uid, CHANNEL_GROUP_ID_GENERAL, CHANNEL_BATTERY_SOC);
updateState(channel, new QuantityType<>(batterySoC, Units.PERCENT));
float batteryPrioritySoC = result.getBatteryPrioritySoC();
- channel = new ChannelUID(uid, "general", CHANNEL_BATTERY_PRIORITY_SOC);
+ channel = new ChannelUID(uid, CHANNEL_GROUP_ID_GENERAL, CHANNEL_BATTERY_PRIORITY_SOC);
updateState(channel, new QuantityType<>(batteryPrioritySoC, Units.PERCENT));
}
boolean gridConfigured = this.gridConfigured;
if (gridConfigured) {
float gridPower = result.getGridPower();
- channel = new ChannelUID(uid, "general", CHANNEL_GRID_POWER);
+ channel = new ChannelUID(uid, CHANNEL_GROUP_ID_GENERAL, CHANNEL_GRID_POWER);
updateState(channel, new QuantityType<>(gridPower, Units.WATT));
}
float homePower = result.getHomePower();
- channel = new ChannelUID(uid, "general", CHANNEL_HOME_POWER);
+ channel = new ChannelUID(uid, CHANNEL_GROUP_ID_GENERAL, CHANNEL_HOME_POWER);
updateState(channel, new QuantityType<>(homePower, Units.WATT));
boolean pvConfigured = this.pvConfigured;
if (pvConfigured) {
float pvPower = result.getPvPower();
- channel = new ChannelUID(uid, "general", CHANNEL_PV_POWER);
+ channel = new ChannelUID(uid, CHANNEL_GROUP_ID_GENERAL, CHANNEL_PV_POWER);
updateState(channel, new QuantityType<>(pvPower, Units.WATT));
}
}
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_ENABLED);
updateState(channel, OnOffType.from(enabled));
- boolean hasVehicle = loadpoint.getHasVehicle();
- channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_HAS_VEHICLE);
- updateState(channel, OnOffType.from(hasVehicle));
-
float maxCurrent = loadpoint.getMaxCurrent();
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_MAX_CURRENT);
updateState(channel, new QuantityType<>(maxCurrent, Units.AMPERE));
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_PHASES);
updateState(channel, new DecimalType(phases));
- targetSoC = loadpoint.getTargetSoC();
+ float targetEnergy = loadpoint.getTargetEnergy();
+ channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_TARGET_ENERGY);
+ updateState(channel, new QuantityType<>(targetEnergy, Units.WATT_HOUR));
+
+ float targetSoC = loadpoint.getTargetSoC();
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_TARGET_SOC);
updateState(channel, new QuantityType<>(targetSoC, Units.PERCENT));
String targetTime = loadpoint.getTargetTime();
- if (targetTime == null) {
+ if (targetTime == null || targetTime.equals("0001-01-01T00:00:00Z")) {
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_TARGET_TIME_ENABLED);
updateState(channel, OnOffType.OFF);
targetTimeEnabled = false;
}
private void createChannel(String channel, String channelGroupId, ChannelTypeUID channelTypeUID, String itemType) {
- ChannelUID channelToCheck = new ChannelUID(thing.getUID(), channelGroupId, channel);
- if (thing.getChannel(channelToCheck) == null) {
- ThingBuilder thingBuilder = editThing();
- Channel testchannel = ChannelBuilder
- .create(new ChannelUID(getThing().getUID(), channelGroupId, channel), itemType)
- .withType(channelTypeUID).build();
- thingBuilder.withChannel(testchannel);
- updateThing(thingBuilder.build());
+ ChannelUID channelUid = new ChannelUID(thing.getUID(), channelGroupId, channel);
+ if (thing.getChannel(channelUid) == null) {
+ updateThing(editThing()
+ .withChannel(ChannelBuilder.create(channelUid, itemType).withType(channelTypeUID).build()).build());
+ }
+ }
+
+ private void removeChannel(String channel, String channelGroupId) {
+ ChannelUID channelUid = new ChannelUID(thing.getUID(), channelGroupId, channel);
+ if (thing.getChannel(channelUid) != null) {
+ updateThing(editThing().withoutChannel(channelUid).build());
}
}
}
/**
* The {@link EvccAPI} is responsible for API calls to evcc.
- *
+ * API requests were written for evcc version 0.117.0
+ *
* @author Florian Hotze - Initial contribution
*/
@NonNullByDefault
/**
* Make a HTTP request.
- *
+ *
* @param url full request URL
* @param method request method, e.g. GET, POST
* @return the response body
}
}
+ // Site API calls.
+ public String setBatteryPrioritySoC(int prioritySoc) throws EvccApiException {
+ return httpRequest(this.host + EVCC_REST_API + "prioritysoc/" + prioritySoc, "POST");
+ }
+
// Loadpoint specific API calls.
public String setMode(int loadpoint, String mode) throws EvccApiException {
return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/mode/" + mode, "POST");
return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/minsoc/" + minSoC, "POST");
}
+ public String setTargetEnergy(int loadpoint, float targetEnergy) throws EvccApiException {
+ return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/target/energy/" + targetEnergy,
+ "POST");
+ }
+
public String setTargetSoC(int loadpoint, int targetSoC) throws EvccApiException {
- return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/targetsoc/" + targetSoC, "POST");
+ return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/target/soc/" + targetSoC, "POST");
}
public String setPhases(int loadpoint, int phases) throws EvccApiException {
return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/maxcurrent/" + maxCurrent, "POST");
}
- public String setTargetCharge(int loadpoint, float targetSoC, ZonedDateTime targetTime) throws EvccApiException {
- DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
- return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/targetcharge/" + targetSoC + "/"
- + targetTime.toLocalDateTime().format(formatter), "POST");
+ public String setTargetTime(int loadpoint, ZonedDateTime targetTime) throws EvccApiException {
+ return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/target/time/"
+ + targetTime.toLocalDateTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) + "Z", "POST");
}
- public String unsetTargetCharge(int loadpoint) throws EvccApiException {
- return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/targetcharge", "DELETE");
+ public String removeTargetTime(int loadpoint) throws EvccApiException {
+ return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/target/time", "DELETE");
}
}
/**
* This class represents a loadpoint object of the status response (/api/state).
- * This DTO was written for evcc version 0.111.1
+ * This DTO was written for evcc version 0.117.0
*
* @author Florian Hotze - Initial contribution
*/
@SerializedName("enabled")
private boolean enabled;
- @SerializedName("hasVehicle")
- private boolean hasVehicle;
-
- @SerializedName("loadpoint")
- private int loadpoint;
-
@SerializedName("maxCurrent")
private float maxCurrent;
@SerializedName("mode")
private String mode;
- @SerializedName("phases")
+ @SerializedName("phasesEnabled")
private int phases;
- @SerializedName("pvAction")
- private String pvAction;
+ @SerializedName("planActive")
+ private boolean planActive;
- @SerializedName("pvRemaining")
- private long pvRemaining;
+ @SerializedName("targetEnergy")
+ private float targetEnergy;
@SerializedName("targetSoc")
private float targetSoC;
return enabled;
}
- /**
- * @return whether vehicle is configured for loadpoint
- */
- public boolean getHasVehicle() {
- return hasVehicle;
- }
-
- /**
- * @return loadpoint id
- */
- public int getLoadpoint() {
- return loadpoint;
- }
-
/**
* @return maximum current
*/
}
/**
- * @return the pv action
+ * @return whether charging plan is active
*/
- public String getPvAction() {
- return pvAction;
+ public boolean getPlanActive() {
+ return planActive;
}
/**
- * @return the pv remaining
+ * @return target energy
*/
- public long getPvRemaining() {
- return pvRemaining;
+ public float getTargetEnergy() {
+ return targetEnergy;
}
/**
/**
* This class represents the result object of the status response (/api/state).
- * This DTO was written for evcc version 0.111.1
+ * This DTO was written for evcc version 0.117.0
*
* @author Florian Hotze - Initial contribution
*/
/**
* This class represents the status response (/api/state).
- * This DTO was written for evcc version 0.111.1
+ * This DTO was written for evcc version 0.117.0
*
* @author Florian Hotze - Initial contribution
*/
# channel group types
-channel-group-type.evcc.general.label = General data
+channel-group-type.evcc.general.label = General Data
channel-group-type.evcc.loadpoint.label = Loadpoint
# channel types
-channel-type.evcc.activePhases.label = Charging active phases
+channel-type.evcc.activePhases.label = Charging Active Phases
channel-type.evcc.activePhases.description = Current number of active phases while charging
channel-type.evcc.batteryCapacity.label = Battery Capacity
channel-type.evcc.batteryCapacity.description = Capacity of (home) battery
channel-type.evcc.batteryPrioritySoC.description = State of Charge for which the battery has priority over charging the ev when charging mode is "pv".
channel-type.evcc.batterySoC.label = Battery SoC
channel-type.evcc.batterySoC.description = Current State of Charge of battery
-channel-type.evcc.chargeCurrent.label = Charging current
+channel-type.evcc.chargeCurrent.label = Charging Current
channel-type.evcc.chargeCurrent.description = Current amperage per connected phase while charging
-channel-type.evcc.chargeDuration.label = Charging duration
+channel-type.evcc.chargeDuration.label = Charging Duration
channel-type.evcc.chargeDuration.description = Charging duration
-channel-type.evcc.chargePower.label = Charging power
+channel-type.evcc.chargePower.label = Charging Power
channel-type.evcc.chargePower.description = Current power of charging
-channel-type.evcc.chargeRemainingDuration.label = Charging remaining duration
+channel-type.evcc.chargeRemainingDuration.label = Charging Remaining Duration
channel-type.evcc.chargeRemainingDuration.description = Remaining duration until target SoC is reached
-channel-type.evcc.chargeRemainingEnergy.label = Charging remaining energy
+channel-type.evcc.chargeRemainingEnergy.label = Charging Remaining Energy
channel-type.evcc.chargeRemainingEnergy.description = Remaining energy until target SoC is reached
-channel-type.evcc.chargedEnergy.label = Charged energy
+channel-type.evcc.chargedEnergy.label = Charged Energy
channel-type.evcc.chargedEnergy.description = Energy charged since plugged-in
-channel-type.evcc.charging.label = Charging state
+channel-type.evcc.charging.label = Charging State
channel-type.evcc.charging.description = Loadpoint is currently charging
channel-type.evcc.charging.state.option.ON = Charging
channel-type.evcc.charging.state.option.OFF = Not charging
-channel-type.evcc.enabled.label = Charging enabled
+channel-type.evcc.enabled.label = Charging Enabled
channel-type.evcc.enabled.description = Charging enabled (mode not "off")
channel-type.evcc.enabled.state.option.ON = Enabled
channel-type.evcc.enabled.state.option.OFF = Disabled
channel-type.evcc.gridPower.label = Grid Power
channel-type.evcc.gridPower.description = Current power from grid (negative means feed-in)
-channel-type.evcc.hasVehicle.label = Loadpoint has vehicle configuration
-channel-type.evcc.hasVehicle.description = Whether vehicle is configured for loadpoint
-channel-type.evcc.hasVehicle.state.option.ON = Configured
-channel-type.evcc.hasVehicle.state.option.OFF = Not configured
channel-type.evcc.homePower.label = Home Power
channel-type.evcc.homePower.description = Current power taken by home
-channel-type.evcc.maxCurrent.label = Charging max current
+channel-type.evcc.maxCurrent.label = Charging max Current
channel-type.evcc.maxCurrent.description = Maximum amperage per connected phase with which the car should be charged
-channel-type.evcc.minCurrent.label = Charging min current
+channel-type.evcc.minCurrent.label = Charging min Current
channel-type.evcc.minCurrent.description = Minimum amperage per connected phase with which the car should be charged
channel-type.evcc.minSoC.label = Charging min SoC
channel-type.evcc.minSoC.description = Charge immediately with maximum power up to the defined SoC, if the charge mode is not set to "off"
-channel-type.evcc.mode.label = Charging mode
+channel-type.evcc.mode.label = Charging Mode
channel-type.evcc.mode.description = Charging mode: "off", "now", "minpv", "pv"
channel-type.evcc.mode.state.option.off = Off
-channel-type.evcc.mode.state.option.now = Now
+channel-type.evcc.mode.state.option.now = Fast
channel-type.evcc.mode.state.option.minpv = Min + PV
channel-type.evcc.mode.state.option.pv = Only PV
-channel-type.evcc.phases.label = Charging enabled phases
+channel-type.evcc.phases.label = Charging Enabled Phases
channel-type.evcc.phases.description = The maximum number of phases which can be used
channel-type.evcc.pvPower.label = PV Power
channel-type.evcc.pvPower.description = Current power from photovoltaik
-channel-type.evcc.targetSoC.label = Charging target SoC
+channel-type.evcc.targetEnergy.label = Charging Target Energy
+channel-type.evcc.targetEnergy.description = Amount of energy to charge the vehicle with
+channel-type.evcc.targetSoC.label = Charging Target SoC
channel-type.evcc.targetSoC.description = Until which state of charge (SoC) should the vehicle be charged
-channel-type.evcc.targetTime.label = Charging target time
+channel-type.evcc.targetTime.label = Charging Target Time
channel-type.evcc.targetTime.description = When the target SoC should be reached
-channel-type.evcc.targetTimeEnabled.label = Charging target time enabled
+channel-type.evcc.targetTimeEnabled.label = Charging Target Time Enabled
channel-type.evcc.targetTimeEnabled.description = Target time for charging enabled
channel-type.evcc.targetTimeEnabled.state.option.ON = Enabled
channel-type.evcc.targetTimeEnabled.state.option.OFF = Disabled
-channel-type.evcc.title.label = Loadpoint title
+channel-type.evcc.title.label = Loadpoint Title
channel-type.evcc.title.description = Title of loadpoint
-channel-type.evcc.vehicleCapacity.label = Vehicle capacity
+channel-type.evcc.vehicleCapacity.label = Vehicle Capacity
channel-type.evcc.vehicleCapacity.description = Capacity of EV battery
-channel-type.evcc.vehicleConnected.label = Vehicle connected
+channel-type.evcc.vehicleConnected.label = Vehicle Connected
channel-type.evcc.vehicleConnected.description = Whether vehicle is connected to loadpoint
channel-type.evcc.vehicleConnected.state.option.ON = Connected
channel-type.evcc.vehicleConnected.state.option.OFF = Not connected
-channel-type.evcc.vehicleConnectedDuration.label = Vehicle connected duration
+channel-type.evcc.vehicleConnectedDuration.label = Vehicle Connected Duration
channel-type.evcc.vehicleConnectedDuration.description = Duration the vehicle is connected to loadpoint
-channel-type.evcc.vehicleOdometer.label = Vehicle odometer
+channel-type.evcc.vehicleOdometer.label = Vehicle Odometer
channel-type.evcc.vehicleOdometer.description = Total distance travelled by EV
-channel-type.evcc.vehiclePresent.label = Vehicle data access
+channel-type.evcc.vehiclePresent.label = Vehicle Data Access
channel-type.evcc.vehiclePresent.description = Whether evcc is able to get data from vehicle
channel-type.evcc.vehiclePresent.state.option.ON = Data access
channel-type.evcc.vehiclePresent.state.option.OFF = No data access
-channel-type.evcc.vehicleRange.label = Vehicle range
+channel-type.evcc.vehicleRange.label = Vehicle Range
channel-type.evcc.vehicleRange.description = Battery range for EV
channel-type.evcc.vehicleSoC.label = Vehicle SoC
channel-type.evcc.vehicleSoC.description = Current State of Charge of EV
-channel-type.evcc.vehicleTitle.label = Vehicle title
+channel-type.evcc.vehicleTitle.label = Vehicle Title
channel-type.evcc.vehicleTitle.description = Name of EV
# thing status description
</thing-type>
<channel-group-type id="general">
- <label>General data</label>
+ <label>General Data</label>
</channel-group-type>
<channel-group-type id="loadpoint">
<label>Loadpoint</label>
<item-type>Number:Dimensionless</item-type>
<label>Battery SoC</label>
<description>Current State of Charge of battery</description>
- <category>batterylevel</category>
+ <category>BatteryLevel</category>
<state pattern="%.0f %unit%" readOnly="true"/>
</channel-type>
<channel-type id="batteryPrioritySoC">
<item-type>Number:Dimensionless</item-type>
<label>Battery Priority SoC</label>
<description>State of Charge for which the battery has priority over charging the ev when charging mode is "pv".</description>
- <category>batterylevel</category>
- <state pattern="%.0f %unit%" readOnly="true"/>
+ <category>BatteryLevel</category>
+ <state min="0" step="0.1" max="100" pattern="%.0f %unit%" readOnly="false"/>
</channel-type>
<channel-type id="gridPower">
<item-type>Number:Power</item-type>
<!-- Channels for loadpoints -->
<channel-type id="activePhases">
<item-type>Number</item-type>
- <label>Charging active phases</label>
+ <label>Charging Active Phases</label>
<description>Current number of active phases while charging</description>
<category></category>
<state pattern="%d" readOnly="true"/>
</channel-type>
<channel-type id="chargeCurrent">
<item-type>Number:ElectricCurrent</item-type>
- <label>Charging current</label>
+ <label>Charging Current</label>
<description>Current amperage per connected phase while charging</description>
<category>Energy</category>
<state pattern="%.1f %unit%" readOnly="true"/>
</channel-type>
<channel-type id="chargeDuration">
<item-type>Number:Time</item-type>
- <label>Charging duration</label>
+ <label>Charging Duration</label>
<description>Charging duration</description>
<category>Time</category>
<state pattern="%.1f min" readOnly="true"/>
</channel-type>
<channel-type id="chargePower">
<item-type>Number:Power</item-type>
- <label>Charging power</label>
+ <label>Charging Power</label>
<description>Current power of charging</description>
<category>Energy</category>
<state pattern="%.1f %unit%" readOnly="true"/>
</channel-type>
<channel-type id="chargeRemainingDuration">
<item-type>Number:Time</item-type>
- <label>Charging remaining duration</label>
+ <label>Charging Remaining Duration</label>
<description>Remaining duration until target SoC is reached</description>
<category>Time</category>
<state pattern="%.1f min" readOnly="true"/>
</channel-type>
<channel-type id="chargeRemainingEnergy">
<item-type>Number:Energy</item-type>
- <label>Charging remaining energy</label>
+ <label>Charging Remaining Energy</label>
<description>Remaining energy until target SoC is reached</description>
<category>Energy</category>
<state pattern="%.1f %unit%" readOnly="true"/>
</channel-type>
<channel-type id="chargedEnergy">
<item-type>Number:Energy</item-type>
- <label>Charged energy</label>
+ <label>Charged Energy</label>
<description>Energy charged since plugged-in</description>
<category>Energy</category>
<state pattern="%.1f %unit%" readOnly="true"/>
</channel-type>
<channel-type id="charging">
<item-type>Switch</item-type>
- <label>Charging state</label>
+ <label>Charging State</label>
<description>Loadpoint is currently charging</description>
<category>Energy</category>
<state pattern="%f %unit%" readOnly="true">
</channel-type>
<channel-type id="enabled">
<item-type>Switch</item-type>
- <label>Charging enabled</label>
+ <label>Charging Enabled</label>
<description>Charging enabled (mode not "off")</description>
<category>Switch</category>
<state readOnly="true">
</options>
</state>
</channel-type>
- <channel-type id="hasVehicle">
- <item-type>Switch</item-type>
- <label>Loadpoint has vehicle configuration</label>
- <description>Whether vehicle is configured for loadpoint</description>
- <category>Switch</category>
- <state readOnly="true">
- <options>
- <option value="ON">Configured</option>
- <option value="OFF">Not configured</option>
- </options>
- </state>
- </channel-type>
<channel-type id="maxCurrent">
<item-type>Number:ElectricCurrent</item-type>
- <label>Charging max current</label>
+ <label>Charging max Current</label>
<description>Maximum amperage per connected phase with which the car should be charged</description>
<category>Energy</category>
<state min="0" step="1" pattern="%.0f %unit%" readOnly="false"/>
</channel-type>
<channel-type id="minCurrent">
<item-type>Number:ElectricCurrent</item-type>
- <label>Charging min current</label>
+ <label>Charging min Current</label>
<description>Minimum amperage per connected phase with which the car should be charged</description>
<category>Energy</category>
<state min="0" step="1" pattern="%.0f %unit%" readOnly="false"/>
<item-type>Number:Dimensionless</item-type>
<label>Charging min SoC</label>
<description>Charge immediately with maximum power up to the defined SoC, if the charge mode is not set to "off"</description>
- <category>Batterylevel</category>
+ <category>BatteryLevel</category>
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="false"/>
<autoUpdatePolicy>veto</autoUpdatePolicy>
</channel-type>
<channel-type id="mode">
<item-type>String</item-type>
- <label>Charging mode</label>
+ <label>Charging Mode</label>
<description>Charging mode: "off", "now", "minpv", "pv"</description>
<category>String</category>
<state readOnly="false">
<options>
<option value="off">Off</option>
- <option value="now">Now</option>
+ <option value="now">Fast</option>
<option value="minpv">Min + PV</option>
<option value="pv">Only PV</option>
</options>
</channel-type>
<channel-type id="phases">
<item-type>Number</item-type>
- <label>Charging enabled phases</label>
+ <label>Charging Enabled Phases</label>
<description>The maximum number of phases which can be used</description>
<category>Energy</category>
<state min="0" step="1" max="3" pattern="%d" readOnly="false"/>
<autoUpdatePolicy>veto</autoUpdatePolicy>
</channel-type>
+ <channel-type id="targetEnergy">
+ <item-type>Number:Energy</item-type>
+ <label>Charging Target Energy</label>
+ <description>Amount of energy to charge the vehicle with</description>
+ <category>BatteryLevel</category>
+ <state min="0" pattern="%.0f %unit%" readOnly="false"/>
+ <autoUpdatePolicy>veto</autoUpdatePolicy>
+ </channel-type>
<channel-type id="targetSoC">
<item-type>Number:Dimensionless</item-type>
- <label>Charging target SoC</label>
+ <label>Charging Target SoC</label>
<description>Until which state of charge (SoC) should the vehicle be charged</description>
- <category>Batterylevel</category>
+ <category>BatteryLevel</category>
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="false"/>
<autoUpdatePolicy>veto</autoUpdatePolicy>
</channel-type>
<channel-type id="targetTime">
<item-type>DateTime</item-type>
- <label>Charging target time</label>
+ <label>Charging Target Time</label>
<description>When the target SoC should be reached</description>
<category>Time</category>
<state readOnly="false"/>
</channel-type>
<channel-type id="targetTimeEnabled">
<item-type>Switch</item-type>
- <label>Charging target time enabled</label>
+ <label>Charging Target Time Enabled</label>
<description>Target time for charging enabled</description>
<category>Switch</category>
<state readOnly="false">
</channel-type>
<channel-type id="title">
<item-type>String</item-type>
- <label>Loadpoint title</label>
+ <label>Loadpoint Title</label>
<description>Title of loadpoint</description>
<category>Text</category>
<state readOnly="true"/>
</channel-type>
<channel-type id="vehicleConnected">
<item-type>Switch</item-type>
- <label>Vehicle connected</label>
+ <label>Vehicle Connected</label>
<description>Whether vehicle is connected to loadpoint</description>
<category>Switch</category>
<state readOnly="true">
</channel-type>
<channel-type id="vehicleConnectedDuration">
<item-type>Number:Time</item-type>
- <label>Vehicle connected duration</label>
+ <label>Vehicle Connected Duration</label>
<description>Duration the vehicle is connected to loadpoint</description>
<category>Time</category>
<state pattern="%.1f %unit%" readOnly="true"/>
</channel-type>
<channel-type id="vehicleCapacity">
<item-type>Number:Energy</item-type>
- <label>Vehicle capacity</label>
+ <label>Vehicle Capacity</label>
<description>Capacity of EV battery</description>
<category>Energy</category>
<state pattern="%.0f %unit%" readOnly="true"/>
</channel-type>
<channel-type id="vehicleOdometer">
<item-type>Number:Length</item-type>
- <label>Vehicle odometer</label>
+ <label>Vehicle Odometer</label>
<description>Total distance travelled by EV</description>
<category></category>
<state pattern="%.1f %unit%" readOnly="true"/>
</channel-type>
<channel-type id="vehiclePresent">
<item-type>Switch</item-type>
- <label>Vehicle data access</label>
+ <label>Vehicle Data Access</label>
<description>Whether evcc is able to get data from vehicle</description>
<category>Switch</category>
<state readOnly="true">
</channel-type>
<channel-type id="vehicleRange">
<item-type>Number:Length</item-type>
- <label>Vehicle range</label>
+ <label>Vehicle Range</label>
<description>Battery range for EV</description>
<category></category>
<state pattern="%.1f %unit%" readOnly="true"/>
<item-type>Number:Dimensionless</item-type>
<label>Vehicle SoC</label>
<description>Current State of Charge of EV</description>
- <category>Batterylevel</category>
+ <category>BatteryLevel</category>
<state pattern="%.0f %unit%" readOnly="true"/>
</channel-type>
<channel-type id="vehicleTitle">
<item-type>String</item-type>
- <label>Vehicle title</label>
+ <label>Vehicle Title</label>
<description>Name of EV</description>
<category>Text</category>
<state readOnly="true"/>