mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-25 14:55:55 +01:00
[evcc] Adjust to evcc version 0.123.1 (#16114)
* updated url of setTargetEnergy and setTargetSoC to match evcc version 0.123.1 * removed minSoc from Loadpoint (since evcc 0.123.0 part of vehicle) * renamed from targetEnergy to limitEnergy to match new evcc version * renamed from targetSoC to limitSoC to match new evcc version * plementation of vehicle object to match new evcc version 0.123.1 -> new implementation of minSoC and plans (served by new api) Signed-off-by: Luca Arnecke <luca@arnecke.name> Signed-off-by: Florian Hotze <florianh_dev@icloud.com> Signed-off-by: Michael Weger <weger.michael@gmx.net> Co-authored-by: Florian Hotze <florianh_dev@icloud.com> Co-authored-by: Michael Weger <weger.michael@gmx.net> Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
This commit is contained in:
parent
bd97a633f9
commit
1521e25ab9
@ -1,7 +1,7 @@
|
||||
# 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.117.0](https://github.com/evcc-io/evcc/releases/tag/0.117.0) or newer and is tested with this version.
|
||||
The binding requires evcc [version 0.123.1](https://github.com/evcc-io/evcc/releases/tag/0.123.1) or newer and is tested with this version.
|
||||
|
||||
You can easily install and upgrade evcc on openHABian using `sudo openhabian-config`.
|
||||
|
||||
@ -38,50 +38,66 @@ Default value for _refreshInterval_ is 60 seconds.
|
||||
Those channels exist only once.
|
||||
Please note that some of them are only available when evcc is properly configured.
|
||||
|
||||
| Channel | Type | Read/Write | Description |
|
||||
|----------------------------|----------------------|------------|--------------------------------------------------------------------------------------------------------------|
|
||||
| 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 | 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. |
|
||||
| Channel | Type | Read/Write | Description |
|
||||
|---------------------------------|----------------------|------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 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#batteryDischargeControl | Switch | RW | Enable or disable battery discharge control |
|
||||
| general#batteryMode | String | R | Current battery mode |
|
||||
| general#prioritySoC | Number:Dimensionless | RW | State of State of Charge for which the battery has priority over charging the ev when charging mode is "pv" |
|
||||
| general#bufferSoC | Number:Dimensionless | RW | Until this State of Charge the discharging of a house battery is allowed in "pv" mode, when there is insufficient solar surplus (below the minimum charging power) |
|
||||
| general#bufferStartSoC | Number:Dimensionless | RW | State of Charge for which a charging session in "pv" mode is started, even if there is insufficient solar surplus |
|
||||
| general#residualPower | Number:Power | RW | Target operating point of the surplus regulation at the grid connection (grid meter) |
|
||||
| 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 |
|
||||
|
||||
### Loadpoint channels
|
||||
|
||||
Those channels exist per configured loadpoint.
|
||||
Please note that you have to replace _N_ with your loadpoint number.
|
||||
|
||||
| Channel | Type | Read/Write | Description |
|
||||
|-------------------------------------|------------------------|------------|-----------------------------------------------------------------------------------------------------|
|
||||
| loadpointN#activePhases | Number | R | Current number of active phases while charging |
|
||||
| loadpointN#chargeCurrent | Number:ElectricCurrent | R | Current amperage per connected phase while charging |
|
||||
| loadpointN#chargeDuration | Number:Time | R | Charging duration |
|
||||
| loadpointN#chargeRemainingDuration | Number:Time | R | Remaining duration until target SoC is reached |
|
||||
| loadpointN#chargeRemainingEnergy | Number:Energy | R | Remaining energy until target SoC is reached |
|
||||
| loadpointN#chargePower | Number:Power | R | Current power of charging |
|
||||
| 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#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 |
|
||||
| loadpointN#title | String | R | Title of loadpoint |
|
||||
| loadpointN#vehicleConnected | Switch | R | Whether vehicle is connected to loadpoint |
|
||||
| loadpointN#vehicleConnectedDuration | Number:Time | R | Duration the vehicle is connected to loadpoint |
|
||||
| loadpointN#vehicleCapacity | Number:Energy | R | Capacity of EV battery |
|
||||
| loadpointN#vehicleOdometer | Number:Length | R | Total distance travelled by EV |
|
||||
| loadpointN#vehiclePresent | Switch | R | Whether evcc is able to get data from vehicle |
|
||||
| loadpointN#vehicleRange | Number:Length | R | Battery range for EV |
|
||||
| loadpointN#vehicleSoC | Number:Dimensionless | R | Current State of Charge of EV |
|
||||
| loadpointN#vehicleTitle | String | R | Name of EV |
|
||||
| Channel | Type | Read/Write | Description |
|
||||
|-------------------------------------|------------------------|------------|-------------------------------------------------------------------------------------------------------------------|
|
||||
| loadpointN#activePhases | Number | R | Current number of active phases while charging |
|
||||
| loadpointN#chargeCurrent | Number:ElectricCurrent | R | Current amperage per connected phase while charging |
|
||||
| loadpointN#chargeDuration | Number:Time | R | Charging duration |
|
||||
| loadpointN#chargeRemainingDuration | Number:Time | R | Remaining duration until limit SoC is reached |
|
||||
| loadpointN#chargeRemainingEnergy | Number:Energy | R | Remaining energy until limit SoC is reached |
|
||||
| loadpointN#chargePower | Number:Power | R | Current power of charging |
|
||||
| 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#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#mode | String | RW | Charging mode: "off", "now", "minpv", "pv" |
|
||||
| loadpointN#phases | Number | RW | The maximum number of phases which can be used |
|
||||
| loadpointN#limitEnergy | Number:Energy | RW | Amount of energy to charge the vehicle with |
|
||||
| loadpointN#limitSoC | Number:Dimensionless | RW | Until which state of charge (SoC) should the vehicle be charged |
|
||||
| loadpointN#title | String | R | Title of loadpoint |
|
||||
| loadpointN#vehicleConnected | Switch | R | Whether vehicle is connected to loadpoint |
|
||||
| loadpointN#vehicleConnectedDuration | Number:Time | R | Duration the vehicle is connected to loadpoint |
|
||||
| loadpointN#vehicleCapacity | Number:Energy | R | Capacity of EV battery |
|
||||
| loadpointN#vehicleOdometer | Number:Length | R | Total distance travelled by EV |
|
||||
| loadpointN#vehiclePresent | Switch | R | Whether evcc is able to get data from vehicle |
|
||||
| loadpointN#vehicleRange | Number:Length | R | Battery range for EV |
|
||||
| loadpointN#vehicleSoC | Number:Dimensionless | R | Current State of Charge of EV |
|
||||
| loadpointN#vehicleName | String | R | The unique identifier of the EV used in the evcc configuration (containing no whitespaces nor special characters) |
|
||||
|
||||
### Vehicle channels
|
||||
|
||||
Those channels exist per configured vehicle.
|
||||
Please note that you have to replace _ID_ with your vehicle id/name.
|
||||
|
||||
| Channel | Type | Read/Write | Description |
|
||||
|------------------------------|----------------------|------------|--------------------------------------------------------------------------|
|
||||
| vehicleID#vehicleTitle | String | R | Title of vehicle |
|
||||
| vehicleID#vehicleMinSoC | Number:Dimensionless | RW | Minimum state of charge (SoC) a vehicle should have |
|
||||
| vehicleID#vehicleLimitSoC | Number:Dimensionless | RW | Until which state of charge (SoC) should the specific vehicle be charged |
|
||||
| vehicleID#vehiclePlanEnabled | Switch | RW | Plan for charging enabled |
|
||||
| vehicleID#vehiclePlanSoC | Number:Dimensionless | RW | Until which state of charge (SoC) should vehicle be charged in plan |
|
||||
| vehicleID#vehiclePlanTime | DateTime | RW | When the plan SoC should be reached |
|
||||
|
||||
## Full Example
|
||||
|
||||
@ -95,43 +111,53 @@ Thing evcc:device:demo "evcc Demo" [url="https://demo.evcc.io", refreshInterval=
|
||||
|
||||
```java
|
||||
// General
|
||||
Number:General evcc_batteryCapacity "Battery Capacity [%.0f kWH]" <energy> {channel="evcc:device:demo:general#batteryCapacity"}
|
||||
Number:Power evcc_batteryPower "Battery Power [%.1f kW]" <energy> {channel="evcc:device:demo:general#batteryPower"}
|
||||
Number:Dimensionless evcc_batterySoC "Battery SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:general#batterySoC"}
|
||||
Number:Dimensionless evcc_batteryPrioritySoC "Battery Priority SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:general#batteryPrioritySoC"}
|
||||
Number:Power evcc_gridPower "Grid Power [%.1f kW]" <energy> {channel="evcc:device:demo:general#gridPower"}
|
||||
Number:Power evcc_homePower "Home Power [%.1f kW]" <energy> {channel="evcc:device:demo:general#homePower"}
|
||||
Number:Power evcc_pvPower "PV Power [%.1f kW]" <energy> {channel="evcc:device:demo:general#pvPower"}
|
||||
Number:Energy evcc_batteryCapacity "Battery Capacity [%.0f kWh]" <energy> {channel="evcc:device:demo:general#batteryCapacity"}
|
||||
Number:Power evcc_batteryPower "Battery Power [%.1f kW]" <energy> {channel="evcc:device:demo:general#batteryPower"}
|
||||
Number:Dimensionless evcc_batterySoC "Battery SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:general#batterySoC"}
|
||||
Switch evcc_batteryDischargeControl "Battery Discharge Control [%s]" <switch> {channel="evcc:device:demo:general#batteryDischargeControl"}
|
||||
String evcc_batteryMode "Battery Mode [%s]" <battery> {channel="evcc:device:demo:general#batteryMode"}
|
||||
Number:Dimensionless evcc_prioritySoC "Battery Priority SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:general#prioritySoC"}
|
||||
Number:Dimensionless evcc_bufferSoC "Battery Buffer SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:general#bufferSoC"}
|
||||
Number:Dimensionless evcc_bufferStartSoC "Battery Buffer Start SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:general#bufferStartSoC"}
|
||||
Number:Power evcc_residualPower "Grid Residual Power [%.1f kW]" <energy> {channel="evcc:device:demo:general#residualPower"}
|
||||
Number:Power evcc_gridPower "Grid Power [%.1f kW]" <energy> {channel="evcc:device:demo:general#gridPower"}
|
||||
Number:Power evcc_homePower "Home Power [%.1f kW]" <energy> {channel="evcc:device:demo:general#homePower"}
|
||||
Number:Power evcc_pvPower "PV Power [%.1f kW]" <energy> {channel="evcc:device:demo:general#pvPower"}
|
||||
|
||||
// Loadpoint
|
||||
Number evcc_loadpoint0_activePhases "Active Phases [%d]" {channel="evcc:device:demo:loadpoint0#activePhases"}
|
||||
Number:ElectricCurrent evcc_loadpoint0_chargeCurrent "Charging current [%.0f A]" <energy> {channel="evcc:device:demo:loadpoint0#chargeCurrent"}
|
||||
Number:Time evcc_loadpoint0_chargeDuration "Charging duration [%1$tH:%1$tM]" <time> {channel="evcc:device:demo:loadpoint0#chargeDuration"}
|
||||
Number:Time evcc_loadpoint0_chargeRemainingDuration "Charging remaining duration [%1$tH:%1$tM]" <time> {channel="evcc:device:demo:loadpoint0#chargeRemainingDuration"}
|
||||
Number:Energy evcc_loadpoint0_chargeRemainingEnergy "Charging remaining energy [%.1f kWh]" <energy> {channel="evcc:device:demo:loadpoint0#chargeRemainingEnergy"}
|
||||
Number:Power evcc_loadpoint0_chargePower "Charging power [%.1f kW]" <energy> {channel="evcc:device:demo:loadpoint0#chargePower"}
|
||||
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"}
|
||||
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"}
|
||||
String evcc_loadpoint0_title "Loadpoint title [%s]" <text> {channel="evcc:device:demo:loadpoint0#title"}
|
||||
Number evcc_loadpoint0_activePhases "Active Phases [%d]" {channel="evcc:device:demo:loadpoint0#activePhases"}
|
||||
Number:ElectricCurrent evcc_loadpoint0_chargeCurrent "Charging current [%.0f A]" <energy> {channel="evcc:device:demo:loadpoint0#chargeCurrent"}
|
||||
Number:Time evcc_loadpoint0_chargeDuration "Charging duration [%1$tH:%1$tM]" <time> {channel="evcc:device:demo:loadpoint0#chargeDuration"}
|
||||
Number:Time evcc_loadpoint0_chargeRemainingDuration "Charging remaining duration [%1$tH:%1$tM]" <time> {channel="evcc:device:demo:loadpoint0#chargeRemainingDuration"}
|
||||
Number:Energy evcc_loadpoint0_chargeRemainingEnergy "Charging remaining energy [%.1f kWh]" <energy> {channel="evcc:device:demo:loadpoint0#chargeRemainingEnergy"}
|
||||
Number:Power evcc_loadpoint0_chargePower "Charging power [%.1f kW]" <energy> {channel="evcc:device:demo:loadpoint0#chargePower"}
|
||||
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"}
|
||||
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"}
|
||||
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_limitEnergy "Limit energy [%.1f kWh]" <batterylevel> {channel="evcc:device:demo:loadpoint0#limitEnergy"}
|
||||
Number:Dimensionless evcc_loadpoint0_limitSoC "Limit SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:loadpoint0#limitSoC"}
|
||||
String evcc_loadpoint0_title "Loadpoint title [%s]" <text> {channel="evcc:device:demo:loadpoint0#title"}
|
||||
// Vehicle on loadpoint
|
||||
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#vehicleTitle"}
|
||||
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:loadpoint0#targetTime"}
|
||||
```
|
||||
|
||||
### Sitemap
|
||||
@ -158,8 +184,8 @@ sitemap evcc label="evcc Demo" {
|
||||
}
|
||||
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_limitEnergy minValue=5 maxValue=100 step=5
|
||||
Setpoint item=evcc_loadpoint0_limitSoC 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
|
||||
Setpoint item=evcc_loadpoint0_minSoC minValue=0 maxValue=100 step=5
|
||||
@ -170,6 +196,12 @@ sitemap evcc label="evcc Demo" {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import org.openhab.core.thing.type.ChannelTypeUID;
|
||||
* used across the whole binding.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
* @author Luca Arnecke - Update to evcc version 0.123.1
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EvccBindingConstants {
|
||||
@ -28,12 +29,19 @@ public class EvccBindingConstants {
|
||||
private static final String BINDING_ID = "evcc";
|
||||
|
||||
public static final String CHANNEL_GROUP_ID_GENERAL = "general";
|
||||
public static final String CHANNEL_GROUP_ID_LOADPOINT = "loadpoint";
|
||||
public static final String CHANNEL_GROUP_ID_VEHICLE = "vehicle";
|
||||
|
||||
// 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_BATTERY_SOC = "batterySoC";
|
||||
public static final String CHANNEL_BATTERY_PRIORITY_SOC = "batteryPrioritySoC";
|
||||
public static final String CHANNEL_BATTERY_DISCHARGE_CONTROL = "batteryDischargeControl";
|
||||
public static final String CHANNEL_BATTERY_MODE = "batteryMode";
|
||||
public static final String CHANNEL_PRIORITY_SOC = "prioritySoC";
|
||||
public static final String CHANNEL_BUFFER_SOC = "bufferSoC";
|
||||
public static final String CHANNEL_BUFFER_START_SOC = "bufferStartSoC";
|
||||
public static final String CHANNEL_RESIDUAL_POWER = "residualPower";
|
||||
public static final String CHANNEL_GRID_POWER = "gridPower";
|
||||
public static final String CHANNEL_HOME_POWER = "homePower";
|
||||
public static final String CHANNEL_PV_POWER = "pvPower";
|
||||
@ -47,27 +55,26 @@ public class EvccBindingConstants {
|
||||
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_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";
|
||||
/**
|
||||
* Whether a target time is set on loadpoint.
|
||||
*/
|
||||
public static final String CHANNEL_LOADPOINT_TARGET_TIME_ENABLED = "targetTimeEnabled";
|
||||
public static final String CHANNEL_LOADPOINT_LIMIT_ENERGY = "limitEnergy";
|
||||
public static final String CHANNEL_LOADPOINT_LIMIT_SOC = "limitSoC";
|
||||
public static final String CHANNEL_LOADPOINT_TITLE = "title";
|
||||
public static final String CHANNEL_LOADPOINT_VEHICLE_CAPACITY = "vehicleCapacity";
|
||||
public static final String CHANNEL_LOADPOINT_VEHICLE_ODOMETER = "vehicleOdometer";
|
||||
public static final String CHANNEL_LOADPOINT_VEHICLE_PRESENT = "vehiclePresent";
|
||||
public static final String CHANNEL_LOADPOINT_VEHICLE_RANGE = "vehicleRange";
|
||||
public static final String CHANNEL_LOADPOINT_VEHICLE_SOC = "vehicleSoC";
|
||||
public static final String CHANNEL_LOADPOINT_VEHICLE_TITLE = "vehicleTitle";
|
||||
public static final String CHANNEL_LOADPOINT_VEHICLE_NAME = "vehicleName";
|
||||
public static final String CHANNEL_VEHICLE_TITLE = "vehicleTitle";
|
||||
public static final String CHANNEL_VEHICLE_MIN_SOC = "vehicleMinSoC";
|
||||
public static final String CHANNEL_VEHICLE_LIMIT_SOC = "vehicleLimitSoC";
|
||||
public static final String CHANNEL_VEHICLE_PLAN_ENABLED = "vehiclePlanEnabled";
|
||||
public static final String CHANNEL_VEHICLE_PLAN_SOC = "vehiclePlanSoC";
|
||||
public static final String CHANNEL_VEHICLE_PLAN_TIME = "vehiclePlanTime";
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
public static final ThingTypeUID THING_TYPE_DEVICE = new ThingTypeUID(BINDING_ID, "device");
|
||||
@ -79,8 +86,17 @@ public class EvccBindingConstants {
|
||||
CHANNEL_BATTERY_POWER);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_BATTERY_SOC = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_BATTERY_SOC);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_BATTERY_PRIORITY_SOC = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_BATTERY_PRIORITY_SOC);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_BATTERY_DISCHARGE_CONTROL = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_BATTERY_DISCHARGE_CONTROL);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_BATTERY_MODE = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_BATTERY_MODE);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_PRIORITY_SOC = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_PRIORITY_SOC);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_BUFFER_SOC = new ChannelTypeUID(BINDING_ID, CHANNEL_BUFFER_SOC);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_BUFFER_START_SOC = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_BUFFER_START_SOC);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_RESIDUAL_POWER = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_RESIDUAL_POWER);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_GRID_POWER = new ChannelTypeUID(BINDING_ID, CHANNEL_GRID_POWER);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_HOME_POWER = new ChannelTypeUID(BINDING_ID, CHANNEL_HOME_POWER);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_PV_POWER = new ChannelTypeUID(BINDING_ID, CHANNEL_PV_POWER);
|
||||
@ -110,20 +126,14 @@ public class EvccBindingConstants {
|
||||
CHANNEL_LOADPOINT_MAX_CURRENT);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_MIN_CURRENT = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_MIN_CURRENT);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_MIN_SOC = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_MIN_SOC);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_MODE = 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,
|
||||
CHANNEL_LOADPOINT_TARGET_TIME);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_TARGET_TIME_ENABLED = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_TARGET_TIME_ENABLED);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_LIMIT_ENERGY = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_LIMIT_ENERGY);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_LIMIT_SOC = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_LIMIT_SOC);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_TITLE = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_TITLE);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_CAPACITY = new ChannelTypeUID(BINDING_ID,
|
||||
@ -136,8 +146,20 @@ public class EvccBindingConstants {
|
||||
CHANNEL_LOADPOINT_VEHICLE_RANGE);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_SOC = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_VEHICLE_SOC);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_TITLE = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_VEHICLE_TITLE);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_NAME = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_VEHICLE_NAME);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_VEHICLE_TITLE = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_VEHICLE_TITLE);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_VEHICLE_MIN_SOC = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_VEHICLE_MIN_SOC);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_VEHICLE_LIMIT_SOC = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_VEHICLE_LIMIT_SOC);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_VEHICLE_PLAN_ENABLED = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_VEHICLE_PLAN_ENABLED);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_VEHICLE_PLAN_SOC = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_VEHICLE_PLAN_SOC);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_VEHICLE_PLAN_TIME = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_VEHICLE_PLAN_TIME);
|
||||
|
||||
public static final int CONNECTION_TIMEOUT_MILLISEC = 5000;
|
||||
public static final int LONG_CONNECTION_TIMEOUT_MILLISEC = 60000;
|
||||
|
@ -16,6 +16,8 @@ import static org.openhab.binding.evcc.internal.EvccBindingConstants.*;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -24,7 +26,9 @@ import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.evcc.internal.api.EvccAPI;
|
||||
import org.openhab.binding.evcc.internal.api.EvccApiException;
|
||||
import org.openhab.binding.evcc.internal.api.dto.Loadpoint;
|
||||
import org.openhab.binding.evcc.internal.api.dto.Plan;
|
||||
import org.openhab.binding.evcc.internal.api.dto.Result;
|
||||
import org.openhab.binding.evcc.internal.api.dto.Vehicle;
|
||||
import org.openhab.core.library.CoreItemFactory;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
@ -52,6 +56,7 @@ import org.slf4j.LoggerFactory;
|
||||
* sent to one of the channels.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
* @author Luca Arnecke - Update to evcc version 0.123.1
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EvccHandler extends BaseThingHandler {
|
||||
@ -64,9 +69,7 @@ public class EvccHandler extends BaseThingHandler {
|
||||
private boolean batteryConfigured = false;
|
||||
private boolean gridConfigured = false;
|
||||
private boolean pvConfigured = false;
|
||||
|
||||
private boolean targetTimeEnabled = false;
|
||||
private ZonedDateTime targetTimeZDT = ZonedDateTime.now().plusHours(12);
|
||||
Map<String, Triple<Boolean, Float, ZonedDateTime>> vehiclePlans = new HashMap<>();
|
||||
|
||||
public EvccHandler(Thing thing) {
|
||||
super(thing);
|
||||
@ -82,25 +85,64 @@ public class EvccHandler extends BaseThingHandler {
|
||||
if (groupId == null) {
|
||||
return;
|
||||
}
|
||||
String channelGroupId = channelUID.getGroupId();
|
||||
String channelIdWithoutGroup = channelUID.getIdWithoutGroup();
|
||||
EvccAPI evccAPI = this.evccAPI;
|
||||
if (evccAPI == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (channelGroupId.equals(CHANNEL_GROUP_ID_GENERAL)) {
|
||||
if (!channelIdWithoutGroup.equals(CHANNEL_BATTERY_PRIORITY_SOC)) {
|
||||
return;
|
||||
if (groupId.equals(CHANNEL_GROUP_ID_GENERAL)) {
|
||||
switch (channelIdWithoutGroup) {
|
||||
case CHANNEL_PRIORITY_SOC -> {
|
||||
if (command instanceof QuantityType<?> qt) {
|
||||
evccAPI.setPrioritySoC(qt.toUnit(Units.PERCENT).intValue());
|
||||
} else if (command instanceof DecimalType dt) {
|
||||
evccAPI.setPrioritySoC(dt.intValue());
|
||||
} else {
|
||||
logger.debug("Command has wrong type, QuantityType or DecimalType required!");
|
||||
}
|
||||
}
|
||||
case CHANNEL_BUFFER_SOC -> {
|
||||
if (command instanceof QuantityType<?> qt) {
|
||||
evccAPI.setBufferSoC(qt.toUnit(Units.PERCENT).intValue());
|
||||
} else if (command instanceof DecimalType dt) {
|
||||
evccAPI.setBufferSoC(dt.intValue());
|
||||
} else {
|
||||
logger.debug("Command has wrong type, QuantityType or DecimalType required!");
|
||||
}
|
||||
}
|
||||
case CHANNEL_BUFFER_START_SOC -> {
|
||||
if (command instanceof QuantityType<?> qt) {
|
||||
evccAPI.setBufferStartSoC(qt.toUnit(Units.PERCENT).intValue());
|
||||
} else if (command instanceof DecimalType dt) {
|
||||
evccAPI.setBufferStartSoC(dt.intValue());
|
||||
} else {
|
||||
logger.debug("Command has wrong type, QuantityType or DecimalType required!");
|
||||
}
|
||||
}
|
||||
case CHANNEL_RESIDUAL_POWER -> {
|
||||
if (command instanceof QuantityType<?> qt) {
|
||||
evccAPI.setResidualPower(qt.toUnit(Units.WATT).intValue());
|
||||
} else if (command instanceof DecimalType dt) {
|
||||
evccAPI.setResidualPower(dt.intValue());
|
||||
} else {
|
||||
logger.debug("Command has wrong type, QuantityType or DecimalType required!");
|
||||
}
|
||||
}
|
||||
case CHANNEL_BATTERY_DISCHARGE_CONTROL -> {
|
||||
if (command == OnOffType.ON) {
|
||||
evccAPI.setBatteryDischargeControl(true);
|
||||
} else if (command == OnOffType.OFF) {
|
||||
evccAPI.setBatteryDischargeControl(false);
|
||||
} else {
|
||||
logger.debug("Command has wrong type, OnOffType required!");
|
||||
}
|
||||
}
|
||||
default -> {
|
||||
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 {
|
||||
} else if (groupId.startsWith(CHANNEL_GROUP_ID_LOADPOINT)) {
|
||||
int loadpoint = Integer.parseInt(groupId.substring(9)) + 1;
|
||||
switch (channelIdWithoutGroup) {
|
||||
case CHANNEL_LOADPOINT_MODE -> {
|
||||
@ -110,59 +152,25 @@ public class EvccHandler extends BaseThingHandler {
|
||||
logger.debug("Command has wrong type, StringType required!");
|
||||
}
|
||||
}
|
||||
case CHANNEL_LOADPOINT_MIN_SOC -> {
|
||||
case CHANNEL_LOADPOINT_LIMIT_ENERGY -> {
|
||||
if (command instanceof QuantityType<?> qt) {
|
||||
evccAPI.setMinSoC(loadpoint, qt.toUnit(Units.PERCENT).intValue());
|
||||
evccAPI.setLimitEnergy(loadpoint, qt.toUnit(Units.WATT_HOUR).floatValue());
|
||||
} else if (command instanceof DecimalType dt) {
|
||||
evccAPI.setMinSoC(loadpoint, dt.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());
|
||||
// DecimalType commands are interpreted as 'kWh'
|
||||
evccAPI.setLimitEnergy(loadpoint, dt.intValue() * 1000);
|
||||
} else {
|
||||
logger.debug("Command has wrong type, QuantityType required!");
|
||||
}
|
||||
}
|
||||
case CHANNEL_LOADPOINT_TARGET_SOC -> {
|
||||
case CHANNEL_LOADPOINT_LIMIT_SOC -> {
|
||||
if (command instanceof QuantityType<?> qt) {
|
||||
evccAPI.setTargetSoC(loadpoint, qt.toUnit(Units.PERCENT).intValue());
|
||||
evccAPI.setLimitSoC(loadpoint, qt.toUnit(Units.PERCENT).intValue());
|
||||
} else if (command instanceof DecimalType dt) {
|
||||
evccAPI.setTargetSoC(loadpoint, dt.intValue());
|
||||
evccAPI.setLimitSoC(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!");
|
||||
}
|
||||
}
|
||||
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!");
|
||||
}
|
||||
}
|
||||
case CHANNEL_LOADPOINT_PHASES -> {
|
||||
if (command instanceof DecimalType dt) {
|
||||
evccAPI.setPhases(loadpoint, dt.intValue());
|
||||
@ -192,6 +200,82 @@ public class EvccHandler extends BaseThingHandler {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (groupId.startsWith(CHANNEL_GROUP_ID_VEHICLE)) {
|
||||
String vehicleName = groupId.substring(7);
|
||||
switch (channelIdWithoutGroup) {
|
||||
case CHANNEL_VEHICLE_MIN_SOC -> {
|
||||
if (command instanceof QuantityType<?> qt) {
|
||||
evccAPI.setVehicleMinSoC(vehicleName, qt.toUnit(Units.PERCENT).intValue());
|
||||
} else if (command instanceof DecimalType dt) {
|
||||
evccAPI.setVehicleMinSoC(vehicleName, dt.intValue());
|
||||
} else {
|
||||
logger.debug("Command has wrong type, QuantityType or DecimalType required!");
|
||||
}
|
||||
}
|
||||
case CHANNEL_VEHICLE_LIMIT_SOC -> {
|
||||
if (command instanceof QuantityType<?> qt) {
|
||||
evccAPI.setVehicleLimitSoC(vehicleName, qt.toUnit(Units.PERCENT).intValue());
|
||||
} else if (command instanceof DecimalType dt) {
|
||||
evccAPI.setVehicleLimitSoC(vehicleName, dt.intValue());
|
||||
} else {
|
||||
logger.debug("Command has wrong type, QuantityType or DecimalType required!");
|
||||
}
|
||||
}
|
||||
case CHANNEL_VEHICLE_PLAN_ENABLED -> {
|
||||
Triple<Boolean, Float, ZonedDateTime> planValues = vehiclePlans.get(vehicleName);
|
||||
if (command == OnOffType.ON) {
|
||||
evccAPI.setVehiclePlan(vehicleName, planValues.getMiddle().intValue(),
|
||||
planValues.getRight());
|
||||
vehiclePlans.put(vehicleName,
|
||||
new Triple<>(true, planValues.getMiddle(), planValues.getRight()));
|
||||
} else if (command == OnOffType.OFF) {
|
||||
evccAPI.removeVehiclePlan(vehicleName);
|
||||
vehiclePlans.put(vehicleName,
|
||||
new Triple<>(false, planValues.getMiddle(), planValues.getRight()));
|
||||
} else {
|
||||
logger.debug("Command has wrong type, OnOffType required!");
|
||||
}
|
||||
}
|
||||
case CHANNEL_VEHICLE_PLAN_SOC -> {
|
||||
Triple<Boolean, Float, ZonedDateTime> planValues = vehiclePlans.get(vehicleName);
|
||||
if (command instanceof QuantityType<?> qt) {
|
||||
vehiclePlans.put(vehicleName, new Triple<>(planValues.getLeft(),
|
||||
qt.toUnit(Units.PERCENT).floatValue(), planValues.getRight()));
|
||||
if (planValues.getLeft()) {
|
||||
evccAPI.setVehiclePlan(vehicleName, qt.toUnit(Units.PERCENT).intValue(),
|
||||
planValues.getRight());
|
||||
}
|
||||
} else if (command instanceof DecimalType dt) {
|
||||
vehiclePlans.put(vehicleName,
|
||||
new Triple<>(planValues.getLeft(), dt.floatValue(), planValues.getRight()));
|
||||
if (planValues.getLeft()) {
|
||||
evccAPI.setVehiclePlan(vehicleName, dt.intValue(), planValues.getRight());
|
||||
}
|
||||
} else {
|
||||
logger.debug("Command has wrong type, QuantityType or DecimalType required!");
|
||||
}
|
||||
}
|
||||
case CHANNEL_VEHICLE_PLAN_TIME -> {
|
||||
Triple<Boolean, Float, ZonedDateTime> planValues = vehiclePlans.get(vehicleName);
|
||||
if (command instanceof DateTimeType dtt) {
|
||||
vehiclePlans.put(vehicleName, new Triple<>(planValues.getLeft(), planValues.getMiddle(),
|
||||
dtt.getZonedDateTime()));
|
||||
if (planValues.getLeft()) {
|
||||
try {
|
||||
evccAPI.setVehiclePlan(vehicleName, planValues.getMiddle().intValue(),
|
||||
dtt.getZonedDateTime());
|
||||
} catch (DateTimeParseException e) {
|
||||
logger.debug("Failed to set vehicle plan time: ", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.debug("Command has wrong type, DateTimeType required!");
|
||||
}
|
||||
}
|
||||
default -> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (EvccApiException e) {
|
||||
Throwable cause = e.getCause();
|
||||
@ -248,6 +332,8 @@ public class EvccHandler extends BaseThingHandler {
|
||||
String sitename = result.getSiteTitle();
|
||||
int numberOfLoadpoints = result.getLoadpoints().length;
|
||||
logger.debug("Found {} loadpoints on site {}.", numberOfLoadpoints, sitename);
|
||||
Map<String, Vehicle> vehicles = result.getVehicles();
|
||||
logger.debug("Found {} vehicles on site {}.", vehicles.size(), sitename);
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
batteryConfigured = result.getBatteryConfigured();
|
||||
gridConfigured = result.getGridConfigured();
|
||||
@ -258,6 +344,10 @@ public class EvccHandler extends BaseThingHandler {
|
||||
createChannelsLoadpoint(i);
|
||||
updateChannelsLoadpoint(i);
|
||||
}
|
||||
for (String vehicleName : vehicles.keySet()) {
|
||||
createChannelsVehicle(vehicleName);
|
||||
updateChannelsVehicle(vehicleName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -279,8 +369,17 @@ public class EvccHandler extends BaseThingHandler {
|
||||
"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,
|
||||
createChannel(CHANNEL_BATTERY_DISCHARGE_CONTROL, CHANNEL_GROUP_ID_GENERAL,
|
||||
CHANNEL_TYPE_UID_BATTERY_DISCHARGE_CONTROL, "Switch");
|
||||
createChannel(CHANNEL_BATTERY_MODE, CHANNEL_GROUP_ID_GENERAL, CHANNEL_TYPE_UID_BATTERY_MODE, "String");
|
||||
createChannel(CHANNEL_PRIORITY_SOC, CHANNEL_GROUP_ID_GENERAL, CHANNEL_TYPE_UID_PRIORITY_SOC,
|
||||
"Number:Dimensionless");
|
||||
createChannel(CHANNEL_BUFFER_SOC, CHANNEL_GROUP_ID_GENERAL, CHANNEL_TYPE_UID_BUFFER_SOC,
|
||||
"Number:Dimensionless");
|
||||
createChannel(CHANNEL_BUFFER_START_SOC, CHANNEL_GROUP_ID_GENERAL, CHANNEL_TYPE_UID_BUFFER_START_SOC,
|
||||
"Number:Dimensionless");
|
||||
createChannel(CHANNEL_RESIDUAL_POWER, CHANNEL_GROUP_ID_GENERAL, CHANNEL_TYPE_UID_RESIDUAL_POWER,
|
||||
"Number:Power");
|
||||
}
|
||||
if (gridConfigured) {
|
||||
createChannel(CHANNEL_GRID_POWER, CHANNEL_GROUP_ID_GENERAL, CHANNEL_TYPE_UID_GRID_POWER, "Number:Power");
|
||||
@ -289,10 +388,11 @@ public class EvccHandler extends BaseThingHandler {
|
||||
if (pvConfigured) {
|
||||
createChannel(CHANNEL_PV_POWER, CHANNEL_GROUP_ID_GENERAL, CHANNEL_TYPE_UID_PV_POWER, "Number:Power");
|
||||
}
|
||||
removeChannel("batteryPrioritySoC", CHANNEL_GROUP_ID_GENERAL);
|
||||
}
|
||||
|
||||
private void createChannelsLoadpoint(int loadpointId) {
|
||||
final String channelGroup = "loadpoint" + loadpointId;
|
||||
final String channelGroup = CHANNEL_GROUP_ID_LOADPOINT + loadpointId;
|
||||
createChannel(CHANNEL_LOADPOINT_ACTIVE_PHASES, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_ACTIVE_PHASES,
|
||||
CoreItemFactory.NUMBER);
|
||||
createChannel(CHANNEL_LOADPOINT_CHARGE_CURRENT, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_CHARGE_CURRENT,
|
||||
@ -319,19 +419,13 @@ public class EvccHandler extends BaseThingHandler {
|
||||
"Number:ElectricCurrent");
|
||||
createChannel(CHANNEL_LOADPOINT_MIN_CURRENT, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_MIN_CURRENT,
|
||||
"Number:ElectricCurrent");
|
||||
createChannel(CHANNEL_LOADPOINT_MIN_SOC, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_MIN_SOC,
|
||||
"Number:Dimensionless");
|
||||
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,
|
||||
createChannel(CHANNEL_LOADPOINT_LIMIT_ENERGY, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_LIMIT_ENERGY,
|
||||
"Number:Energy");
|
||||
createChannel(CHANNEL_LOADPOINT_TARGET_SOC, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_TARGET_SOC,
|
||||
createChannel(CHANNEL_LOADPOINT_LIMIT_SOC, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_LIMIT_SOC,
|
||||
"Number:Dimensionless");
|
||||
createChannel(CHANNEL_LOADPOINT_TARGET_TIME, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_TARGET_TIME,
|
||||
CoreItemFactory.DATETIME);
|
||||
createChannel(CHANNEL_LOADPOINT_TARGET_TIME_ENABLED, channelGroup,
|
||||
CHANNEL_TYPE_UID_LOADPOINT_TARGET_TIME_ENABLED, CoreItemFactory.SWITCH);
|
||||
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");
|
||||
@ -343,10 +437,33 @@ public class EvccHandler extends BaseThingHandler {
|
||||
"Number:Length");
|
||||
createChannel(CHANNEL_LOADPOINT_VEHICLE_SOC, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_SOC,
|
||||
"Number:Dimensionless");
|
||||
createChannel(CHANNEL_LOADPOINT_VEHICLE_TITLE, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_TITLE,
|
||||
createChannel(CHANNEL_LOADPOINT_VEHICLE_NAME, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_NAME,
|
||||
CoreItemFactory.STRING);
|
||||
|
||||
removeChannel(CHANNEL_LOADPOINT_HAS_VEHICLE, channelGroup);
|
||||
removeChannel("hasVehicle", channelGroup);
|
||||
removeChannel("minSoC", channelGroup);
|
||||
removeChannel("targetEnergy", channelGroup);
|
||||
removeChannel("targetSoC", channelGroup);
|
||||
removeChannel("targetTime", channelGroup);
|
||||
removeChannel("targetTimeEnabled", channelGroup);
|
||||
}
|
||||
|
||||
private void createChannelsVehicle(String vehicleName) {
|
||||
final String channelGroup = CHANNEL_GROUP_ID_VEHICLE + vehicleName;
|
||||
createChannel(CHANNEL_VEHICLE_TITLE, channelGroup, CHANNEL_TYPE_UID_VEHICLE_TITLE, CoreItemFactory.STRING);
|
||||
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,
|
||||
"Number:Dimensionless");
|
||||
createChannel(CHANNEL_VEHICLE_PLAN_SOC, channelGroup, CHANNEL_TYPE_UID_VEHICLE_PLAN_SOC,
|
||||
"Number:Dimensionless");
|
||||
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,
|
||||
CoreItemFactory.SWITCH);
|
||||
createChannel(CHANNEL_VEHICLE_PLAN_SOC, channelGroup, CHANNEL_TYPE_UID_VEHICLE_PLAN_SOC,
|
||||
"Number:Dimensionless");
|
||||
createChannel(CHANNEL_VEHICLE_PLAN_TIME, channelGroup, CHANNEL_TYPE_UID_VEHICLE_PLAN_TIME,
|
||||
CoreItemFactory.DATETIME);
|
||||
}
|
||||
|
||||
// Units and description for vars: https://docs.evcc.io/docs/reference/configuration/messaging/#msg
|
||||
@ -371,9 +488,29 @@ public class EvccHandler extends BaseThingHandler {
|
||||
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, CHANNEL_GROUP_ID_GENERAL, CHANNEL_BATTERY_PRIORITY_SOC);
|
||||
updateState(channel, new QuantityType<>(batteryPrioritySoC, Units.PERCENT));
|
||||
boolean batteryDischargeControl = result.getBatteryDischargeControl();
|
||||
channel = new ChannelUID(uid, CHANNEL_GROUP_ID_GENERAL, CHANNEL_BATTERY_DISCHARGE_CONTROL);
|
||||
updateState(channel, OnOffType.from(batteryDischargeControl));
|
||||
|
||||
String batteryMode = result.getBatteryMode();
|
||||
channel = new ChannelUID(uid, CHANNEL_GROUP_ID_GENERAL, CHANNEL_BATTERY_MODE);
|
||||
updateState(channel, new StringType(batteryMode));
|
||||
|
||||
float prioritySoC = result.getPrioritySoC();
|
||||
channel = new ChannelUID(uid, CHANNEL_GROUP_ID_GENERAL, CHANNEL_PRIORITY_SOC);
|
||||
updateState(channel, new QuantityType<>(prioritySoC, Units.PERCENT));
|
||||
|
||||
float bufferSoC = result.getBufferSoC();
|
||||
channel = new ChannelUID(uid, CHANNEL_GROUP_ID_GENERAL, CHANNEL_BUFFER_SOC);
|
||||
updateState(channel, new QuantityType<>(bufferSoC, Units.PERCENT));
|
||||
|
||||
float bufferStartSoC = result.getBufferStartSoC();
|
||||
channel = new ChannelUID(uid, CHANNEL_GROUP_ID_GENERAL, CHANNEL_BUFFER_START_SOC);
|
||||
updateState(channel, new QuantityType<>(bufferStartSoC, Units.PERCENT));
|
||||
|
||||
float residualPower = result.getResidualPower();
|
||||
channel = new ChannelUID(uid, CHANNEL_GROUP_ID_GENERAL, CHANNEL_RESIDUAL_POWER);
|
||||
updateState(channel, new QuantityType<>(residualPower, Units.WATT));
|
||||
}
|
||||
boolean gridConfigured = this.gridConfigured;
|
||||
if (gridConfigured) {
|
||||
@ -398,123 +535,147 @@ public class EvccHandler extends BaseThingHandler {
|
||||
return;
|
||||
}
|
||||
final ThingUID uid = getThing().getUID();
|
||||
final String loadpointName = "loadpoint" + loadpointId;
|
||||
final String channelGroup = CHANNEL_GROUP_ID_LOADPOINT + loadpointId;
|
||||
ChannelUID channel;
|
||||
Loadpoint loadpoint = result.getLoadpoints()[loadpointId];
|
||||
|
||||
int activePhases = loadpoint.getActivePhases();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_ACTIVE_PHASES);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_ACTIVE_PHASES);
|
||||
updateState(channel, new DecimalType(activePhases));
|
||||
|
||||
float chargeCurrent = loadpoint.getChargeCurrent();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_CHARGE_CURRENT);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_CHARGE_CURRENT);
|
||||
updateState(channel, new QuantityType<>(chargeCurrent, Units.AMPERE));
|
||||
|
||||
long chargeDuration = loadpoint.getChargeDuration();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_CHARGE_DURATION);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_CHARGE_DURATION);
|
||||
updateState(channel, new QuantityType<>(chargeDuration, MetricPrefix.NANO(Units.SECOND)));
|
||||
|
||||
float chargePower = loadpoint.getChargePower();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_CHARGE_POWER);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_CHARGE_POWER);
|
||||
updateState(channel, new QuantityType<>(chargePower, Units.WATT));
|
||||
|
||||
long chargeRemainingDuration = loadpoint.getChargeRemainingDuration();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_CHARGE_REMAINING_DURATION);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_CHARGE_REMAINING_DURATION);
|
||||
updateState(channel, new QuantityType<>(chargeRemainingDuration, MetricPrefix.NANO(Units.SECOND)));
|
||||
|
||||
float chargeRemainingEnergy = loadpoint.getChargeRemainingEnergy();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_CHARGE_REMAINING_ENERGY);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_CHARGE_REMAINING_ENERGY);
|
||||
updateState(channel, new QuantityType<>(chargeRemainingEnergy, Units.WATT_HOUR));
|
||||
|
||||
float chargedEnergy = loadpoint.getChargedEnergy();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_CHARGED_ENERGY);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_CHARGED_ENERGY);
|
||||
updateState(channel, new QuantityType<>(chargedEnergy, Units.WATT_HOUR));
|
||||
|
||||
boolean charging = loadpoint.getCharging();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_CHARGING);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_CHARGING);
|
||||
updateState(channel, OnOffType.from(charging));
|
||||
|
||||
boolean connected = loadpoint.getConnected();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_CONNECTED);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_CONNECTED);
|
||||
updateState(channel, OnOffType.from(connected));
|
||||
|
||||
long connectedDuration = loadpoint.getConnectedDuration();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_CONNECTED_DURATION);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_CONNECTED_DURATION);
|
||||
updateState(channel, new QuantityType<>(connectedDuration, MetricPrefix.NANO(Units.SECOND)));
|
||||
|
||||
boolean enabled = loadpoint.getEnabled();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_ENABLED);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_ENABLED);
|
||||
updateState(channel, OnOffType.from(enabled));
|
||||
|
||||
float maxCurrent = loadpoint.getMaxCurrent();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_MAX_CURRENT);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_MAX_CURRENT);
|
||||
updateState(channel, new QuantityType<>(maxCurrent, Units.AMPERE));
|
||||
|
||||
float minCurrent = loadpoint.getMinCurrent();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_MIN_CURRENT);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_MIN_CURRENT);
|
||||
updateState(channel, new QuantityType<>(minCurrent, Units.AMPERE));
|
||||
|
||||
float minSoC = loadpoint.getMinSoC();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_MIN_SOC);
|
||||
updateState(channel, new QuantityType<>(minSoC, Units.PERCENT));
|
||||
|
||||
String mode = loadpoint.getMode();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_MODE);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_MODE);
|
||||
updateState(channel, new StringType(mode));
|
||||
|
||||
int phases = loadpoint.getPhases();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_PHASES);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_PHASES);
|
||||
updateState(channel, new DecimalType(phases));
|
||||
|
||||
float targetEnergy = loadpoint.getTargetEnergy();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_TARGET_ENERGY);
|
||||
updateState(channel, new QuantityType<>(targetEnergy, Units.WATT_HOUR));
|
||||
float limitEnergy = loadpoint.getLimitEnergy();
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_LIMIT_ENERGY);
|
||||
updateState(channel, new QuantityType<>(limitEnergy, 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 || "0001-01-01T00:00:00Z".equals(targetTime)) {
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_TARGET_TIME_ENABLED);
|
||||
updateState(channel, OnOffType.OFF);
|
||||
targetTimeEnabled = false;
|
||||
} else {
|
||||
this.targetTimeZDT = ZonedDateTime.parse(targetTime);
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_TARGET_TIME);
|
||||
updateState(channel, new DateTimeType(targetTimeZDT));
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_TARGET_TIME_ENABLED);
|
||||
updateState(channel, OnOffType.ON);
|
||||
targetTimeEnabled = true;
|
||||
}
|
||||
float limitSoC = loadpoint.getLimitSoC();
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_LIMIT_SOC);
|
||||
updateState(channel, new QuantityType<>(limitSoC, Units.PERCENT));
|
||||
|
||||
String title = loadpoint.getTitle();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_TITLE);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_TITLE);
|
||||
updateState(channel, new StringType(title));
|
||||
|
||||
float vehicleCapacity = loadpoint.getVehicleCapacity();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_VEHICLE_CAPACITY);
|
||||
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, loadpointName, CHANNEL_LOADPOINT_VEHICLE_ODOMETER);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_VEHICLE_ODOMETER);
|
||||
updateState(channel, new QuantityType<>(vehicleOdometer, MetricPrefix.KILO(SIUnits.METRE)));
|
||||
|
||||
boolean vehiclePresent = loadpoint.getVehiclePresent();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_VEHICLE_PRESENT);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_VEHICLE_PRESENT);
|
||||
updateState(channel, OnOffType.from(vehiclePresent));
|
||||
|
||||
float vehicleRange = loadpoint.getVehicleRange();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_VEHICLE_RANGE);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_VEHICLE_RANGE);
|
||||
updateState(channel, new QuantityType<>(vehicleRange, MetricPrefix.KILO(SIUnits.METRE)));
|
||||
|
||||
float vehicleSoC = loadpoint.getVehicleSoC();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_VEHICLE_SOC);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_VEHICLE_SOC);
|
||||
updateState(channel, new QuantityType<>(vehicleSoC, Units.PERCENT));
|
||||
|
||||
String vehicleTitle = loadpoint.getVehicleTitle();
|
||||
channel = new ChannelUID(uid, loadpointName, CHANNEL_LOADPOINT_VEHICLE_TITLE);
|
||||
updateState(channel, new StringType(vehicleTitle));
|
||||
String vehicleName = loadpoint.getVehicleName();
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_LOADPOINT_VEHICLE_NAME);
|
||||
updateState(channel, new StringType(vehicleName));
|
||||
}
|
||||
|
||||
private void updateChannelsVehicle(String vehicleName) {
|
||||
final Result result = this.result;
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
final ThingUID uid = getThing().getUID();
|
||||
final String channelGroup = CHANNEL_GROUP_ID_VEHICLE + vehicleName;
|
||||
ChannelUID channel;
|
||||
Vehicle vehicle = result.getVehicles().get(vehicleName);
|
||||
|
||||
String title = vehicle.getTitle();
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_VEHICLE_TITLE);
|
||||
updateState(channel, new StringType(title));
|
||||
|
||||
float minSoC = vehicle.getMinSoC();
|
||||
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));
|
||||
|
||||
Plan plan = 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);
|
||||
}
|
||||
|
||||
private void updateVehiclePlanChannel(String vehicleName, ThingUID uid, String channelGroup) {
|
||||
Triple<Boolean, Float, ZonedDateTime> planValues = vehiclePlans.get(vehicleName);
|
||||
|
||||
ChannelUID channel = new ChannelUID(uid, channelGroup, CHANNEL_VEHICLE_PLAN_ENABLED);
|
||||
updateState(channel, planValues.getLeft() ? OnOffType.ON : OnOffType.OFF);
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_VEHICLE_PLAN_SOC);
|
||||
updateState(channel, new QuantityType<>(planValues.getMiddle(), Units.PERCENT));
|
||||
channel = new ChannelUID(uid, channelGroup, CHANNEL_VEHICLE_PLAN_TIME);
|
||||
updateState(channel, new DateTimeType(planValues.getRight()));
|
||||
}
|
||||
|
||||
private void createChannel(String channel, String channelGroupId, ChannelTypeUID channelTypeUID, String itemType) {
|
||||
@ -531,4 +692,28 @@ public class EvccHandler extends BaseThingHandler {
|
||||
updateThing(editThing().withoutChannel(channelUid).build());
|
||||
}
|
||||
}
|
||||
|
||||
private class Triple<L, M, R> {
|
||||
private final L left;
|
||||
private final M middle;
|
||||
private final R right;
|
||||
|
||||
private Triple(L left, M middle, R right) {
|
||||
this.left = left;
|
||||
this.middle = middle;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
private L getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
private M getMiddle() {
|
||||
return middle;
|
||||
}
|
||||
|
||||
private R getRight() {
|
||||
return right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,9 +31,10 @@ import com.google.gson.JsonSyntaxException;
|
||||
|
||||
/**
|
||||
* The {@link EvccAPI} is responsible for API calls to evcc.
|
||||
* API requests were written for evcc version 0.117.0
|
||||
* API requests were written for evcc version 0.123.1
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
* @author Luca Arnecke - Update to evcc version 0.123.1
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EvccAPI {
|
||||
@ -86,26 +87,38 @@ public class EvccAPI {
|
||||
}
|
||||
|
||||
// Site API calls.
|
||||
public String setBatteryPrioritySoC(int prioritySoc) throws EvccApiException {
|
||||
public String setPrioritySoC(int prioritySoc) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "prioritysoc/" + prioritySoc, "POST");
|
||||
}
|
||||
|
||||
public String setBufferSoC(int bufferSoC) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "buffersoc/" + bufferSoC, "POST");
|
||||
}
|
||||
|
||||
public String setBufferStartSoC(int bufferStartSoC) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "bufferstartsoc/" + bufferStartSoC, "POST");
|
||||
}
|
||||
|
||||
public String setResidualPower(int residualPower) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "residualpower/" + residualPower, "POST");
|
||||
}
|
||||
|
||||
public String setBatteryDischargeControl(boolean batteryDischargeControl) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "batterydischargecontrol/" + batteryDischargeControl, "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");
|
||||
}
|
||||
|
||||
public String setMinSoC(int loadpoint, int minSoC) throws EvccApiException {
|
||||
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,
|
||||
public String setLimitEnergy(int loadpoint, float limitEnergy) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/limitenergy/" + limitEnergy,
|
||||
"POST");
|
||||
}
|
||||
|
||||
public String setTargetSoC(int loadpoint, int targetSoC) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/target/soc/" + targetSoC, "POST");
|
||||
public String setLimitSoC(int loadpoint, int limitSoC) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/limitsoc/" + limitSoC, "POST");
|
||||
}
|
||||
|
||||
public String setPhases(int loadpoint, int phases) throws EvccApiException {
|
||||
@ -120,12 +133,21 @@ public class EvccAPI {
|
||||
return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/maxcurrent/" + maxCurrent, "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");
|
||||
// Vehicle specific API calls.
|
||||
public String setVehicleMinSoC(String vehicleName, int minSoC) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "vehicles/" + vehicleName + "/minsoc/" + minSoC, "POST");
|
||||
}
|
||||
|
||||
public String removeTargetTime(int loadpoint) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/target/time", "DELETE");
|
||||
public String setVehicleLimitSoC(String vehicleName, int limitSoC) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "vehicles/" + vehicleName + "/limitsoc/" + limitSoC, "POST");
|
||||
}
|
||||
|
||||
public String setVehiclePlan(String vehicleName, int planSoC, ZonedDateTime planTime) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "vehicles/" + vehicleName + "/plan/soc/" + planSoC + "/"
|
||||
+ planTime.toLocalDateTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) + "Z", "POST");
|
||||
}
|
||||
|
||||
public String removeVehiclePlan(String vehicleName) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "vehicles/" + vehicleName + "/plan/soc", "DELETE");
|
||||
}
|
||||
}
|
||||
|
@ -16,9 +16,10 @@ import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* This class represents a loadpoint object of the status response (/api/state).
|
||||
* This DTO was written for evcc version 0.117.0
|
||||
* This DTO was written for evcc version 0.123.1
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
* @author Luca Arnecke - Update to evcc version 0.123.1
|
||||
*/
|
||||
public class Loadpoint {
|
||||
// Data types from https://github.com/evcc-io/evcc/blob/master/api/api.go
|
||||
@ -63,23 +64,17 @@ public class Loadpoint {
|
||||
@SerializedName("minCurrent")
|
||||
private float minCurrent;
|
||||
|
||||
@SerializedName("minSoc")
|
||||
private float minSoC;
|
||||
|
||||
@SerializedName("mode")
|
||||
private String mode;
|
||||
|
||||
@SerializedName("phasesEnabled")
|
||||
private int phases;
|
||||
|
||||
@SerializedName("planActive")
|
||||
private boolean planActive;
|
||||
@SerializedName("limitEnergy")
|
||||
private float limitEnergy;
|
||||
|
||||
@SerializedName("targetEnergy")
|
||||
private float targetEnergy;
|
||||
|
||||
@SerializedName("targetSoc")
|
||||
private float targetSoC;
|
||||
@SerializedName("limitSoc")
|
||||
private float limitSoC;
|
||||
|
||||
@SerializedName("targetTime")
|
||||
private String targetTime;
|
||||
@ -102,8 +97,8 @@ public class Loadpoint {
|
||||
@SerializedName("vehicleSoc")
|
||||
private float vehicleSoC;
|
||||
|
||||
@SerializedName("vehicleTitle")
|
||||
private String vehicleTitle;
|
||||
@SerializedName("vehicleName")
|
||||
private String vehicleName;
|
||||
|
||||
/**
|
||||
* @return number of active phases
|
||||
@ -196,13 +191,6 @@ public class Loadpoint {
|
||||
return minCurrent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return minimum state of charge
|
||||
*/
|
||||
public float getMinSoC() {
|
||||
return minSoC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return charging mode: off, now, minpv, pv
|
||||
*/
|
||||
@ -218,24 +206,17 @@ public class Loadpoint {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether charging plan is active
|
||||
* @return limit energy
|
||||
*/
|
||||
public boolean getPlanActive() {
|
||||
return planActive;
|
||||
public float getLimitEnergy() {
|
||||
return limitEnergy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return target energy
|
||||
* @return limit state of charge (SoC)
|
||||
*/
|
||||
public float getTargetEnergy() {
|
||||
return targetEnergy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return target state of charge (SoC)
|
||||
*/
|
||||
public float getTargetSoC() {
|
||||
return targetSoC;
|
||||
public float getLimitSoC() {
|
||||
return limitSoC;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -290,7 +271,7 @@ public class Loadpoint {
|
||||
/**
|
||||
* @return vehicle's title/name
|
||||
*/
|
||||
public String getVehicleTitle() {
|
||||
return vehicleTitle;
|
||||
public String getVehicleName() {
|
||||
return vehicleName;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.evcc.internal.api.dto;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* This class represents a plan object of the status response (/api/state).
|
||||
* This DTO was written for evcc version 0.123.1
|
||||
*
|
||||
* @author Luca Arnecke - Initial contribution
|
||||
*/
|
||||
public class Plan {
|
||||
// Data types from https://github.com/evcc-io/evcc/blob/master/api/api.go
|
||||
// and from https://docs.evcc.io/docs/reference/configuration/messaging/#msg
|
||||
|
||||
@SerializedName("soc")
|
||||
private float soc;
|
||||
|
||||
@SerializedName("time")
|
||||
private String time;
|
||||
|
||||
/**
|
||||
* @return state of charge
|
||||
*/
|
||||
public float getSoC() {
|
||||
return soc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return time
|
||||
*/
|
||||
public String getTime() {
|
||||
return time;
|
||||
}
|
||||
}
|
@ -12,13 +12,16 @@
|
||||
*/
|
||||
package org.openhab.binding.evcc.internal.api.dto;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* This class represents the result object of the status response (/api/state).
|
||||
* This DTO was written for evcc version 0.117.0
|
||||
* This DTO was written for evcc version 0.123.1
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
* @author Luca Arnecke - update to evcc version 0.123.1
|
||||
*/
|
||||
public class Result {
|
||||
// Data types from https://github.com/evcc-io/evcc/blob/master/api/api.go
|
||||
@ -38,6 +41,12 @@ public class Result {
|
||||
@SerializedName("batterySoc")
|
||||
private float batterySoC;
|
||||
|
||||
@SerializedName("batteryDischargeControl")
|
||||
private boolean batteryDischargeControl;
|
||||
|
||||
@SerializedName("batteryMode")
|
||||
private String batteryMode;
|
||||
|
||||
@SerializedName("gridConfigured")
|
||||
private boolean gridConfigured;
|
||||
|
||||
@ -51,7 +60,16 @@ public class Result {
|
||||
private Loadpoint[] loadpoints;
|
||||
|
||||
@SerializedName("prioritySoc")
|
||||
private float batteryPrioritySoC;
|
||||
private float prioritySoC;
|
||||
|
||||
@SerializedName("bufferSoc")
|
||||
private float bufferSoC;
|
||||
|
||||
@SerializedName("bufferStartSoc")
|
||||
private float bufferStartSoC;
|
||||
|
||||
@SerializedName("residualPower")
|
||||
private float residualPower;
|
||||
|
||||
@SerializedName("pvConfigured")
|
||||
private boolean pvConfigured;
|
||||
@ -62,6 +80,9 @@ public class Result {
|
||||
@SerializedName("siteTitle")
|
||||
private String siteTitle;
|
||||
|
||||
@SerializedName("vehicles")
|
||||
private Map<String, Vehicle> vehicles;
|
||||
|
||||
/**
|
||||
* @return battery's capacity
|
||||
*/
|
||||
@ -86,8 +107,29 @@ public class Result {
|
||||
/**
|
||||
* @return battery's priority state of charge
|
||||
*/
|
||||
public float getBatteryPrioritySoC() {
|
||||
return batteryPrioritySoC;
|
||||
public float getPrioritySoC() {
|
||||
return prioritySoC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Battery Buffer SoC
|
||||
*/
|
||||
public float getBufferSoC() {
|
||||
return bufferSoC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Battery Buffer Start SoC
|
||||
*/
|
||||
public float getBufferStartSoC() {
|
||||
return bufferStartSoC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Grid Residual Power
|
||||
*/
|
||||
public float getResidualPower() {
|
||||
return residualPower;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,6 +139,20 @@ public class Result {
|
||||
return batterySoC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return battery discharge control
|
||||
*/
|
||||
public boolean getBatteryDischargeControl() {
|
||||
return batteryDischargeControl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return battery mode
|
||||
*/
|
||||
public String getBatteryMode() {
|
||||
return batteryMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether grid is configured
|
||||
*/
|
||||
@ -145,4 +201,8 @@ public class Result {
|
||||
public String getSiteTitle() {
|
||||
return siteTitle;
|
||||
}
|
||||
|
||||
public Map<String, Vehicle> getVehicles() {
|
||||
return vehicles;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.evcc.internal.api.dto;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* This class represents a vehicle object of the status response (/api/state).
|
||||
* This DTO was written for evcc version 0.123.1
|
||||
*
|
||||
* @author Luca Arnecke - Initial contribution
|
||||
*/
|
||||
public class Vehicle {
|
||||
// Data types from https://github.com/evcc-io/evcc/blob/master/api/api.go
|
||||
// and from https://docs.evcc.io/docs/reference/configuration/messaging/#msg
|
||||
|
||||
@SerializedName("title")
|
||||
private String title;
|
||||
|
||||
@SerializedName("minSoc")
|
||||
private float minSoC;
|
||||
|
||||
@SerializedName("limitSoc")
|
||||
private float limitSoC;
|
||||
|
||||
@SerializedName("plans")
|
||||
private Plan[] plans;
|
||||
|
||||
/**
|
||||
* @return vehicle name
|
||||
*/
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return minimum state of charge
|
||||
*/
|
||||
public float getMinSoC() {
|
||||
return minSoC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return limit state of charge
|
||||
*/
|
||||
public float getLimitSoC() {
|
||||
return limitSoC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return current plan for vehicle
|
||||
*/
|
||||
public Plan getPlan() {
|
||||
if (plans != null) {
|
||||
return plans[0];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -26,12 +26,20 @@ 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.batteryDischargeControl.label = Battery Discharge Control
|
||||
channel-type.evcc.batteryDischargeControl.description = Enable or disable battery discharge control
|
||||
channel-type.evcc.batteryDischargeControl.state.option.ON = Enabled
|
||||
channel-type.evcc.batteryDischargeControl.state.option.OFF = Disabled
|
||||
channel-type.evcc.batteryMode.label = Battery Mode
|
||||
channel-type.evcc.batteryMode.description = Current Battery Mode
|
||||
channel-type.evcc.batteryPower.label = Battery Power
|
||||
channel-type.evcc.batteryPower.description = Current power from battery
|
||||
channel-type.evcc.batteryPrioritySoC.label = Battery Priority SoC
|
||||
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.bufferSoC.label = Battery Buffer SoC
|
||||
channel-type.evcc.bufferSoC.description = Until this State of Charge the discharging of a house battery is allowed in "pv" mode, when there is insufficient solar surplus (below the minimum charging power)
|
||||
channel-type.evcc.bufferStartSoC.label = Battery Buffer Start SoC
|
||||
channel-type.evcc.bufferStartSoC.description = State of Charge for which a charging session in "pv" mode is started, even if there is insufficient solar surplus
|
||||
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
|
||||
@ -39,9 +47,9 @@ channel-type.evcc.chargeDuration.description = Charging duration
|
||||
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.description = Remaining duration until target SoC is reached
|
||||
channel-type.evcc.chargeRemainingDuration.description = Remaining duration until limit SoC is reached
|
||||
channel-type.evcc.chargeRemainingEnergy.label = Charging Remaining Energy
|
||||
channel-type.evcc.chargeRemainingEnergy.description = Remaining energy until target SoC is reached
|
||||
channel-type.evcc.chargeRemainingEnergy.description = Remaining energy until limit SoC is reached
|
||||
channel-type.evcc.chargedEnergy.label = Charged Energy
|
||||
channel-type.evcc.chargedEnergy.description = Energy charged since plugged-in
|
||||
channel-type.evcc.charging.label = Charging State
|
||||
@ -56,12 +64,14 @@ channel-type.evcc.gridPower.label = Grid Power
|
||||
channel-type.evcc.gridPower.description = Current power from grid (negative means feed-in)
|
||||
channel-type.evcc.homePower.label = Home Power
|
||||
channel-type.evcc.homePower.description = Current power taken by home
|
||||
channel-type.evcc.limitEnergy.label = Charging Limit Energy
|
||||
channel-type.evcc.limitEnergy.description = Amount of energy to charge the vehicle with
|
||||
channel-type.evcc.limitSoC.label = Charging Limit SoC
|
||||
channel-type.evcc.limitSoC.description = Until which state of charge (SoC) should the vehicle be charged
|
||||
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.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.description = Charging mode: "off", "now", "minpv", "pv"
|
||||
channel-type.evcc.mode.state.option.off = Off
|
||||
@ -70,18 +80,12 @@ 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.description = The maximum number of phases which can be used
|
||||
channel-type.evcc.prioritySoC.label = Battery Priority SoC
|
||||
channel-type.evcc.prioritySoC.description = State of Charge for which the battery has priority over charging the EV when charging mode is "pv"
|
||||
channel-type.evcc.pvPower.label = PV Power
|
||||
channel-type.evcc.pvPower.description = Current power from photovoltaik
|
||||
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.description = When the target SoC should be reached
|
||||
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.residualPower.label = Grid Residual Power
|
||||
channel-type.evcc.residualPower.description = Target operating point of the surplus regulation at the grid connection (grid meter)
|
||||
channel-type.evcc.title.label = Loadpoint Title
|
||||
channel-type.evcc.title.description = Title of loadpoint
|
||||
channel-type.evcc.vehicleCapacity.label = Vehicle Capacity
|
||||
@ -92,8 +96,22 @@ 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.description = Duration the vehicle is connected to loadpoint
|
||||
channel-type.evcc.vehicleLimitSoC.label = Vehicle Charging Limit SoC
|
||||
channel-type.evcc.vehicleLimitSoC.description = Until which state of charge (SoC) should the specific vehicle be charged
|
||||
channel-type.evcc.vehicleMinSoC.label = Vehicle Min SoC
|
||||
channel-type.evcc.vehicleMinSoC.description = Minimum state of charge (SoC) a vehicle should have
|
||||
channel-type.evcc.vehicleName.label = Vehicle Name
|
||||
channel-type.evcc.vehicleName.description = The unique identifier of the EV used in the evcc configuration (containing no whitespaces nor special characters)
|
||||
channel-type.evcc.vehicleOdometer.label = Vehicle Odometer
|
||||
channel-type.evcc.vehicleOdometer.description = Total distance travelled by EV
|
||||
channel-type.evcc.vehiclePlanEnabled.label = Vehicle Plan Enabled
|
||||
channel-type.evcc.vehiclePlanEnabled.description = Plan for charging enabled
|
||||
channel-type.evcc.vehiclePlanEnabled.state.option.ON = Enabled
|
||||
channel-type.evcc.vehiclePlanEnabled.state.option.OFF = Disabled
|
||||
channel-type.evcc.vehiclePlanSoC.label = Vehicle Plan SoC
|
||||
channel-type.evcc.vehiclePlanSoC.description = Until which state of charge (SoC) should vehicle be charged in plan
|
||||
channel-type.evcc.vehiclePlanTime.label = Vehicle Plan Time
|
||||
channel-type.evcc.vehiclePlanTime.description = When the plan SoC should be reached
|
||||
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
|
||||
@ -103,7 +121,12 @@ 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.description = Name of EV
|
||||
channel-type.evcc.vehicleTitle.description = Title of vehicle
|
||||
|
||||
# channel types
|
||||
|
||||
channel-type.evcc.batteryPrioritySoC.label = Battery Priority SoC
|
||||
channel-type.evcc.batteryPrioritySoC.description = State of Charge for which the battery has priority over charging the ev when charging mode is "pv".
|
||||
|
||||
# thing status description
|
||||
|
||||
|
@ -67,13 +67,59 @@
|
||||
<category>BatteryLevel</category>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="batteryPrioritySoC">
|
||||
<channel-type id="batteryDischargeControl">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Battery Discharge Control</label>
|
||||
<description>Enable or disable battery discharge control</description>
|
||||
<category>Switch</category>
|
||||
<state readOnly="false">
|
||||
<options>
|
||||
<option value="ON">Enabled</option>
|
||||
<option value="OFF">Disabled</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="batteryMode">
|
||||
<item-type>String</item-type>
|
||||
<label>Battery Mode</label>
|
||||
<description>Current Battery Mode</description>
|
||||
<category>Battery</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="prioritySoC">
|
||||
<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>
|
||||
<description>State of Charge for which the battery has priority over charging the EV when charging mode is "pv"
|
||||
</description>
|
||||
<category>BatteryLevel</category>
|
||||
<state min="0" step="0.1" max="100" pattern="%.0f %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
<channel-type id="bufferSoC">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Battery Buffer SoC</label>
|
||||
<description>Until this State of Charge the discharging of a house battery is allowed in "pv" mode, when there is
|
||||
insufficient solar surplus (below the minimum charging power)
|
||||
</description>
|
||||
<category>BatteryLevel</category>
|
||||
<state min="0" step="0.1" max="100" pattern="%.0f %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
<channel-type id="bufferStartSoC">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Battery Buffer Start SoC</label>
|
||||
<description>State of Charge for which a charging session in "pv" mode is started, even if there is insufficient solar
|
||||
surplus
|
||||
</description>
|
||||
<category>BatteryLevel</category>
|
||||
<state min="0" step="0.1" max="100" pattern="%.0f %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
<channel-type id="residualPower">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Grid Residual Power</label>
|
||||
<description>Target operating point of the surplus regulation at the grid connection (grid meter)
|
||||
</description>
|
||||
<category>Energy</category>
|
||||
<state min="0" step="1" pattern="%.0f %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
<channel-type id="gridPower">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Grid Power</label>
|
||||
@ -96,7 +142,7 @@
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<!-- Channels for loadpoints -->
|
||||
<!-- Channel Types for loadpoints -->
|
||||
<channel-type id="activePhases">
|
||||
<item-type>Number</item-type>
|
||||
<label>Charging Active Phases</label>
|
||||
@ -128,14 +174,14 @@
|
||||
<channel-type id="chargeRemainingDuration">
|
||||
<item-type>Number:Time</item-type>
|
||||
<label>Charging Remaining Duration</label>
|
||||
<description>Remaining duration until target SoC is reached</description>
|
||||
<description>Remaining duration until limit 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>
|
||||
<description>Remaining energy until target SoC is reached</description>
|
||||
<description>Remaining energy until limit SoC is reached</description>
|
||||
<category>Energy</category>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
@ -186,19 +232,11 @@
|
||||
<state min="0" step="1" pattern="%.0f %unit%" readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="minSoC">
|
||||
<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>
|
||||
<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>
|
||||
<description>Charging mode: "off", "now", "minpv", "pv"</description>
|
||||
<category>String</category>
|
||||
<category>Heating</category>
|
||||
<state readOnly="false">
|
||||
<options>
|
||||
<option value="off">Off</option>
|
||||
@ -217,48 +255,27 @@
|
||||
<state min="0" step="1" max="3" pattern="%d" readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="targetEnergy">
|
||||
<channel-type id="limitEnergy">
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>Charging Target Energy</label>
|
||||
<label>Charging Limit 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">
|
||||
<channel-type id="limitSoC">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Charging Target SoC</label>
|
||||
<label>Charging Limit SoC</label>
|
||||
<description>Until which state of charge (SoC) should the vehicle be charged</description>
|
||||
<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>
|
||||
<description>When the target SoC should be reached</description>
|
||||
<category>Time</category>
|
||||
<state readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="targetTimeEnabled">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Charging Target Time Enabled</label>
|
||||
<description>Target time for charging enabled</description>
|
||||
<category>Switch</category>
|
||||
<state readOnly="false">
|
||||
<options>
|
||||
<option value="ON">Enabled</option>
|
||||
<option value="OFF">Disabled</option>
|
||||
</options>
|
||||
</state>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="title">
|
||||
<item-type>String</item-type>
|
||||
<label>Loadpoint Title</label>
|
||||
<description>Title of loadpoint</description>
|
||||
<category>Text</category>
|
||||
<category>PowerOutlet</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="vehicleConnected">
|
||||
@ -291,7 +308,7 @@
|
||||
<item-type>Number:Length</item-type>
|
||||
<label>Vehicle Odometer</label>
|
||||
<description>Total distance travelled by EV</description>
|
||||
<category></category>
|
||||
<category>MoveControl</category>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="vehiclePresent">
|
||||
@ -320,11 +337,66 @@
|
||||
<category>BatteryLevel</category>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="vehicleName">
|
||||
<item-type>String</item-type>
|
||||
<label>Vehicle Name</label>
|
||||
<description>The unique identifier of the EV used in the evcc configuration (containing no whitespaces nor special
|
||||
characters)</description>
|
||||
<category>Settings</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<!-- Channel Types for vehicles -->
|
||||
<channel-type id="vehicleTitle">
|
||||
<item-type>String</item-type>
|
||||
<label>Vehicle Title</label>
|
||||
<description>Name of EV</description>
|
||||
<category>Text</category>
|
||||
<description>Title of vehicle</description>
|
||||
<category>GarageDoor</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="vehicleMinSoC">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Vehicle Min SoC</label>
|
||||
<description>Minimum state of charge (SoC) a vehicle should have</description>
|
||||
<category>BatteryLevel</category>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="vehicleLimitSoC">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Vehicle Charging Limit SoC</label>
|
||||
<description>Until which state of charge (SoC) should the specific vehicle be charged</description>
|
||||
<category>BatteryLevel</category>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="vehiclePlanEnabled">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Vehicle Plan Enabled</label>
|
||||
<description>Plan for charging enabled</description>
|
||||
<category>Switch</category>
|
||||
<state readOnly="false">
|
||||
<options>
|
||||
<option value="ON">Enabled</option>
|
||||
<option value="OFF">Disabled</option>
|
||||
</options>
|
||||
</state>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="vehiclePlanSoC">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Vehicle Plan SoC</label>
|
||||
<description>Until which state of charge (SoC) should vehicle be charged in plan</description>
|
||||
<category>BatteryLevel</category>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="vehiclePlanTime">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>Vehicle Plan Time</label>
|
||||
<description>When the plan SoC should be reached</description>
|
||||
<category>Time</category>
|
||||
<state readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
|
Loading…
Reference in New Issue
Block a user