]> git.basschouten.com Git - openhab-addons.git/commitdiff
[evcc] Adjust to evcc version 0.123.1 (#16114)
authorlucaarn <luca@arnecke.name>
Mon, 5 Feb 2024 19:49:57 +0000 (20:49 +0100)
committerGitHub <noreply@github.com>
Mon, 5 Feb 2024 19:49:57 +0000 (20:49 +0100)
* 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>
bundles/org.openhab.binding.evcc/README.md
bundles/org.openhab.binding.evcc/src/main/java/org/openhab/binding/evcc/internal/EvccBindingConstants.java
bundles/org.openhab.binding.evcc/src/main/java/org/openhab/binding/evcc/internal/EvccHandler.java
bundles/org.openhab.binding.evcc/src/main/java/org/openhab/binding/evcc/internal/api/EvccAPI.java
bundles/org.openhab.binding.evcc/src/main/java/org/openhab/binding/evcc/internal/api/dto/Loadpoint.java
bundles/org.openhab.binding.evcc/src/main/java/org/openhab/binding/evcc/internal/api/dto/Plan.java [new file with mode: 0644]
bundles/org.openhab.binding.evcc/src/main/java/org/openhab/binding/evcc/internal/api/dto/Result.java
bundles/org.openhab.binding.evcc/src/main/java/org/openhab/binding/evcc/internal/api/dto/Vehicle.java [new file with mode: 0644]
bundles/org.openhab.binding.evcc/src/main/resources/OH-INF/i18n/evcc.properties
bundles/org.openhab.binding.evcc/src/main/resources/OH-INF/thing/thing-types.xml

index d4ee769da0cd69572b4d374d7cd39413cdcc528d..3a625b6864bc48a360d683061e1e38b4e4c4cffa 100644 (file)
@@ -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
         }
     }
 }
