| loadpoint\<N\>#title | String | R | Title of loadpoint |
| loadpoint\<N\>#vehicleConnected | Switch | R | Whether vehicle is connected to loadpoint |
| loadpoint\<N\>#vehicleConnectedDuration | Number:Time | R | Duration the vehicle is connected to loadpoint |
-| loadpoint\<N\>#vehicleCapacity | Number:Energy | R | Capacity of EV battery |
| loadpoint\<N\>#vehicleOdometer | Number:Length | R | Total distance travelled by EV |
| loadpoint\<N\>#vehiclePresent | Switch | R | Whether evcc is able to get data from vehicle |
| loadpoint\<N\>#vehicleRange | Number:Length | R | Battery range for EV |
### Vehicle Channels
-Those channels exist per configured vehicle.
-Please note that you have to replace _\<ID\>_ with your vehicle id/name.
+Those channels exist:
-| Channel | Type | Read/Write | Description |
-|----------------------------------|----------------------|------------|--------------------------------------------------------------------------|
-| vehicle\<ID\>#vehicleTitle | String | R | Title of vehicle |
-| vehicle\<ID\>#vehicleMinSoC | Number:Dimensionless | RW | Minimum state of charge (SoC) a vehicle should have |
-| vehicle\<ID\>#vehicleLimitSoC | Number:Dimensionless | RW | Until which state of charge (SoC) should the specific vehicle be charged |
-| vehicle\<ID\>#vehiclePlanEnabled | Switch | RW | Plan for charging enabled |
-| vehicle\<ID\>#vehiclePlanSoC | Number:Dimensionless | RW | Until which state of charge (SoC) should vehicle be charged in plan |
-| vehicle\<ID\>#vehiclePlanTime | DateTime | RW | When the plan SoC should be reached |
+* 1 per configured loadpoint with `chargerFeatureHeating = false`:
+ * These channels point to the heating device that is currently active/connected at/to the loadpoint
+ * Please note that you have to replace _\<N\>_ with your loadpoint id/number
+* 1 per configured vehicle:
+ * Please note that you have to replace _\<ID\>_ with your vehicle id/name
+
+| Channel | Type | Read/Write | Description |
+|----------------------------------------------------|----------------------|------------|--------------------------------------------------------------------------|
+| [loadpoint\<N\>\|vehicle\<ID\]>#vehicleTitle | String | R | Title of vehicle |
+| [loadpoint\<N\>\|vehicle\<ID\]>#vehicleMinSoC | Number:Dimensionless | RW | Minimum state of charge (SoC) a vehicle should have |
+| [loadpoint\<N\>\|vehicle\<ID\]>#vehicleLimitSoC | Number:Dimensionless | RW | Until which state of charge (SoC) should the specific vehicle be charged |
+| [loadpoint\<N\>\|vehicle\<ID\]>#vehicleCapacity | Number:Energy | R | Capacity of EV battery |
+| [loadpoint\<N\>\|vehicle\<ID\]>#vehiclePlanEnabled | Switch | RW | Plan for charging enabled |
+| [loadpoint\<N\>\|vehicle\<ID\]>#vehiclePlanSoC | Number:Dimensionless | RW | Until which state of charge (SoC) should vehicle be charged in plan |
+| [loadpoint\<N\>\|vehicle\<ID\]>#vehiclePlanTime | DateTime | RW | When the plan SoC should be reached |
### Heating Channels
-Those channels exist per configured heating device.
-Please note that you have to replace _\<ID\>_ with your heating device id/name.
+Those channels exist:
+
+* 1 per configured loadpoint with `chargerFeatureHeating = true`:
+ * These channels point to the heating device that is currently active/connected at/to the loadpoint
+ * Please note that you have to replace _\<N\>_ with your loadpoint id/number
+* 1 per configured heating device:
+ * Please note that you have to replace _\<ID\>_ with your heating device id/name
-| Channel | Type | Read/Write | Description |
-|---------------------------------------|--------------------|------------|-----------------------------------------------------------------------|
-| heating\<ID\>#heatingTitle | String | R | Title of heating device |
-| heating\<ID\>#heatingMinTemperature | Number:Temperature | RW | Minimum Temperature a heating device should have |
-| heating\<ID\>#heatingLimitTemperature | Number:Temperature | RW | Until which Temperature should the specific heating device be charged |
-| heating\<ID\>#heatingPlanEnabled | Switch | RW | Plan for charging enabled |
-| heating\<ID\>#heatingPlanTemperature | Number:Temperature | RW | Until which Temperature should heating device be charged in plan |
-| heating\<ID\>#heatingPlanTime | DateTime | RW | When the plan Temperature should be reached |
+| Channel | Type | Read/Write | Description |
+|---------------------------------------------------------|--------------------|------------|-----------------------------------------------------------------------|
+| [loadpoint\<N\>\|heating\<ID\]>#heatingTitle | String | R | Title of heating device |
+| [loadpoint\<N\>\|heating\<ID\]>#heatingMinTemperature | Number:Temperature | RW | Minimum Temperature a heating device should have |
+| [loadpoint\<N\>\|heating\<ID\]>#heatingLimitTemperature | Number:Temperature | RW | Until which Temperature should the specific heating device be charged |
+| [loadpoint\<N\>\|heating\<ID\]>#heatingCapacity | Number:Energy | R | Capacity of heating device |
+| [loadpoint\<N\>\|heating\<ID\]>#heatingPlanEnabled | Switch | RW | Plan for charging enabled |
+| [loadpoint\<N\>\|heating\<ID\]>#heatingPlanTemperature | Number:Temperature | RW | Until which Temperature should heating device be charged in plan |
+| [loadpoint\<N\>\|heating\<ID\]>#heatingPlanTime | DateTime | RW | When the plan Temperature should be reached |
## Full Example
Switch evcc_loadpoint0_chargerFeatureHeating "Feature: Heating [%s]" <switch> {channel="evcc:device:demo:loadpoint0#chargerFeatureHeating"}
Switch evcc_loadpoint0_chargerFeatureIntegratedDevice "Feature: Integrated Device [%s]" <switch> {channel="evcc:device:demo:loadpoint0#chargerFeatureIntegratedDevice"}
-// Vehicle on loadpoint
+// Loadpoint vehicle channels
Switch evcc_loadpoint0_vehicleConnected "Vehicle connected [%s]" <switch> {channel="evcc:device:demo:loadpoint0#vehicleConnected"}
Number:Time evcc_loadpoint0_vehicleConnectedDuration "Vehicle connected duration [%.1f h]" <time> {channel="evcc:device:demo:loadpoint0#vehicleConnectedDuration"}
-Number:Energy evcc_loadpoint0_vehicleCapacity "Vehicle capacity [%.0f kWh]" <batterylevel> {channel="evcc:device:demo:loadpoint0#vehicleCapacity"}
Number:Length evcc_loadpoint0_vehicleOdometer "Vehicle odometer [%.1f km]" {channel="evcc:device:demo:loadpoint0#vehicleOdometer"}
Switch evcc_loadpoint0_vehiclePresent "Vehicle present [%s]" <switch> {channel="evcc:device:demo:loadpoint0#vehiclePresent"}
Number:Length evcc_loadpoint0_vehicleRange "Vehicle Range [%.0f km]" {channel="evcc:device:demo:loadpoint0#vehicleRange"}
Number:Dimensionless evcc_loadpoint0_vehicleSoC "Vehicle SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:loadpoint0#vehicleSoC"}
String evcc_loadpoint0_VehicleName "Vehicle name [%s]" <text> {channel="evcc:device:demo:loadpoint0#vehicleName"}
-// Vehicle
-String evcc_vehicle0_vehicleTitle "Vehicle title [%s]" <text> {channel="evcc:device:demo:vehicle0#vehicleTitle"}
-Number:Dimensionless evcc_vehicle0_vehicleMinSoC "Vehicle minimum SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:vehicle0#vehicleMinSoC"}
-Number:Dimensionless evcc_vehicle0_vehicleLimitSoC "Vehicle limit SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:vehicle0#vehicleLimitSoC"}
-Switch evcc_vehicle0_vehiclePlanEnabled "Vehicle plan enabled [%s]" <switch> {channel="evcc:device:demo:vehicle0#vehiclePlanEnabled"}
-Number:Dimensionless evcc_vehicle0_vehiclePlanSoC "Vehicle plan SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:vehicle0#vehiclePlanSoC"}
-DateTime evcc_vehicle0_vehiclePlanTime "Vehicle plan time [%1$td.%1$tm.%1$tY, %1$tH:%1$tM]" <time> {channel="evcc:device:demo:vehicle0#vehiclePlanTime"}
+// Vehicle on loadpoint
+String evcc_loadpoint0current_vehicleTitle "Vehicle title [%s]" <text> {channel="evcc:device:demo:loadpoint0current#vehicleTitle"}
+Number:Dimensionless evcc_loadpoint0current_vehicleMinSoC "Vehicle minimum SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:loadpoint0current#vehicleMinSoC"}
+Number:Dimensionless evcc_loadpoint0current_vehicleLimitSoC "Vehicle limit SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:loadpoint0current#vehicleLimitSoC"}
+Number:Energy evcc_loadpoint0current_vehicleCapacity "Vehicle capacity [%.0f kWh]" <batterylevel> {channel="evcc:device:demo:loadpoint0current#vehicleCapacity"}
+Switch evcc_loadpoint0current_vehiclePlanEnabled "Vehicle plan enabled [%s]" <switch> {channel="evcc:device:demo:loadpoint0current#vehiclePlanEnabled"}
+Number:Dimensionless evcc_loadpoint0current_vehiclePlanSoC "Vehicle plan SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:loadpoint0current#vehiclePlanSoC"}
+DateTime evcc_loadpoint0current_vehiclePlanTime "Vehicle plan time [%1$td.%1$tm.%1$tY, %1$tH:%1$tM]" <time> {channel="evcc:device:demo:loadpoint0current#vehiclePlanTime"}
```
### Sitemap
Setpoint item=evcc_loadpoint0_phases minValue=1 maxValue=3 step=2
}
Text item=evcc_loadpoint0_vehicleName label="Vehicle" {
- Text item=evcc_loadpoint0_vehicleCapacity
+ Text item=evcc_loadpoint0current_vehicleCapacity
Text item=evcc_loadpoint0_vehicleOdometer
Text item=evcc_loadpoint0_vehicleRange
Text item=evcc_loadpoint0_vehicleSoC
- Text item=evcc_vehicle0_vehicleTitle
- Setpoint item=evcc_vehicle0_vehicleMinSoC minValue=0 maxValue=100 step=5
- Setpoint item=evcc_vehicle0_vehicleLimitSoC minValue=5 maxValue=100 step=5
- Switch item=evcc_vehicle0_vehiclePlanEnabled
- Setpoint item=evcc_vehicle0_vehiclePlanSoC minValue=5 maxValue=100 step=5
- Input item=evcc_vehicle0_vehiclePlanTime
+ Text item=evcc_loadpoint0current_vehicleTitle
+ Setpoint item=evcc_loadpoint0current_vehicleMinSoC minValue=0 maxValue=100 step=5
+ Setpoint item=evcc_loadpoint0current_vehicleLimitSoC minValue=5 maxValue=100 step=5
+ Switch item=evcc_loadpoint0current_vehiclePlanEnabled
+ Setpoint item=evcc_loadpoint0current_vehiclePlanSoC minValue=5 maxValue=100 step=5
+ Input item=evcc_loadpoint0current_vehiclePlanTime
}
}
}
import org.openhab.core.thing.type.ChannelTypeUID;
import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType;
+import org.openhab.core.types.UnDefType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private boolean gridConfigured = false;
private boolean pvConfigured = false;
private Set<String> vehicleFeatureHeating = new HashSet<String>();
+ private Set<String> loadpointFeatureHeating = new HashSet<String>();
+
Map<String, Triple<Boolean, Float, ZonedDateTime>> vehiclePlans = new HashMap<>();
public EvccHandler(Thing thing) {
return;
}
}
- } else if (groupId.startsWith(CHANNEL_GROUP_ID_LOADPOINT)) {
+ } else if (groupId.startsWith(CHANNEL_GROUP_ID_LOADPOINT)
+ && !groupId.endsWith(CHANNEL_GROUP_ID_CURRENT)) {
int loadpoint = Integer.parseInt(groupId.substring(CHANNEL_GROUP_ID_LOADPOINT.length())) + 1;
switch (channelIdWithoutGroup) {
case CHANNEL_LOADPOINT_MODE -> {
return;
}
}
- } else if (groupId.startsWith(CHANNEL_GROUP_ID_VEHICLE)
- || groupId.startsWith(CHANNEL_GROUP_ID_HEATING)) {
- String vehicleName;
- if (groupId.startsWith(CHANNEL_GROUP_ID_VEHICLE)) {
- vehicleName = groupId.substring(CHANNEL_GROUP_ID_VEHICLE.length());
- } else {
- vehicleName = groupId.substring(CHANNEL_GROUP_ID_HEATING.length());
+
+ } else if (groupId.startsWith(CHANNEL_GROUP_ID_VEHICLE) || groupId.startsWith(CHANNEL_GROUP_ID_HEATING)
+ || (groupId.startsWith(CHANNEL_GROUP_ID_LOADPOINT)
+ && groupId.endsWith(CHANNEL_GROUP_ID_CURRENT))) {
+ String vehicleName = null;
+ if (groupId.startsWith(CHANNEL_GROUP_ID_VEHICLE) || groupId.startsWith(CHANNEL_GROUP_ID_HEATING)) {
+ if (groupId.startsWith(CHANNEL_GROUP_ID_VEHICLE)) {
+ vehicleName = groupId.substring(CHANNEL_GROUP_ID_VEHICLE.length());
+ } else {
+ vehicleName = groupId.substring(CHANNEL_GROUP_ID_HEATING.length());
+ }
+ } else if (groupId.startsWith(CHANNEL_GROUP_ID_LOADPOINT)
+ && groupId.endsWith(CHANNEL_GROUP_ID_CURRENT)) {
+ final Result result = this.result;
+ if (result == null) {
+ return;
+ }
+ int loadpointId = Integer.parseInt(groupId.substring(CHANNEL_GROUP_ID_LOADPOINT.length(),
+ groupId.length() - CHANNEL_GROUP_ID_CURRENT.length()));
+ Loadpoint loadpoint = result.getLoadpoints()[loadpointId];
+ vehicleName = loadpoint.getVehicleName();
+ }
+
+ if (vehicleName == null) {
+ return;
}
switch (channelIdWithoutGroup) {
case CHANNEL_VEHICLE_MIN_SOC -> {
if (result == null) {
return;
}
- final String channelGroup = CHANNEL_GROUP_ID_LOADPOINT + loadpointId;
+ final String channelGroup = CHANNEL_GROUP_ID_LOADPOINT + String.valueOf(loadpointId);
Loadpoint loadpoint = result.getLoadpoints()[loadpointId];
boolean chargerFeatureHeating = loadpoint.getChargerFeatureHeating();
+ String vehicleName = loadpoint.getVehicleName();
createChannel(CHANNEL_LOADPOINT_ACTIVE_PHASES, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_ACTIVE_PHASES,
CoreItemFactory.NUMBER);
createChannel(CHANNEL_LOADPOINT_LIMIT_ENERGY, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_LIMIT_ENERGY,
"Number:Energy");
if (chargerFeatureHeating) {
+ if ((vehicleName != null) && !vehicleName.isBlank()) {
+ this.vehicleFeatureHeating.add(vehicleName);
+ }
+ this.loadpointFeatureHeating.add(channelGroup);
+
createChannel(CHANNEL_LOADPOINT_LIMIT_TEMPERATURE, channelGroup,
CHANNEL_TYPE_UID_LOADPOINT_LIMIT_TEMPERATURE, "Number:Temperature");
createChannel(CHANNEL_LOADPOINT_EFFECTIVE_LIMIT_TEMPERATURE, channelGroup,
removeChannel(CHANNEL_LOADPOINT_EFFECTIVE_LIMIT_SOC, channelGroup);
removeChannel(CHANNEL_LOADPOINT_VEHICLE_SOC, channelGroup);
} else {
+ if ((vehicleName != null) && !vehicleName.isBlank()) {
+ this.vehicleFeatureHeating.remove(vehicleName);
+ }
+ this.loadpointFeatureHeating.remove(channelGroup);
+
createChannel(CHANNEL_LOADPOINT_LIMIT_SOC, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_LIMIT_SOC,
"Number:Dimensionless");
createChannel(CHANNEL_LOADPOINT_EFFECTIVE_LIMIT_SOC, channelGroup,
}
createChannel(CHANNEL_LOADPOINT_TITLE, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_TITLE, CoreItemFactory.STRING);
- createChannel(CHANNEL_LOADPOINT_VEHICLE_CAPACITY, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_CAPACITY,
- "Number:Energy");
createChannel(CHANNEL_LOADPOINT_VEHICLE_ODOMETER, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_ODOMETER,
"Number:Length");
createChannel(CHANNEL_LOADPOINT_VEHICLE_PRESENT, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_PRESENT,
removeChannel("targetSoC", channelGroup);
removeChannel("targetTime", channelGroup);
removeChannel("targetTimeEnabled", channelGroup);
+ removeChannel("vehicleCapacity", channelGroup);
+
+ if (vehicleName != null) {
+ createChannelsVehicle(vehicleName, channelGroup);
+ }
}
private void createChannelsVehicle(String vehicleName) {
- String channelGroup;
- if (vehicleFeatureHeating.contains(vehicleName)) {
- channelGroup = CHANNEL_GROUP_ID_HEATING + vehicleName;
+ createChannelsVehicle(vehicleName, null);
+ }
+
+ private void createChannelsVehicle(String vehicleName, @Nullable String loadpointName) {
+ boolean isHeating;
+ if (loadpointName == null) {
+ isHeating = this.vehicleFeatureHeating.contains(vehicleName);
+ } else {
+ isHeating = this.loadpointFeatureHeating.contains(loadpointName);
+ }
+
+ if (isHeating) {
+ String channelGroup;
+ if (loadpointName == null) {
+ channelGroup = CHANNEL_GROUP_ID_HEATING + vehicleName;
+ } else {
+ channelGroup = loadpointName + CHANNEL_GROUP_ID_CURRENT;
+ }
+
createChannel(CHANNEL_HEATING_MIN_TEMPERATURE, channelGroup, CHANNEL_TYPE_UID_HEATING_MIN_TEMPERATURE,
"Number:Temperature");
createChannel(CHANNEL_HEATING_LIMIT_TEMPERATURE, channelGroup, CHANNEL_TYPE_UID_HEATING_LIMIT_TEMPERATURE,
createChannel(CHANNEL_HEATING_PLAN_TEMPERATURE, channelGroup, CHANNEL_TYPE_UID_HEATING_PLAN_TEMPERATURE,
"Number:Temperature");
createChannel(CHANNEL_HEATING_TITLE, channelGroup, CHANNEL_TYPE_UID_HEATING_TITLE, CoreItemFactory.STRING);
+ createChannel(CHANNEL_HEATING_CAPACITY, channelGroup, CHANNEL_TYPE_UID_HEATING_CAPACITY, "Number:Energy");
createChannel(CHANNEL_HEATING_PLAN_TIME, channelGroup, CHANNEL_TYPE_UID_HEATING_PLAN_TIME,
CoreItemFactory.DATETIME);
createChannel(CHANNEL_HEATING_PLAN_ENABLED, channelGroup, CHANNEL_TYPE_UID_HEATING_PLAN_ENABLED,
removeChannel(CHANNEL_VEHICLE_PLAN_TIME, channelGroup);
removeChannel(CHANNEL_VEHICLE_PLAN_ENABLED, channelGroup);
removeChannel(CHANNEL_VEHICLE_PLAN_TIME, channelGroup);
+ removeChannel(CHANNEL_VEHICLE_CAPACITY, channelGroup);
} else {
- channelGroup = CHANNEL_GROUP_ID_VEHICLE + vehicleName;
+ String channelGroup;
+ if (loadpointName == null) {
+ channelGroup = CHANNEL_GROUP_ID_VEHICLE + vehicleName;
+ } else {
+ channelGroup = loadpointName + CHANNEL_GROUP_ID_CURRENT;
+ }
+
createChannel(CHANNEL_VEHICLE_MIN_SOC, channelGroup, CHANNEL_TYPE_UID_VEHICLE_MIN_SOC,
"Number:Dimensionless");
createChannel(CHANNEL_VEHICLE_LIMIT_SOC, channelGroup, CHANNEL_TYPE_UID_VEHICLE_LIMIT_SOC,
createChannel(CHANNEL_VEHICLE_PLAN_SOC, channelGroup, CHANNEL_TYPE_UID_VEHICLE_PLAN_SOC,
"Number:Dimensionless");
createChannel(CHANNEL_VEHICLE_TITLE, channelGroup, CHANNEL_TYPE_UID_VEHICLE_TITLE, CoreItemFactory.STRING);
+ createChannel(CHANNEL_VEHICLE_CAPACITY, channelGroup, CHANNEL_TYPE_UID_VEHICLE_CAPACITY, "Number:Energy");
createChannel(CHANNEL_VEHICLE_PLAN_TIME, channelGroup, CHANNEL_TYPE_UID_VEHICLE_PLAN_TIME,
CoreItemFactory.DATETIME);
createChannel(CHANNEL_VEHICLE_PLAN_ENABLED, channelGroup, CHANNEL_TYPE_UID_VEHICLE_PLAN_ENABLED,
removeChannel(CHANNEL_HEATING_PLAN_TIME, channelGroup);
removeChannel(CHANNEL_HEATING_PLAN_ENABLED, channelGroup);
removeChannel(CHANNEL_HEATING_PLAN_TIME, channelGroup);
+ removeChannel(CHANNEL_HEATING_CAPACITY, channelGroup);
}
}
updateState(channel, new StringType(vehicleName));
if (chargerFeatureHeating) {
- vehicleFeatureHeating.add(vehicleName);
-
float limitSoC = loadpoint.getLimitSoC();
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_LIMIT_TEMPERATURE);
updateState(channel, new QuantityType<>(limitSoC, SIUnits.CELSIUS));
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_VEHICLE_TEMPERATURE);
updateState(channel, new QuantityType<>(vehicleSoC, SIUnits.CELSIUS));
} else {
- vehicleFeatureHeating.remove(vehicleName);
-
float limitSoC = loadpoint.getLimitSoC();
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_LIMIT_SOC);
updateState(channel, new QuantityType<>(limitSoC, Units.PERCENT));
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_TITLE);
updateState(channel, new StringType(title));
- float vehicleCapacity = loadpoint.getVehicleCapacity();
- channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_VEHICLE_CAPACITY);
- updateState(channel, new QuantityType<>(vehicleCapacity, Units.KILOWATT_HOUR));
-
float vehicleOdometer = loadpoint.getVehicleOdometer();
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_VEHICLE_ODOMETER);
updateState(channel, new QuantityType<>(vehicleOdometer, MetricPrefix.KILO(SIUnits.METRE)));
float vehicleRange = loadpoint.getVehicleRange();
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_VEHICLE_RANGE);
updateState(channel, new QuantityType<>(vehicleRange, MetricPrefix.KILO(SIUnits.METRE)));
+
+ if (vehicleName != null) {
+ updateChannelsVehicle(vehicleName, channelGroup);
+ }
}
private void updateChannelsVehicle(String vehicleName) {
+ updateChannelsVehicle(vehicleName, null);
+ }
+
+ private void updateChannelsVehicle(String vehicleName, @Nullable String loadpointName) {
final Result result = this.result;
if (result == null) {
return;
}
final ThingUID uid = getThing().getUID();
- Vehicle vehicle = result.getVehicles().get(vehicleName);
- final String channelGroup;
- boolean vehicleFeatureHeating = this.vehicleFeatureHeating.contains(vehicleName);
- if (vehicleFeatureHeating) {
- channelGroup = CHANNEL_GROUP_ID_HEATING + vehicleName;
+ boolean isHeating;
+ if (loadpointName == null) {
+ isHeating = this.vehicleFeatureHeating.contains(vehicleName);
+ } else {
+ isHeating = this.loadpointFeatureHeating.contains(loadpointName);
+ }
+ Vehicle vehicle = null;
+ if (!vehicleName.isBlank()) {
+ vehicle = result.getVehicles().get(vehicleName);
+ }
- float minSoC = vehicle.getMinSoC();
- ChannelUID channel = new ChannelUID(uid, channelGroup, CHANNEL_HEATING_MIN_TEMPERATURE);
- updateState(channel, new QuantityType<>(minSoC, SIUnits.CELSIUS));
+ String channelGroup;
+ if (isHeating) {
+ if (loadpointName == null) {
+ channelGroup = CHANNEL_GROUP_ID_HEATING + vehicleName;
+ } else {
+ channelGroup = loadpointName + CHANNEL_GROUP_ID_CURRENT;
+ }
- float limitSoC = vehicle.getLimitSoC();
- channel = new ChannelUID(uid, channelGroup, CHANNEL_HEATING_LIMIT_TEMPERATURE);
- updateState(channel, new QuantityType<>(limitSoC, SIUnits.CELSIUS));
+ if (vehicle == null) {
+ ChannelUID channel = new ChannelUID(uid, channelGroup, CHANNEL_HEATING_MIN_TEMPERATURE);
+ updateState(channel, UnDefType.UNDEF);
- String title = vehicle.getTitle();
- channel = new ChannelUID(uid, channelGroup, CHANNEL_HEATING_TITLE);
- updateState(channel, new StringType(title));
- } else {
- channelGroup = CHANNEL_GROUP_ID_VEHICLE + vehicleName;
+ channel = new ChannelUID(uid, channelGroup, CHANNEL_HEATING_LIMIT_TEMPERATURE);
+ updateState(channel, UnDefType.UNDEF);
- float minSoC = vehicle.getMinSoC();
- ChannelUID channel = new ChannelUID(uid, channelGroup, CHANNEL_VEHICLE_MIN_SOC);
- updateState(channel, new QuantityType<>(minSoC, Units.PERCENT));
+ channel = new ChannelUID(uid, channelGroup, CHANNEL_HEATING_TITLE);
+ updateState(channel, UnDefType.UNDEF);
- float limitSoC = vehicle.getLimitSoC();
- channel = new ChannelUID(uid, channelGroup, CHANNEL_VEHICLE_LIMIT_SOC);
- updateState(channel, new QuantityType<>(limitSoC, Units.PERCENT));
+ channel = new ChannelUID(uid, channelGroup, CHANNEL_HEATING_CAPACITY);
+ updateState(channel, UnDefType.UNDEF);
+ } else {
+ float minSoC = vehicle.getMinSoC();
+ ChannelUID channel = new ChannelUID(uid, channelGroup, CHANNEL_HEATING_MIN_TEMPERATURE);
+ updateState(channel, new QuantityType<>(minSoC, SIUnits.CELSIUS));
+
+ float limitSoC = vehicle.getLimitSoC();
+ channel = new ChannelUID(uid, channelGroup, CHANNEL_HEATING_LIMIT_TEMPERATURE);
+ updateState(channel, new QuantityType<>(limitSoC, SIUnits.CELSIUS));
- String title = vehicle.getTitle();
- channel = new ChannelUID(uid, channelGroup, CHANNEL_HEATING_TITLE);
- updateState(channel, new StringType(title));
+ String title = vehicle.getTitle();
+ channel = new ChannelUID(uid, channelGroup, CHANNEL_HEATING_TITLE);
+ updateState(channel, new StringType(title));
+
+ float capacity = vehicle.getCapacity();
+ channel = new ChannelUID(uid, channelGroup, CHANNEL_HEATING_CAPACITY);
+ updateState(channel, new QuantityType<>(capacity, Units.KILOWATT_HOUR));
+ }
+ } else {
+ if (loadpointName == null) {
+ channelGroup = CHANNEL_GROUP_ID_VEHICLE + vehicleName;
+ } else {
+ channelGroup = loadpointName + CHANNEL_GROUP_ID_CURRENT;
+ }
+ if (vehicle == null) {
+ ChannelUID channel = new ChannelUID(uid, channelGroup, CHANNEL_VEHICLE_MIN_SOC);
+ updateState(channel, UnDefType.UNDEF);
+
+ channel = new ChannelUID(uid, channelGroup, CHANNEL_VEHICLE_LIMIT_SOC);
+ updateState(channel, UnDefType.UNDEF);
+
+ channel = new ChannelUID(uid, channelGroup, CHANNEL_VEHICLE_TITLE);
+ updateState(channel, UnDefType.UNDEF);
+
+ channel = new ChannelUID(uid, channelGroup, CHANNEL_VEHICLE_CAPACITY);
+ updateState(channel, UnDefType.UNDEF);
+ } else {
+ float minSoC = vehicle.getMinSoC();
+ ChannelUID channel = new ChannelUID(uid, channelGroup, CHANNEL_VEHICLE_MIN_SOC);
+ updateState(channel, new QuantityType<>(minSoC, Units.PERCENT));
+
+ float limitSoC = vehicle.getLimitSoC();
+ channel = new ChannelUID(uid, channelGroup, CHANNEL_VEHICLE_LIMIT_SOC);
+ updateState(channel, new QuantityType<>(limitSoC, Units.PERCENT));
+
+ String title = vehicle.getTitle();
+ channel = new ChannelUID(uid, channelGroup, CHANNEL_VEHICLE_TITLE);
+ updateState(channel, new StringType(title));
+
+ float capacity = vehicle.getCapacity();
+ channel = new ChannelUID(uid, channelGroup, CHANNEL_VEHICLE_CAPACITY);
+ updateState(channel, new QuantityType<>(capacity, Units.KILOWATT_HOUR));
+ }
}
- Plan plan = vehicle.getPlan();
+ Plan plan = null;
+ if (vehicle != null) {
+ vehicle.getPlan();
+ }
if (plan == null && vehiclePlans.get(vehicleName) == null) {
vehiclePlans.put(vehicleName, new Triple<>(false, 100f, ZonedDateTime.now().plusHours(12)));
} else if (plan != null) {
vehiclePlans.put(vehicleName, new Triple<>(true, plan.getSoC(), ZonedDateTime.parse(plan.getTime())));
}
- updateVehiclePlanChannel(vehicleName, uid, channelGroup, vehicleFeatureHeating);
+ updateVehiclePlanChannel(uid, vehicleName, channelGroup, isHeating);
}
- private void updateVehiclePlanChannel(String vehicleName, ThingUID uid, String channelGroup,
- boolean vehicleFeatureHeating) {
+ private void updateVehiclePlanChannel(ThingUID uid, String vehicleName, String channelGroup, boolean isHeating) {
Triple<Boolean, Float, ZonedDateTime> planValues = vehiclePlans.get(vehicleName);
- if (vehicleFeatureHeating) {
+ if (isHeating) {
ChannelUID channel = new ChannelUID(uid, channelGroup, CHANNEL_HEATING_PLAN_ENABLED);
updateState(channel, planValues.getLeft() ? OnOffType.ON : OnOffType.OFF);
channel = new ChannelUID(uid, channelGroup, CHANNEL_HEATING_PLAN_TEMPERATURE);
<channel-groups>
<channel-group id="general" typeId="general"/>
- <channel-group id="loadpoint0" typeId="loadpoint"/>
- <channel-group id="loadpoint1" typeId="loadpoint"/>
- <channel-group id="loadpoint2" typeId="loadpoint"/>
- <channel-group id="loadpoint3" typeId="loadpoint"/>
- <channel-group id="loadpoint4" typeId="loadpoint"/>
- <channel-group id="loadpoint5" typeId="loadpoint"/>
- <channel-group id="loadpoint6" typeId="loadpoint"/>
- <channel-group id="loadpoint7" typeId="loadpoint"/>
- <channel-group id="loadpoint8" typeId="loadpoint"/>
- <channel-group id="loadpoint9" typeId="loadpoint"/>
+ <channel-group id="loadpoint0" typeId="loadpoint0"/>
+ <channel-group id="loadpoint1" typeId="loadpoint1"/>
+ <channel-group id="loadpoint2" typeId="loadpoint2"/>
+ <channel-group id="loadpoint3" typeId="loadpoint3"/>
+ <channel-group id="loadpoint4" typeId="loadpoint4"/>
+ <channel-group id="loadpoint5" typeId="loadpoint5"/>
+ <channel-group id="loadpoint6" typeId="loadpoint6"/>
+ <channel-group id="loadpoint7" typeId="loadpoint7"/>
+ <channel-group id="loadpoint8" typeId="loadpoint8"/>
+ <channel-group id="loadpoint9" typeId="loadpoint9"/>
+ <channel-group id="loadpoint0current" typeId="loadpoint0current"/>
+ <channel-group id="loadpoint1current" typeId="loadpoint1current"/>
+ <channel-group id="loadpoint2current" typeId="loadpoint2current"/>
+ <channel-group id="loadpoint3current" typeId="loadpoint3current"/>
+ <channel-group id="loadpoint4current" typeId="loadpoint4current"/>
+ <channel-group id="loadpoint5current" typeId="loadpoint5current"/>
+ <channel-group id="loadpoint6current" typeId="loadpoint6current"/>
+ <channel-group id="loadpoint7current" typeId="loadpoint7current"/>
+ <channel-group id="loadpoint8current" typeId="loadpoint8current"/>
+ <channel-group id="loadpoint9current" typeId="loadpoint9current"/>
</channel-groups>
<config-description>
<channel-group-type id="general">
<label>General Data</label>
</channel-group-type>
- <channel-group-type id="loadpoint">
- <label>Loadpoint</label>
+ <channel-group-type id="loadpoint0">
+ <label>Loadpoint 0</label>
+ </channel-group-type>
+ <channel-group-type id="loadpoint1">
+ <label>Loadpoint 1</label>
+ </channel-group-type>
+ <channel-group-type id="loadpoint2">
+ <label>Loadpoint 2</label>
+ </channel-group-type>
+ <channel-group-type id="loadpoint3">
+ <label>Loadpoint 3</label>
+ </channel-group-type>
+ <channel-group-type id="loadpoint4">
+ <label>Loadpoint 4</label>
+ </channel-group-type>
+ <channel-group-type id="loadpoint5">
+ <label>Loadpoint 5</label>
+ </channel-group-type>
+ <channel-group-type id="loadpoint6">
+ <label>Loadpoint 6</label>
+ </channel-group-type>
+ <channel-group-type id="loadpoint7">
+ <label>Loadpoint 7</label>
+ </channel-group-type>
+ <channel-group-type id="loadpoint8">
+ <label>Loadpoint 8</label>
+ </channel-group-type>
+ <channel-group-type id="loadpoint9">
+ <label>Loadpoint 9</label>
+ </channel-group-type>
+ <channel-group-type id="loadpoint0current">
+ <label>Loadpoint 0: Current</label>
+ </channel-group-type>
+ <channel-group-type id="loadpoint1current">
+ <label>Loadpoint 1: Current</label>
+ </channel-group-type>
+ <channel-group-type id="loadpoint2current">
+ <label>Loadpoint 2: Current</label>
+ </channel-group-type>
+ <channel-group-type id="loadpoint3current">
+ <label>Loadpoint 3: Current</label>
+ </channel-group-type>
+ <channel-group-type id="loadpoint4current">
+ <label>Loadpoint 4: Current</label>
+ </channel-group-type>
+ <channel-group-type id="loadpoint5current">
+ <label>Loadpoint 5: Current</label>
+ </channel-group-type>
+ <channel-group-type id="loadpoint6current">
+ <label>Loadpoint 6: Current</label>
+ </channel-group-type>
+ <channel-group-type id="loadpoint7current">
+ <label>Loadpoint 7: Current</label>
+ </channel-group-type>
+ <channel-group-type id="loadpoint8current">
+ <label>Loadpoint 8: Current</label>
+ </channel-group-type>
+ <channel-group-type id="loadpoint9current">
+ <label>Loadpoint 9: Current</label>
</channel-group-type>
<!-- Units and description on: https://docs.evcc.io/docs/reference/configuration/messaging/#msg -->
<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>
- <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>
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="false"/>
<autoUpdatePolicy>veto</autoUpdatePolicy>
</channel-type>
+ <channel-type id="vehicleCapacity">
+ <item-type>Number:Energy</item-type>
+ <label>Vehicle Capacity</label>
+ <description>Capacity of EV battery</description>
+ <category>Energy</category>
+ <state pattern="%.0f %unit%" readOnly="true"/>
+ </channel-type>
+ <channel-type id="heatingCapacity">
+ <item-type>Number:Energy</item-type>
+ <label>Heating Capacity</label>
+ <description>Capacity of heating device</description>
+ <category>Energy</category>
+ <state pattern="%.0f %unit%" readOnly="true"/>
+ </channel-type>
<channel-type id="vehiclePlanEnabled">
<item-type>Switch</item-type>
<label>Vehicle Plan Enabled</label>