index 8434ed7df1a4f94b54dcf1e9aed50fb67658b836..a322d19abceb2522415a2cd0711fb877fb86c62a 100644 (file)
@@ -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;
index 064ddaf310eeba54b9478785a9cc6bf768e353be..abdd3351c03df7d4cef5f8cdf38fb31a92e3126a 100644 (file)
@@ -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,87 +85,92 @@ 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 (command instanceof QuantityType<?> qt) {
-                        evccAPI.setBatteryPrioritySoC(qt.toUnit(Units.PERCENT).intValue());
-                    } else if (command instanceof DecimalType dt) {
-                        evccAPI.setBatteryPrioritySoC(dt.intValue());
-                    } else {
-                        logger.debug("Command has wrong type, QuantityType or DecimalType required!");
-                    }
-                } else {
-                    int loadpoint = Integer.parseInt(groupId.substring(9)) + 1;
+                if (groupId.equals(CHANNEL_GROUP_ID_GENERAL)) {
                     switch (channelIdWithoutGroup) {
-                        case CHANNEL_LOADPOINT_MODE -> {
-                            if (command instanceof StringType) {
-                                evccAPI.setMode(loadpoint, command.toString());
-                            } else {
-                                logger.debug("Command has wrong type, StringType required!");
-                            }
-                        }
-                        case CHANNEL_LOADPOINT_MIN_SOC -> {
+                        case CHANNEL_PRIORITY_SOC -> {
                             if (command instanceof QuantityType<?> qt) {
-                                evccAPI.setMinSoC(loadpoint, qt.toUnit(Units.PERCENT).intValue());
+                                evccAPI.setPrioritySoC(qt.toUnit(Units.PERCENT).intValue());
                             } else if (command instanceof DecimalType dt) {
-                                evccAPI.setMinSoC(loadpoint, dt.intValue());
+                                evccAPI.setPrioritySoC(dt.intValue());
                             } else {
                                 logger.debug("Command has wrong type, QuantityType or DecimalType required!");
                             }
                         }
-                        case CHANNEL_LOADPOINT_TARGET_ENERGY -> {
+                        case CHANNEL_BUFFER_SOC -> {
                             if (command instanceof QuantityType<?> qt) {
-                                evccAPI.setTargetEnergy(loadpoint, qt.toUnit(Units.WATT_HOUR).floatValue());
+                                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 required!");
+                                logger.debug("Command has wrong type, QuantityType or DecimalType required!");
                             }
                         }
-                        case CHANNEL_LOADPOINT_TARGET_SOC -> {
+                        case CHANNEL_BUFFER_START_SOC -> {
                             if (command instanceof QuantityType<?> qt) {
-                                evccAPI.setTargetSoC(loadpoint, qt.toUnit(Units.PERCENT).intValue());
+                                evccAPI.setBufferStartSoC(qt.toUnit(Units.PERCENT).intValue());
                             } else if (command instanceof DecimalType dt) {
-                                evccAPI.setTargetSoC(loadpoint, dt.intValue());
+                                evccAPI.setBufferStartSoC(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);
-                                    }
-                                }
+                        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, DateTimeType required!");
+                                logger.debug("Command has wrong type, QuantityType or DecimalType required!");
                             }
                         }
-                        case CHANNEL_LOADPOINT_TARGET_TIME_ENABLED -> {
+                        case CHANNEL_BATTERY_DISCHARGE_CONTROL -> {
                             if (command == OnOffType.ON) {
-                                evccAPI.setTargetTime(loadpoint, targetTimeZDT);
-                                targetTimeEnabled = true;
+                                evccAPI.setBatteryDischargeControl(true);
                             } else if (command == OnOffType.OFF) {
-                                evccAPI.removeTargetTime(loadpoint);
-                                targetTimeEnabled = false;
+                                evccAPI.setBatteryDischargeControl(false);
                             } else {
                                 logger.debug("Command has wrong type, OnOffType required!");
                             }
                         }
+                        default -> {
+                            return;
+                        }
+                    }
+                } else if (groupId.startsWith(CHANNEL_GROUP_ID_LOADPOINT)) {
+                    int loadpoint = Integer.parseInt(groupId.substring(9)) + 1;
+                    switch (channelIdWithoutGroup) {
+                        case CHANNEL_LOADPOINT_MODE -> {
+                            if (command instanceof StringType) {
+                                evccAPI.setMode(loadpoint, command.toString());
+                            } else {
+                                logger.debug("Command has wrong type, StringType required!");
+                            }
+                        }
+                        case CHANNEL_LOADPOINT_LIMIT_ENERGY -> {
+                            if (command instanceof QuantityType<?> qt) {
+                                evccAPI.setLimitEnergy(loadpoint, qt.toUnit(Units.WATT_HOUR).floatValue());
+                            } else if (command instanceof DecimalType dt) {
+                                // DecimalType commands are interpreted as 'kWh'
+                                evccAPI.setLimitEnergy(loadpoint, dt.intValue() * 1000);
+                            } else {
+                                logger.debug("Command has wrong type, QuantityType required!");
+                            }
+                        }
+                        case CHANNEL_LOADPOINT_LIMIT_SOC -> {
+                            if (command instanceof QuantityType<?> qt) {
+                                evccAPI.setLimitSoC(loadpoint, qt.toUnit(Units.PERCENT).intValue());
+                            } else if (command instanceof DecimalType dt) {
+                                evccAPI.setLimitSoC(loadpoint, dt.intValue());
+                            } else {
+                                logger.debug("Command has wrong type, QuantityType or DecimalType 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;
+        }
+    }
 }
index 55d72e5137bf0fd475cf7e796773da5be019fa06..f658f23869b99e0b24e3dfd0e3f1762e030c00dc 100644 (file)
@@ -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 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 removeTargetTime(int loadpoint) throws EvccApiException {
-        return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/target/time", "DELETE");
+    public String removeVehiclePlan(String vehicleName) throws EvccApiException {
+        return httpRequest(this.host + EVCC_REST_API + "vehicles/" + vehicleName + "/plan/soc", "DELETE");
     }
 }
index 66227620b2fd4ed06b4d6a6e6a31d0a9ef1c251b..0a1328283a4fbf8ebf69b63e4a850d41b7278e40 100644 (file)
@@ -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("targetEnergy")
-    private float targetEnergy;
+    @SerializedName("limitEnergy")
+    private float limitEnergy;
 
-    @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
-     */
-    public boolean getPlanActive() {
-        return planActive;
-    }
-
-    /**
-     * @return target energy
+     * @return limit energy
      */
-    public float getTargetEnergy() {
-        return targetEnergy;
+    public float getLimitEnergy() {
+        return limitEnergy;
     }
 
     /**
-     * @return target state of charge (SoC)
+     * @return limit 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;
     }
 }
diff --git a/bundles/org.openhab.binding.evcc/src/main/java/org/openhab/binding/evcc/internal/api/dto/Plan.java b/bundles/org.openhab.binding.evcc/src/main/java/org/openhab/binding/evcc/internal/api/dto/Plan.java
new file mode 100644 (file)
index 0000000..85a1cad
--- /dev/null
@@ -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;
+    }
+}
index e007c2b0abbb79d26c65a6dc0e7f948392edc00e..bdbe0c74ab2aa5e9750a00381d4abfaa999f07df 100644 (file)
  */
 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;
+    }
 }
diff --git a/bundles/org.openhab.binding.evcc/src/main/java/org/openhab/binding/evcc/internal/api/dto/Vehicle.java b/bundles/org.openhab.binding.evcc/src/main/java/org/openhab/binding/evcc/internal/api/dto/Vehicle.java
new file mode 100644 (file)
index 0000000..26882d1
--- /dev/null
@@ -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;
+        }
+    }
+}
index bb9bc5a2b0005e76d0153a55610225f81397749d..ad2a371b3cdfcf44e480124df4ed498917c2293b 100644 (file)
@@ -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
 
index ed354200966f44645bede2cb2204c3c34c32d439..0f57096088e602797f1b5eaefc1fc6da71c0b8b7 100644 (file)
                <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>
                <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>
        <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>
                <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>
                <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">
                <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">
                <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>