mirror of
https://github.com/danieldemus/openhab-addons
synced 2026-07-29 12:34:21 +02:00
[evcc] Rework the binding, add missing datapoints and make it future ready (#18946)
* First commit of reworked binding Signed-off-by: Marcel Goerentz <m.goerentz@t-online.de>
This commit is contained in:
+1
-1
@@ -119,7 +119,7 @@
|
||||
/bundles/org.openhab.binding.ephemeris/ @clinique
|
||||
/bundles/org.openhab.binding.epsonprojector/ @mlobstein
|
||||
/bundles/org.openhab.binding.etherrain/ @dfad1469
|
||||
/bundles/org.openhab.binding.evcc/ @florian-h05
|
||||
/bundles/org.openhab.binding.evcc/ @florian-h05 @marcelGoerentz
|
||||
/bundles/org.openhab.binding.evohome/ @Nebula83
|
||||
/bundles/org.openhab.binding.exec/ @kgoderis
|
||||
/bundles/org.openhab.binding.feed/ @openhab/add-ons-maintainers
|
||||
|
||||
@@ -1,257 +1,84 @@
|
||||
# evcc Binding
|
||||
|
||||
This binding integrates [evcc](https://evcc.io), an extensible **E**lectric **V**ehicle **C**harge **C**ontroller and home energy management system.
|
||||
The binding is compatible to evcc [version 0.123.1](https://github.com/evcc-io/evcc/releases/tag/0.123.1) or newer and was tested with [version 0.125.0](https://github.com/evcc-io/evcc/releases/tag/0.125.0).
|
||||
The binding is compatible to evcc [version 0.123.1](https://github.com/evcc-io/evcc/releases/tag/0.123.1) or newer and was tested with [version 0.205.0](https://github.com/evcc-io/evcc/releases/tag/0.205.0).
|
||||
|
||||
You can easily install and upgrade evcc on openHABian using `sudo openhabian-config`.
|
||||
|
||||
evcc controls your wallbox(es) with multiple charging modes and allows you to charge your ev with your photovoltaik's excess current.
|
||||
evcc controls your wallbox(es) with multiple charging modes and allows you to charge your ev with your photovoltaic's excess current.
|
||||
To provide an intelligent charging control, evcc supports over 30 wallboxes and over 20 energy meters/home energy management systems from many manufacturers as well as electric vehicles from over 20 car manufacturers.
|
||||
Furthermore, evcc calculates your money savings.
|
||||
|
||||
This binding enables openHAB to retrieve status data from your evcc installation and to control the charging process.
|
||||
This binding enables openHAB to retrieve status data from your evcc instance and to control the charging process.
|
||||
For more advanced features like calculated savings, you have to visit the web UI of evcc.
|
||||
|
||||
This binding will create a file in your userdata folder, when it detects new datapoints in the response from evcc.
|
||||
This will help to add them to the binding and make them available with the next version of the binding.
|
||||
|
||||
## Supported Things
|
||||
|
||||
- `device`: A running evcc installation.
|
||||
- `server`: A running evcc instance. It will be used as the bridge for the other things
|
||||
- `battery`: A battery configured in your evcc instance.
|
||||
- `heating`: A heating loadpoint configured in your evcc instance.
|
||||
- `loadpoint`: A loadpoint configured in your evcc instance.
|
||||
- `pv`: A photovoltaic system configured in your evcc instance.
|
||||
- `site`: The relevant site data from your evcc instance.
|
||||
- `vehicle`: A vehicle configured in your evcc instance
|
||||
|
||||
## Discovery
|
||||
|
||||
No auto discovery supported.
|
||||
The bridge will discover the things automatically in the background.
|
||||
|
||||
## Thing Configuration
|
||||
## `server` Bridge Configuration
|
||||
|
||||
### `device` Thing Configuration
|
||||
| Parameter | Type | Description | Advanced | Required |
|
||||
|-----------------|---------|----------------------------------------------------------|----------|----------|
|
||||
| schema | String | Schema to connect to your instance (http or https) | No | Yes |
|
||||
| host | String | IP or hostname running your evcc instance | No | Yes |
|
||||
| port | Integer | Port of your evcc instance | Yes | Yes |
|
||||
| refreshInterval | Number | Interval the status is polled in seconds (minimum is 15) | Yes | Yes |
|
||||
|
||||
| Parameter | Type | Description | Advanced | Required |
|
||||
|-----------------|--------|----------------------------------------------------------|----------|----------|
|
||||
| url | String | URL of evcc web UI, e.g. `https://demo.evcc.io` | No | Yes |
|
||||
| refreshInterval | Number | Interval the status is polled in seconds (minimum is 15) | Yes | No |
|
||||
Default value for _refreshInterval_ is 30 seconds.
|
||||
|
||||
Default value for _refreshInterval_ is 60 seconds.
|
||||
## Thing(s) Configuration
|
||||
|
||||
The Things don't have a configuration. They will be set up automatically when a bridge has been configured.
|
||||
You can add them via file configuration or in the openHAB UI.
|
||||
|
||||
## Channels
|
||||
|
||||
### General Channels
|
||||
|
||||
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#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 |
|
||||
| general#version | String | R | Current evcc version |
|
||||
| general#availableVersion | String | R | Available evcc update version |
|
||||
|
||||
### Loadpoint Channels
|
||||
|
||||
Those channels exist per configured loadpoint.
|
||||
Please note that you have to replace _\<N\>_ with your loadpoint id/number.
|
||||
|
||||
| Channel | Type | Read/Write | Description |
|
||||
|-----------------------------------------------|------------------------|------------|-------------------------------------------------------------------------------------------------------------------|
|
||||
| loadpoint\<N\>#activePhases | Number | R | Current number of active phases while charging |
|
||||
| loadpoint\<N\>#chargeCurrent | Number:ElectricCurrent | R | Current amperage per connected phase while charging |
|
||||
| loadpoint\<N\>#chargeDuration | Number:Time | R | Charging duration |
|
||||
| loadpoint\<N\>#chargeRemainingDuration | Number:Time | R | Remaining duration until limit SoC is reached |
|
||||
| loadpoint\<N\>#chargeRemainingEnergy | Number:Energy | R | Remaining energy until limit SoC is reached |
|
||||
| loadpoint\<N\>#chargePower | Number:Power | R | Current power of charging |
|
||||
| loadpoint\<N\>#chargedEnergy | Number:Energy | R | Energy charged since plugged-in |
|
||||
| loadpoint\<N\>#charging | Switch | R | Loadpoint is currently charging |
|
||||
| loadpoint\<N\>#enabled | Switch | R | Charging enabled (mode is not "off") |
|
||||
| loadpoint\<N\>#maxCurrent | Number:ElectricCurrent | RW | Maximum amperage per connected phase with which the car should be charged |
|
||||
| loadpoint\<N\>#minCurrent | Number:ElectricCurrent | RW | Minimum amperage per connected phase with which the car should be charged |
|
||||
| loadpoint\<N\>#mode | String | RW | Charging mode: "off", "now", "minpv", "pv" |
|
||||
| loadpoint\<N\>#phases | Number | RW | The maximum number of phases which can be used |
|
||||
| loadpoint\<N\>#limitEnergy | Number:Energy | RW | Amount of energy to charge the vehicle with |
|
||||
| loadpoint\<N\>#title | String | R | Title of loadpoint |
|
||||
| loadpoint\<N\>#vehicleConnected | Switch | R | Whether vehicle is connected to loadpoint |
|
||||
| loadpoint\<N\>#vehicleConnectedDuration | Number:Time | R | Duration the vehicle is connected to loadpoint |
|
||||
| loadpoint\<N\>#vehicleOdometer | Number:Length | R | Total distance travelled by EV |
|
||||
| loadpoint\<N\>#vehiclePresent | Switch | R | Whether evcc is able to get data from vehicle |
|
||||
| loadpoint\<N\>#vehicleRange | Number:Length | R | Battery range for EV |
|
||||
| loadpoint\<N\>#vehicleName | String | R | The unique identifier of the EV used in the evcc configuration (containing no whitespaces nor special characters) |
|
||||
| loadpoint\<N\>#chargerFeatureHeating | Switch | R | 'True' for heating device: State of Charge in Degree instead of Percent |
|
||||
| loadpoint\<N\>#chargerFeatureIntegratedDevice | Switch | R | 'True' for integrated device: Operate without a "vehicle" (e.g. heat pump, eBike) |
|
||||
|
||||
#### Loadpoint Channels Specific for Vehicles
|
||||
|
||||
| Channel | Type | Read/Write | Description |
|
||||
|----------------------------------|----------------------|------------|-------------------------------------------------------------------------|
|
||||
| loadpoint\<N\>#limitSoC | Number:Dimensionless | RW | Until which state of charge (SoC) should the vehicle be charged |
|
||||
| loadpoint\<N\>#effectiveLimitSoC | Number:Dimensionless | R | Effective state of charge (SoC) until which the vehicle will be charged |
|
||||
| loadpoint\<N\>#vehicleSoC | Number:Dimensionless | R | Current State of Charge of EV |
|
||||
|
||||
#### Loadpoint Channels Specific for Heating Devices
|
||||
|
||||
| Channel | Type | Read/Write | Description |
|
||||
|------------------------------------------|--------------------|------------|----------------------------------------------------------------------|
|
||||
| loadpoint\<N\>#limitTemperature | Number:Temperature | RW | Until which Temperature should the heating device be charged |
|
||||
| loadpoint\<N\>#effectiveLimitTemperature | Number:Temperature | R | Effective Temperature until which the heating device will be charged |
|
||||
| loadpoint\<N\>#vehicleTemperature | Number:Temperature | R | Current Temperature of the heating device |
|
||||
|
||||
### Vehicle Channels
|
||||
|
||||
Those channels exist:
|
||||
|
||||
- 1 per configured loadpoint with `chargerFeatureHeating = false`:
|
||||
- These channels point to the heating device that is currently active/connected at/to the loadpoint
|
||||
- Please note that you have to replace _\<N\>_ with your loadpoint id/number
|
||||
- 1 per configured vehicle:
|
||||
- Please note that you have to replace _\<ID\>_ with your vehicle id/name
|
||||
|
||||
| Channel | Type | Read/Write | Description |
|
||||
|----------------------------------------------------|----------------------|------------|--------------------------------------------------------------------------|
|
||||
| [loadpoint\<N\>\|vehicle\<ID\]>#vehicleTitle | String | R | Title of vehicle |
|
||||
| [loadpoint\<N\>\|vehicle\<ID\]>#vehicleMinSoC | Number:Dimensionless | RW | Minimum state of charge (SoC) a vehicle should have |
|
||||
| [loadpoint\<N\>\|vehicle\<ID\]>#vehicleLimitSoC | Number:Dimensionless | RW | Until which state of charge (SoC) should the specific vehicle be charged |
|
||||
| [loadpoint\<N\>\|vehicle\<ID\]>#vehicleCapacity | Number:Energy | R | Capacity of EV battery |
|
||||
| [loadpoint\<N\>\|vehicle\<ID\]>#vehiclePlanEnabled | Switch | RW | Plan for charging enabled |
|
||||
| [loadpoint\<N\>\|vehicle\<ID\]>#vehiclePlanSoC | Number:Dimensionless | RW | Until which state of charge (SoC) should vehicle be charged in plan |
|
||||
| [loadpoint\<N\>\|vehicle\<ID\]>#vehiclePlanTime | DateTime | RW | When the plan SoC should be reached |
|
||||
|
||||
### Heating Channels
|
||||
|
||||
Those channels exist:
|
||||
|
||||
- 1 per configured loadpoint with `chargerFeatureHeating = true`:
|
||||
- These channels point to the heating device that is currently active/connected at/to the loadpoint
|
||||
- Please note that you have to replace _\<N\>_ with your loadpoint id/number
|
||||
- 1 per configured heating device:
|
||||
- Please note that you have to replace _\<ID\>_ with your heating device id/name
|
||||
|
||||
| Channel | Type | Read/Write | Description |
|
||||
|---------------------------------------------------------|--------------------|------------|-----------------------------------------------------------------------|
|
||||
| [loadpoint\<N\>\|heating\<ID\]>#heatingTitle | String | R | Title of heating device |
|
||||
| [loadpoint\<N\>\|heating\<ID\]>#heatingMinTemperature | Number:Temperature | RW | Minimum Temperature a heating device should have |
|
||||
| [loadpoint\<N\>\|heating\<ID\]>#heatingLimitTemperature | Number:Temperature | RW | Until which Temperature should the specific heating device be charged |
|
||||
| [loadpoint\<N\>\|heating\<ID\]>#heatingCapacity | Number:Energy | R | Capacity of heating device |
|
||||
| [loadpoint\<N\>\|heating\<ID\]>#heatingPlanEnabled | Switch | RW | Plan for charging enabled |
|
||||
| [loadpoint\<N\>\|heating\<ID\]>#heatingPlanTemperature | Number:Temperature | RW | Until which Temperature should heating device be charged in plan |
|
||||
| [loadpoint\<N\>\|heating\<ID\]>#heatingPlanTime | DateTime | RW | When the plan Temperature should be reached |
|
||||
evcc Things can have several channels based corresponding on their capabilities.
|
||||
These channels are dynamically added to the Thing during their initialization; therefore, there is no list of possible channels in this documentation.
|
||||
|
||||
## Full Example
|
||||
|
||||
### Thing(s)
|
||||
### `demo.things` Example
|
||||
|
||||
```java
|
||||
Thing evcc:device:demo "evcc Demo" [url="https://demo.evcc.io", refreshInterval=60]
|
||||
```
|
||||
|
||||
### Items
|
||||
|
||||
```java
|
||||
// General
|
||||
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"}
|
||||
String evcc_version "Version [%s]" <text> {channel="evcc:device:demo:general#version"}
|
||||
String evcc_availableVersion "Available Version [%s]" <text> {channel="evcc:device:demo:general#availableVersion"}
|
||||
|
||||
// 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"}
|
||||
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"}
|
||||
Number:Dimensionless evcc_loadpoint0_effectiveLimitSoC "Effective Limit SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:loadpoint0#effectiveLimitSoC"}
|
||||
String evcc_loadpoint0_title "Loadpoint title [%s]" <text> {channel="evcc:device:demo:loadpoint0#title"}
|
||||
Switch evcc_loadpoint0_chargerFeatureHeating "Feature: Heating [%s]" <switch> {channel="evcc:device:demo:loadpoint0#chargerFeatureHeating"}
|
||||
Switch evcc_loadpoint0_chargerFeatureIntegratedDevice "Feature: Integrated Device [%s]" <switch> {channel="evcc:device:demo:loadpoint0#chargerFeatureIntegratedDevice"}
|
||||
|
||||
// Loadpoint vehicle channels
|
||||
Switch evcc_loadpoint0_vehicleConnected "Vehicle connected [%s]" <switch> {channel="evcc:device:demo:loadpoint0#vehicleConnected"}
|
||||
Number:Time evcc_loadpoint0_vehicleConnectedDuration "Vehicle connected duration [%.1f h]" <time> {channel="evcc:device:demo:loadpoint0#vehicleConnectedDuration"}
|
||||
Number: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 on loadpoint
|
||||
String evcc_loadpoint0current_vehicleTitle "Vehicle title [%s]" <text> {channel="evcc:device:demo:loadpoint0current#vehicleTitle"}
|
||||
Number:Dimensionless evcc_loadpoint0current_vehicleMinSoC "Vehicle minimum SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:loadpoint0current#vehicleMinSoC"}
|
||||
Number:Dimensionless evcc_loadpoint0current_vehicleLimitSoC "Vehicle limit SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:loadpoint0current#vehicleLimitSoC"}
|
||||
Number:Energy evcc_loadpoint0current_vehicleCapacity "Vehicle capacity [%.0f kWh]" <batterylevel> {channel="evcc:device:demo:loadpoint0current#vehicleCapacity"}
|
||||
Switch evcc_loadpoint0current_vehiclePlanEnabled "Vehicle plan enabled [%s]" <switch> {channel="evcc:device:demo:loadpoint0current#vehiclePlanEnabled"}
|
||||
Number:Dimensionless evcc_loadpoint0current_vehiclePlanSoC "Vehicle plan SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:loadpoint0current#vehiclePlanSoC"}
|
||||
DateTime evcc_loadpoint0current_vehiclePlanTime "Vehicle plan time [%1$td.%1$tm.%1$tY, %1$tH:%1$tM]" <time> {channel="evcc:device:demo:loadpoint0current#vehiclePlanTime"}
|
||||
```
|
||||
|
||||
### Sitemap
|
||||
|
||||
```perl
|
||||
sitemap evcc label="evcc Demo" {
|
||||
Frame label="General" {
|
||||
Text item=evcc_batteryPower
|
||||
Text item=evcc_batterySoC
|
||||
Text item=evcc_gridPower
|
||||
Text item=evcc_homePower
|
||||
Text item=evcc_pvPower
|
||||
}
|
||||
Frame label="Loadpoint 0" {
|
||||
Text item=evcc_loadpoint0_title
|
||||
Text item=evcc_loadpoint0_enabled label="Charging" {
|
||||
Text item=evcc_loadpoint0_charging
|
||||
Text item=evcc_loadpoint0_chargePower
|
||||
Text item=evcc_loadpoint0_chargeCurrent
|
||||
Text item=evcc_loadpoint0_activePhases
|
||||
Text item=evcc_loadpoint0_chargeDuration
|
||||
Text item=evcc_loadpoint0_chargeRemainingDuration
|
||||
Text item=evcc_loadpoint0_chargeRemainingEnergy
|
||||
}
|
||||
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_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
|
||||
Setpoint item=evcc_loadpoint0_phases minValue=1 maxValue=3 step=2
|
||||
}
|
||||
Text item=evcc_loadpoint0_vehicleName label="Vehicle" {
|
||||
Text item=evcc_loadpoint0current_vehicleCapacity
|
||||
Text item=evcc_loadpoint0_vehicleOdometer
|
||||
Text item=evcc_loadpoint0_vehicleRange
|
||||
Text item=evcc_loadpoint0_vehicleSoC
|
||||
Text item=evcc_loadpoint0current_vehicleTitle
|
||||
Setpoint item=evcc_loadpoint0current_vehicleMinSoC minValue=0 maxValue=100 step=5
|
||||
Setpoint item=evcc_loadpoint0current_vehicleLimitSoC minValue=5 maxValue=100 step=5
|
||||
Switch item=evcc_loadpoint0current_vehiclePlanEnabled
|
||||
Setpoint item=evcc_loadpoint0current_vehiclePlanSoC minValue=5 maxValue=100 step=5
|
||||
Input item=evcc_loadpoint0current_vehiclePlanTime
|
||||
}
|
||||
}
|
||||
Bridge evcc:server:demo-server "Demo" [scheme="https", url="demo.evcc.io", port=80, refreshInterval=30] {
|
||||
// This thing will only exist once per evcc instance
|
||||
Thing site demo-site "Site - evcc Demo"
|
||||
// You can define as many Battery things as you have batteries configured in your evcc instance
|
||||
Thing battery demo-battery1 "Battery - evcc Demo Battery 1"
|
||||
..
|
||||
// You can define as many PV things as you have photovoltaics configured in your evcc instance
|
||||
Thing pv demo-pv1 "PV - evcc Demo Photovoltaic 1"
|
||||
..
|
||||
// You can define as many Loadpoint things as you have loadpoints configured in your evcc instance
|
||||
Thing loadpoint demo-loadpoint-carport "Loadpoint - evcc Demo Loadpoint 1"
|
||||
..
|
||||
// You can define as many Vehicle things as you have vehicles configured in your evcc instance
|
||||
Thing vehicle demo-vehicle1 "Vehicle - evcc Demo Vehicle 1"
|
||||
..
|
||||
}
|
||||
```
|
||||
|
||||
### `demo.items` Example
|
||||
|
||||
```java
|
||||
Number GridPower "Grid Power" { channel="evcc:site:demo-server:demo-site:site-grid-power" }
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If you need additional data that can be read out of the API response please reach out to the openHAB community.
|
||||
|
||||
+44
-184
@@ -12,206 +12,66 @@
|
||||
*/
|
||||
package org.openhab.binding.evcc.internal;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.library.CoreItemFactory;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.type.ChannelTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link EvccBindingConstants} class defines common constants, which are
|
||||
* used across the whole binding.
|
||||
* The {@link EvccBindingConstants} class contains fields mapping thing configuration parameters.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
* @author Luca Arnecke - Update to evcc version 0.123.1
|
||||
* @author Marcel Goerentz - Reworked the binding
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EvccBindingConstants {
|
||||
|
||||
private static final String BINDING_ID = "evcc";
|
||||
public 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";
|
||||
public static final String CHANNEL_GROUP_ID_HEATING = "heating";
|
||||
public static final String CHANNEL_GROUP_ID_CURRENT = "current";
|
||||
public static final ThingTypeUID THING_TYPE_SERVER = new ThingTypeUID(BINDING_ID, "server");
|
||||
public static final ThingTypeUID THING_TYPE_SITE = new ThingTypeUID(BINDING_ID, "site");
|
||||
public static final ThingTypeUID THING_TYPE_LOADPOINT = new ThingTypeUID(BINDING_ID, "loadpoint");
|
||||
public static final ThingTypeUID THING_TYPE_VEHICLE = new ThingTypeUID(BINDING_ID, "vehicle");
|
||||
public static final ThingTypeUID THING_TYPE_PV = new ThingTypeUID(BINDING_ID, "pv");
|
||||
public static final ThingTypeUID THING_TYPE_BATTERY = new ThingTypeUID(BINDING_ID, "battery");
|
||||
public static final ThingTypeUID THING_TYPE_HEATING = new ThingTypeUID(BINDING_ID, "heating");
|
||||
public static final ThingTypeUID THING_TYPE_STATISTICS = new ThingTypeUID(BINDING_ID, "statistics");
|
||||
|
||||
// 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_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";
|
||||
public static final String CHANNEL_VERSION = "version";
|
||||
public static final String CHANNEL_AVAILABLE_VERSION = "availableVersion";
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Set.of(THING_TYPE_SITE, THING_TYPE_VEHICLE,
|
||||
THING_TYPE_LOADPOINT, THING_TYPE_BATTERY, THING_TYPE_PV, THING_TYPE_HEATING, THING_TYPE_STATISTICS);
|
||||
|
||||
public static final String CHANNEL_LOADPOINT_ACTIVE_PHASES = "activePhases";
|
||||
public static final String CHANNEL_LOADPOINT_CHARGE_CURRENT = "chargeCurrent";
|
||||
public static final String CHANNEL_LOADPOINT_CHARGE_DURATION = "chargeDuration";
|
||||
public static final String CHANNEL_LOADPOINT_CHARGE_POWER = "chargePower";
|
||||
public static final String CHANNEL_LOADPOINT_CHARGE_REMAINING_DURATION = "chargeRemainingDuration";
|
||||
public static final String CHANNEL_LOADPOINT_CHARGE_REMAINING_ENERGY = "chargeRemainingEnergy";
|
||||
public static final String CHANNEL_LOADPOINT_CHARGED_ENERGY = "chargedEnergy";
|
||||
public static final String CHANNEL_LOADPOINT_CHARGING = "charging";
|
||||
public static final String CHANNEL_LOADPOINT_CONNECTED = "vehicleConnected";
|
||||
public static final String CHANNEL_LOADPOINT_CONNECTED_DURATION = "vehicleConnectedDuration";
|
||||
public static final String CHANNEL_LOADPOINT_ENABLED = "enabled";
|
||||
public static final String CHANNEL_LOADPOINT_MAX_CURRENT = "maxCurrent";
|
||||
public static final String CHANNEL_LOADPOINT_MIN_CURRENT = "minCurrent";
|
||||
public static final String CHANNEL_LOADPOINT_MODE = "mode";
|
||||
public static final String CHANNEL_LOADPOINT_PHASES = "phases";
|
||||
public static final String CHANNEL_LOADPOINT_LIMIT_ENERGY = "limitEnergy";
|
||||
public static final String CHANNEL_LOADPOINT_LIMIT_SOC = "limitSoC";
|
||||
public static final String CHANNEL_LOADPOINT_LIMIT_TEMPERATURE = "limitTemperature";
|
||||
public static final String CHANNEL_LOADPOINT_EFFECTIVE_LIMIT_SOC = "effectiveLimitSoC";
|
||||
public static final String CHANNEL_LOADPOINT_EFFECTIVE_LIMIT_TEMPERATURE = "effectiveLimitTemperature";
|
||||
public static final String CHANNEL_LOADPOINT_TITLE = "title";
|
||||
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_TEMPERATURE = "vehicleTemperature";
|
||||
public static final String CHANNEL_LOADPOINT_VEHICLE_NAME = "vehicleName";
|
||||
public static final String CHANNEL_LOADPOINT_CHARGER_FEATURE_HEATING = "chargerFeatureHeating";
|
||||
public static final String CHANNEL_LOADPOINT_CHARGER_FEATURE_INTEGRATED_DEVICE = "chargerFeatureIntegratedDevice";
|
||||
public static final String PROPERTY_ID = "id";
|
||||
public static final String PROPERTY_INDEX = "index";
|
||||
public static final String PROPERTY_TYPE = "type";
|
||||
public static final String PROPERTY_TITLE = "title";
|
||||
public static final String PROPERTY_SITE_TITLE = "siteTitle";
|
||||
|
||||
public static final String CHANNEL_VEHICLE_TITLE = "vehicleTitle";
|
||||
public static final String CHANNEL_HEATING_TITLE = "heatingTitle";
|
||||
public static final String CHANNEL_VEHICLE_MIN_SOC = "vehicleMinSoC";
|
||||
public static final String CHANNEL_HEATING_MIN_TEMPERATURE = "heatingMinTemperature";
|
||||
public static final String CHANNEL_VEHICLE_LIMIT_SOC = "vehicleLimitSoC";
|
||||
public static final String CHANNEL_HEATING_LIMIT_TEMPERATURE = "heatingLimitTemperature";
|
||||
public static final String CHANNEL_VEHICLE_CAPACITY = "vehicleCapacity";
|
||||
public static final String CHANNEL_HEATING_CAPACITY = "heatingCapacity";
|
||||
public static final String CHANNEL_VEHICLE_PLAN_ENABLED = "vehiclePlanEnabled";
|
||||
public static final String CHANNEL_HEATING_PLAN_ENABLED = "heatingPlanEnabled";
|
||||
public static final String CHANNEL_VEHICLE_PLAN_SOC = "vehiclePlanSoC";
|
||||
public static final String CHANNEL_HEATING_PLAN_TEMPERATURE = "heatingPlanTemperature";
|
||||
public static final String CHANNEL_VEHICLE_PLAN_TIME = "vehiclePlanTime";
|
||||
public static final String CHANNEL_HEATING_PLAN_TIME = "heatingPlanTime";
|
||||
public static final String API_PATH_LOADPOINTS = "/loadpoints";
|
||||
public static final String API_PATH_VEHICLES = "/vehicles";
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
public static final ThingTypeUID THING_TYPE_DEVICE = new ThingTypeUID(BINDING_ID, "device");
|
||||
public static final String PROPERTY_TYPE_BATTERY = "battery";
|
||||
public static final String PROPERTY_TYPE_HEATING = "heating";
|
||||
public static final String PROPERTY_TYPE_LOADPOINT = "loadpoint";
|
||||
public static final String PROPERTY_TYPE_PV = "pv";
|
||||
public static final String PROPERTY_TYPE_SITE = "site";
|
||||
public static final String PROPERTY_TYPE_STATISTICS = "statistics";
|
||||
public static final String PROPERTY_TYPE_VEHICLE = "vehicle";
|
||||
|
||||
// List of all Channel Type UIDs
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_BATTERY_CAPACITY = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_BATTERY_CAPACITY);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_BATTERY_POWER = new ChannelTypeUID(BINDING_ID,
|
||||
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_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);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_VERSION = new ChannelTypeUID(BINDING_ID, CHANNEL_VERSION);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_AVAILABLE_VERSION = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_AVAILABLE_VERSION);
|
||||
public static final String JSON_MEMBER_BATTERY = "battery";
|
||||
public static final String JSON_MEMBER_LOADPOINTS = "loadpoints";
|
||||
public static final String JSON_MEMBER_PV = "pv";
|
||||
public static final String JSON_MEMBER_STATISTICS = "statistics";
|
||||
public static final String JSON_MEMBER_VEHICLES = "vehicles";
|
||||
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_ACTIVE_PHASES = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_ACTIVE_PHASES);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_CHARGE_CURRENT = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_CHARGE_CURRENT);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_CHARGE_DURATION = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_CHARGE_DURATION);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_CHARGE_POWER = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_CHARGE_POWER);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_CHARGE_REMAINING_DURATION = new ChannelTypeUID(
|
||||
BINDING_ID, CHANNEL_LOADPOINT_CHARGE_REMAINING_DURATION);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_CHARGE_REMAINING_ENERGY = new ChannelTypeUID(
|
||||
BINDING_ID, CHANNEL_LOADPOINT_CHARGE_REMAINING_ENERGY);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_CHARGED_ENERGY = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_CHARGED_ENERGY);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_CHARGING = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_CHARGING);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_CONNECTED = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_CONNECTED);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_CONNECTED_DURATION = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_CONNECTED_DURATION);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_ENABLED = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_ENABLED);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_MAX_CURRENT = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_MAX_CURRENT);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_MIN_CURRENT = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_MIN_CURRENT);
|
||||
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_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_LIMIT_TEMPERATURE = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_LIMIT_TEMPERATURE);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_EFFECTIVE_LIMIT_SOC = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_EFFECTIVE_LIMIT_SOC);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_EFFECTIVE_LIMIT_TEMPERATURE = new ChannelTypeUID(
|
||||
BINDING_ID, CHANNEL_LOADPOINT_EFFECTIVE_LIMIT_TEMPERATURE);
|
||||
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_ODOMETER = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_VEHICLE_ODOMETER);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_PRESENT = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_VEHICLE_PRESENT);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_RANGE = new ChannelTypeUID(BINDING_ID,
|
||||
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_TEMPERATURE = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_LOADPOINT_VEHICLE_TEMPERATURE);
|
||||
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_LOADPOINT_CHARGER_FEATURE_HEATING = new ChannelTypeUID(
|
||||
BINDING_ID, CHANNEL_LOADPOINT_CHARGER_FEATURE_HEATING);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_CHARGER_FEATURE_INTEGRATED_DEVICE = new ChannelTypeUID(
|
||||
BINDING_ID, CHANNEL_LOADPOINT_CHARGER_FEATURE_INTEGRATED_DEVICE);
|
||||
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_VEHICLE_TITLE = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_VEHICLE_TITLE);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_HEATING_TITLE = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_HEATING_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_HEATING_MIN_TEMPERATURE = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_HEATING_MIN_TEMPERATURE);
|
||||
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_HEATING_LIMIT_TEMPERATURE = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_HEATING_LIMIT_TEMPERATURE);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_VEHICLE_CAPACITY = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_VEHICLE_CAPACITY);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_HEATING_CAPACITY = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_HEATING_CAPACITY);
|
||||
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_HEATING_PLAN_ENABLED = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_HEATING_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_HEATING_PLAN_TEMPERATURE = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_HEATING_PLAN_TEMPERATURE);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_VEHICLE_PLAN_TIME = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_VEHICLE_PLAN_TIME);
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_HEATING_PLAN_TIME = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_HEATING_PLAN_TIME);
|
||||
|
||||
public static final int CONNECTION_TIMEOUT_MILLISEC = 5000;
|
||||
public static final int LONG_CONNECTION_TIMEOUT_MILLISEC = 60000;
|
||||
public static final String EVCC_REST_API = "/api/";
|
||||
public static final String NUMBER_CURRENCY = CoreItemFactory.NUMBER + ":Currency";
|
||||
public static final String NUMBER_DIMENSIONLESS = CoreItemFactory.NUMBER + ":Dimensionless";
|
||||
public static final String NUMBER_ELECTRIC_CURRENT = CoreItemFactory.NUMBER + ":ElectricCurrent";
|
||||
public static final String NUMBER_EMISSION_INTENSITY = CoreItemFactory.NUMBER + ":EmissionIntensity";
|
||||
public static final String NUMBER_ENERGY = CoreItemFactory.NUMBER + ":Energy";
|
||||
public static final String NUMBER_POWER = CoreItemFactory.NUMBER + ":Power";
|
||||
public static final String NUMBER_TIME = CoreItemFactory.NUMBER + ":Time";
|
||||
public static final String NUMBER_LENGTH = CoreItemFactory.NUMBER + ":Length";
|
||||
public static final String NUMBER_ENERGY_PRICE = CoreItemFactory.NUMBER + ":EnergyPrice";
|
||||
}
|
||||
|
||||
+5
-10
@@ -13,22 +13,17 @@
|
||||
package org.openhab.binding.evcc.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* The {@link EvccConfiguration} class contains fields mapping thing configuration parameters.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
* @author Marcel Goerentz - Rework the binding
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EvccConfiguration {
|
||||
|
||||
/**
|
||||
* URL of the evcc instance, e.g. https://demo.evcc.io
|
||||
*/
|
||||
public @Nullable String url;
|
||||
/**
|
||||
* Interval for state fetching in seconds.
|
||||
*/
|
||||
public int refreshInterval = 60;
|
||||
public String host = "";
|
||||
public int pollInterval = 30;
|
||||
public int port = 7070;
|
||||
public String scheme = "http";
|
||||
}
|
||||
|
||||
-1046
File diff suppressed because it is too large
Load Diff
+45
-14
@@ -14,16 +14,26 @@ package org.openhab.binding.evcc.internal;
|
||||
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.*;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.binding.evcc.internal.handler.EvccBatteryHandler;
|
||||
import org.openhab.binding.evcc.internal.handler.EvccBridgeHandler;
|
||||
import org.openhab.binding.evcc.internal.handler.EvccHeatingHandler;
|
||||
import org.openhab.binding.evcc.internal.handler.EvccLoadpointHandler;
|
||||
import org.openhab.binding.evcc.internal.handler.EvccPvHandler;
|
||||
import org.openhab.binding.evcc.internal.handler.EvccSiteHandler;
|
||||
import org.openhab.binding.evcc.internal.handler.EvccStatisticsHandler;
|
||||
import org.openhab.binding.evcc.internal.handler.EvccVehicleHandler;
|
||||
import org.openhab.core.i18n.LocaleProvider;
|
||||
import org.openhab.core.i18n.TranslationProvider;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
import org.openhab.core.thing.type.ChannelTypeRegistry;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
@@ -33,33 +43,54 @@ import org.osgi.service.component.annotations.Reference;
|
||||
* handlers.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
* @author Marcel Goerentz - Rework the binding
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(configurationPid = "binding.evcc", service = ThingHandlerFactory.class)
|
||||
public class EvccHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_DEVICE);
|
||||
|
||||
private final TimeZoneProvider timeZoneProvider;
|
||||
private final HttpClientFactory httpClientFactory;
|
||||
private final ChannelTypeRegistry channelTypeRegistry;
|
||||
private final TranslationProvider i18nProvider;
|
||||
private final LocaleProvider localeProvider;
|
||||
|
||||
@Activate
|
||||
public EvccHandlerFactory(final @Reference TimeZoneProvider timeZoneProvider) {
|
||||
this.timeZoneProvider = timeZoneProvider;
|
||||
public EvccHandlerFactory(@Reference HttpClientFactory httpClientFactory,
|
||||
@Reference ChannelTypeRegistry channelTypeRegistry, @Reference TranslationProvider i18nProvider,
|
||||
@Reference LocaleProvider localeProvider) {
|
||||
this.httpClientFactory = httpClientFactory;
|
||||
this.channelTypeRegistry = channelTypeRegistry;
|
||||
this.i18nProvider = i18nProvider;
|
||||
this.localeProvider = localeProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
|
||||
return SUPPORTED_THING_TYPES.contains(thingTypeUID) || THING_TYPE_SERVER.equals(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
ThingHandler handler = null;
|
||||
ThingTypeUID type = thing.getThingTypeUID();
|
||||
|
||||
if (THING_TYPE_DEVICE.equals(thingTypeUID)) {
|
||||
return new EvccHandler(thing, timeZoneProvider);
|
||||
if (THING_TYPE_SERVER.equals(type)) {
|
||||
handler = new EvccBridgeHandler((Bridge) thing, httpClientFactory, i18nProvider, localeProvider);
|
||||
} else if (THING_TYPE_SITE.equals(type)) {
|
||||
handler = new EvccSiteHandler(thing, channelTypeRegistry);
|
||||
} else if (THING_TYPE_VEHICLE.equals(type)) {
|
||||
handler = new EvccVehicleHandler(thing, channelTypeRegistry);
|
||||
} else if (THING_TYPE_LOADPOINT.equals(type)) {
|
||||
handler = new EvccLoadpointHandler(thing, channelTypeRegistry);
|
||||
} else if (THING_TYPE_HEATING.equals(type)) {
|
||||
handler = new EvccHeatingHandler(thing, channelTypeRegistry);
|
||||
} else if (THING_TYPE_BATTERY.equals(type)) {
|
||||
handler = new EvccBatteryHandler(thing, channelTypeRegistry);
|
||||
} else if (THING_TYPE_PV.equals(type)) {
|
||||
handler = new EvccPvHandler(thing, channelTypeRegistry);
|
||||
} else if (THING_TYPE_STATISTICS.equals(type)) {
|
||||
handler = new EvccStatisticsHandler(thing, channelTypeRegistry);
|
||||
}
|
||||
|
||||
return null;
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
|
||||
-173
@@ -1,173 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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;
|
||||
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.EVCC_REST_API;
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.LONG_CONNECTION_TIMEOUT_MILLISEC;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.evcc.internal.api.dto.Result;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.io.net.http.HttpUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
/**
|
||||
* The {@link EvccAPI} is responsible for API calls to evcc.
|
||||
* 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 {
|
||||
private final Logger logger = LoggerFactory.getLogger(EvccAPI.class);
|
||||
private final Gson gson = new Gson();
|
||||
private final TimeZoneProvider timeZoneProvider;
|
||||
private String host;
|
||||
|
||||
public EvccAPI(String host, TimeZoneProvider timeZoneProvider) {
|
||||
this.host = (host.endsWith("/") ? host.substring(0, host.length() - 1) : host);
|
||||
this.timeZoneProvider = timeZoneProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a HTTP request.
|
||||
*
|
||||
* @param url full request URL
|
||||
* @param method request method, e.g. GET, POST
|
||||
* @return the response body
|
||||
* @throws EvccApiException if HTTP request failed
|
||||
*/
|
||||
private String httpRequest(String url, String method) throws EvccApiException {
|
||||
try {
|
||||
String response = HttpUtil.executeUrl(method, url, LONG_CONNECTION_TIMEOUT_MILLISEC);
|
||||
logger.trace("{} {} - {}", method, url, response);
|
||||
return response;
|
||||
} catch (IOException e) {
|
||||
throw new EvccApiException("HTTP request failed for URL " + url, e);
|
||||
}
|
||||
}
|
||||
|
||||
// End utility functions
|
||||
|
||||
// API calls to evcc
|
||||
/**
|
||||
* Get the status from evcc.
|
||||
*
|
||||
* @return {@link Result} result object from API
|
||||
* @throws EvccApiException if status request failed
|
||||
*/
|
||||
public Result getResult() throws EvccApiException {
|
||||
final String response = httpRequest(this.host + EVCC_REST_API + "state", "GET");
|
||||
logger.trace("API Response >> {}", response);
|
||||
try {
|
||||
JsonObject jsonObject = gson.fromJson(response, JsonObject.class);
|
||||
if (jsonObject == null) {
|
||||
throw new EvccApiException("Invalid response - no json.");
|
||||
}
|
||||
Result result = null;
|
||||
if (jsonObject.has("result")) {
|
||||
result = gson.fromJson(jsonObject.get("result"), Result.class);
|
||||
}
|
||||
if (jsonObject.has("version")) {
|
||||
// Attribute version available - continue as Result
|
||||
result = gson.fromJson(jsonObject, Result.class);
|
||||
}
|
||||
if (result != null) {
|
||||
return result;
|
||||
} else {
|
||||
throw new EvccApiException("Invalid response - no result: " + response);
|
||||
}
|
||||
} catch (JsonSyntaxException e) {
|
||||
throw new EvccApiException("Error parsing response: " + response, e);
|
||||
}
|
||||
}
|
||||
|
||||
// Site API calls.
|
||||
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 setLimitEnergy(int loadpoint, float limitEnergy) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/limitenergy/" + limitEnergy,
|
||||
"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 {
|
||||
return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/phases/" + phases, "POST");
|
||||
}
|
||||
|
||||
public String setMinCurrent(int loadpoint, int minCurrent) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/mincurrent/" + minCurrent, "POST");
|
||||
}
|
||||
|
||||
public String setMaxCurrent(int loadpoint, int maxCurrent) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/maxcurrent/" + maxCurrent, "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, Instant planTime) throws EvccApiException {
|
||||
ZonedDateTime adjustedTime = planTime.atZone(timeZoneProvider.getTimeZone());
|
||||
String formattedTime = adjustedTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
|
||||
return httpRequest(
|
||||
this.host + EVCC_REST_API + "vehicles/" + vehicleName + "/plan/soc/" + planSoC + "/" + formattedTime,
|
||||
"POST");
|
||||
}
|
||||
|
||||
public String removeVehiclePlan(String vehicleName) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "vehicles/" + vehicleName + "/plan/soc", "DELETE");
|
||||
}
|
||||
}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link EvccApiException} signals that an API request by {@link EvccAPI} failed.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EvccApiException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -1935778974024277328L;
|
||||
|
||||
public EvccApiException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public EvccApiException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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 battery object of the status response (/api/state).
|
||||
* This DTO was written for evcc version 0.123.1
|
||||
*
|
||||
* @author MikeTheTux - Initial contribution
|
||||
*/
|
||||
public class Battery {
|
||||
// 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("power")
|
||||
private float power;
|
||||
|
||||
@SerializedName("energy")
|
||||
private float energy;
|
||||
|
||||
@SerializedName("soc")
|
||||
private float soc;
|
||||
|
||||
@SerializedName("capacity")
|
||||
private float capacity;
|
||||
|
||||
@SerializedName("controllable")
|
||||
private boolean controllable;
|
||||
|
||||
/**
|
||||
* @return battery's capacity
|
||||
*/
|
||||
public float getCapacity() {
|
||||
return capacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return battery's power
|
||||
*/
|
||||
public float getPower() {
|
||||
return power;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return battery's state of charge
|
||||
*/
|
||||
public float getSoC() {
|
||||
return soc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return battery discharge controlable
|
||||
*/
|
||||
public boolean getControllable() {
|
||||
return controllable;
|
||||
}
|
||||
}
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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 the grid response (/api/state).
|
||||
* This DTO was written for evcc version 0.133.0
|
||||
*
|
||||
* @author Daniel Kötting - Initial contribution
|
||||
*/
|
||||
public class Grid {
|
||||
// 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("currents")
|
||||
private Float[] currents;
|
||||
|
||||
@SerializedName("energy")
|
||||
private Float energy;
|
||||
|
||||
@SerializedName("power")
|
||||
private Float power;
|
||||
|
||||
/**
|
||||
* @return grid's currents
|
||||
*/
|
||||
public Float[] getCurrents() {
|
||||
return currents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return grid's energy
|
||||
*/
|
||||
public Float getEnergy() {
|
||||
return energy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return grid's power or {@code null} if not available
|
||||
*/
|
||||
public Float getPower() {
|
||||
return power;
|
||||
}
|
||||
}
|
||||
-298
@@ -1,298 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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 loadpoint object of the status response (/api/state).
|
||||
* 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
|
||||
* @author Marcel Goerentz - Replace invalid chars with hyphens in vehicleName
|
||||
*/
|
||||
public class Loadpoint {
|
||||
// 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("phasesActive")
|
||||
private int activePhases;
|
||||
|
||||
@SerializedName("chargeCurrent")
|
||||
private float chargeCurrent;
|
||||
|
||||
@SerializedName("chargeDuration")
|
||||
private long chargeDuration;
|
||||
|
||||
@SerializedName("chargePower")
|
||||
private float chargePower;
|
||||
|
||||
@SerializedName("chargeRemainingDuration")
|
||||
private long chargeRemainingDuration;
|
||||
|
||||
@SerializedName("chargeRemainingEnergy")
|
||||
private float chargeRemainingEnergy;
|
||||
|
||||
@SerializedName("chargedEnergy")
|
||||
private float chargedEnergy;
|
||||
|
||||
@SerializedName("charging")
|
||||
private boolean charging;
|
||||
|
||||
@SerializedName("connected")
|
||||
private boolean connected;
|
||||
|
||||
@SerializedName("connectedDuration")
|
||||
private long connectedDuration;
|
||||
|
||||
@SerializedName("enabled")
|
||||
private boolean enabled;
|
||||
|
||||
@SerializedName("maxCurrent")
|
||||
private float maxCurrent;
|
||||
|
||||
@SerializedName("minCurrent")
|
||||
private float minCurrent;
|
||||
|
||||
@SerializedName("mode")
|
||||
private String mode;
|
||||
|
||||
@SerializedName("phasesEnabled")
|
||||
private int phases;
|
||||
|
||||
@SerializedName("limitEnergy")
|
||||
private float limitEnergy;
|
||||
|
||||
@SerializedName("limitSoc")
|
||||
private float limitSoC;
|
||||
|
||||
@SerializedName("targetTime")
|
||||
private String targetTime;
|
||||
|
||||
@SerializedName("title")
|
||||
private String title;
|
||||
|
||||
@SerializedName("vehicleOdometer")
|
||||
private float vehicleOdometer;
|
||||
|
||||
@SerializedName("vehiclePresent")
|
||||
private boolean vehiclePresent;
|
||||
|
||||
@SerializedName("vehicleRange")
|
||||
private float vehicleRange;
|
||||
|
||||
@SerializedName("vehicleSoc")
|
||||
private float vehicleSoC;
|
||||
|
||||
@SerializedName("vehicleName")
|
||||
private String vehicleName;
|
||||
|
||||
@SerializedName("effectiveLimitSoc")
|
||||
private float effectiveLimitSoC;
|
||||
|
||||
@SerializedName("chargerFeatureHeating")
|
||||
private boolean chargerFeatureHeating;
|
||||
|
||||
@SerializedName("chargerFeatureIntegratedDevice")
|
||||
private boolean chargerFeatureIntegratedDevice;
|
||||
|
||||
/**
|
||||
* @return number of active phases
|
||||
*/
|
||||
public int getActivePhases() {
|
||||
return activePhases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return charge current
|
||||
*/
|
||||
public float getChargeCurrent() {
|
||||
return chargeCurrent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return charge duration
|
||||
*/
|
||||
public long getChargeDuration() {
|
||||
return chargeDuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return charge power
|
||||
*/
|
||||
public float getChargePower() {
|
||||
return chargePower;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return charge remaining duration until the target SoC is reached
|
||||
*/
|
||||
public long getChargeRemainingDuration() {
|
||||
return chargeRemainingDuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return charge remaining energy until the target SoC is reached
|
||||
*/
|
||||
public float getChargeRemainingEnergy() {
|
||||
return chargeRemainingEnergy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return charged energy
|
||||
*/
|
||||
public float getChargedEnergy() {
|
||||
return chargedEnergy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether loadpoint is charging a vehicle
|
||||
*/
|
||||
public boolean getCharging() {
|
||||
return charging;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether a vehicle is connected to the loadpoint
|
||||
*/
|
||||
public boolean getConnected() {
|
||||
return connected;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return vehicle connected duration
|
||||
*/
|
||||
public long getConnectedDuration() {
|
||||
return connectedDuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether loadpoint is enabled
|
||||
*/
|
||||
public boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return maximum current
|
||||
*/
|
||||
public float getMaxCurrent() {
|
||||
return maxCurrent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return minimum current
|
||||
*/
|
||||
public float getMinCurrent() {
|
||||
return minCurrent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return charging mode: off, now, minpv, pv
|
||||
*/
|
||||
public String getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of enabled phases
|
||||
*/
|
||||
public int getPhases() {
|
||||
return phases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return limit energy
|
||||
*/
|
||||
public float getLimitEnergy() {
|
||||
return limitEnergy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return limit state of charge (SoC)
|
||||
*/
|
||||
public float getLimitSoC() {
|
||||
return limitSoC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return target time for the target state of charge
|
||||
*/
|
||||
public String getTargetTime() {
|
||||
return targetTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return loadpoint's title/name
|
||||
*/
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return vehicle's odometer
|
||||
*/
|
||||
public float getVehicleOdometer() {
|
||||
return vehicleOdometer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether evcc is able to get data from vehicle
|
||||
*/
|
||||
public boolean getVehiclePresent() {
|
||||
return vehiclePresent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return vehicle's range
|
||||
*/
|
||||
public float getVehicleRange() {
|
||||
return vehicleRange;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return vehicle's state of charge (SoC)
|
||||
*/
|
||||
public float getVehicleSoC() {
|
||||
return vehicleSoC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return vehicle's title/name
|
||||
*/
|
||||
public String getVehicleName() {
|
||||
return vehicleName != null ? vehicleName.replaceAll("[^a-zA-Z0-9_-]", "-") : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return effective limit state of charge
|
||||
*/
|
||||
public float getEffectiveLimitSoC() {
|
||||
return effectiveLimitSoC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Charger Feature: Heating
|
||||
*/
|
||||
public boolean getChargerFeatureHeating() {
|
||||
return chargerFeatureHeating;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Charger Feature: Integrated Device
|
||||
*/
|
||||
public boolean getChargerFeatureIntegratedDevice() {
|
||||
return chargerFeatureIntegratedDevice;
|
||||
}
|
||||
}
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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 PV object of the status response (/api/state).
|
||||
* This DTO was written for evcc version 0.123.1
|
||||
*
|
||||
* @author MikeTheTux - Initial contribution
|
||||
*/
|
||||
public class PV {
|
||||
// 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("power")
|
||||
private float power;
|
||||
|
||||
/**
|
||||
* @return PV power
|
||||
*/
|
||||
public float getPower() {
|
||||
return power;
|
||||
}
|
||||
}
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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;
|
||||
}
|
||||
}
|
||||
-252
@@ -1,252 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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 java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
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.123.1
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
* @author Luca Arnecke - update to evcc version 0.123.1
|
||||
* @author Daniel Kötting - update to evcc version 0.133.0
|
||||
* @author Marcel Goerentz - Replace invalid chars with hyphens in vehicles map
|
||||
*/
|
||||
public class Result {
|
||||
// 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
|
||||
|
||||
// "auth" is left out because it does not provide any useful information
|
||||
|
||||
@SerializedName("batteryCapacity")
|
||||
private float batteryCapacity;
|
||||
|
||||
@SerializedName("battery")
|
||||
private Battery[] battery;
|
||||
|
||||
@SerializedName("batteryPower")
|
||||
private float batteryPower;
|
||||
|
||||
@SerializedName("batterySoc")
|
||||
private float batterySoC;
|
||||
|
||||
@SerializedName("batteryDischargeControl")
|
||||
private boolean batteryDischargeControl;
|
||||
|
||||
@SerializedName("batteryMode")
|
||||
private String batteryMode;
|
||||
|
||||
@SerializedName("gridPower")
|
||||
private Float gridPower;
|
||||
|
||||
@SerializedName("grid")
|
||||
private Grid grid;
|
||||
|
||||
@SerializedName("gridConfigured")
|
||||
private boolean gridConfigured;
|
||||
|
||||
@SerializedName("homePower")
|
||||
private float homePower;
|
||||
|
||||
@SerializedName("loadpoints")
|
||||
private Loadpoint[] loadpoints;
|
||||
|
||||
@SerializedName("prioritySoc")
|
||||
private float prioritySoC;
|
||||
|
||||
@SerializedName("bufferSoc")
|
||||
private float bufferSoC;
|
||||
|
||||
@SerializedName("bufferStartSoc")
|
||||
private float bufferStartSoC;
|
||||
|
||||
@SerializedName("residualPower")
|
||||
private float residualPower;
|
||||
|
||||
@SerializedName("pv")
|
||||
private PV[] pv;
|
||||
|
||||
@SerializedName("pvPower")
|
||||
private float pvPower;
|
||||
|
||||
@SerializedName("siteTitle")
|
||||
private String siteTitle;
|
||||
|
||||
@SerializedName("vehicles")
|
||||
private Map<String, Vehicle> vehicles;
|
||||
|
||||
@SerializedName("version")
|
||||
private String version;
|
||||
|
||||
@SerializedName("availableVersion")
|
||||
private String availableVersion;
|
||||
|
||||
/**
|
||||
* @return all configured batteries
|
||||
*/
|
||||
public Battery[] getBattery() {
|
||||
return battery;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return battery's capacity
|
||||
*/
|
||||
public float getBatteryCapacity() {
|
||||
return batteryCapacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return battery's power
|
||||
*/
|
||||
public float getBatteryPower() {
|
||||
return batteryPower;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return battery's priority state of charge
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return battery's state of charge
|
||||
*/
|
||||
public float getBatterySoC() {
|
||||
return batterySoC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return battery discharge control
|
||||
*/
|
||||
public boolean getBatteryDischargeControl() {
|
||||
return batteryDischargeControl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return battery mode
|
||||
*/
|
||||
public String getBatteryMode() {
|
||||
return batteryMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return gridPower (before evcc version 0.133.0)
|
||||
*/
|
||||
public Float getGridPower() {
|
||||
return gridPower;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return all grid related values (since evcc version 0.133.0)
|
||||
*/
|
||||
public Grid getGrid() {
|
||||
return grid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return is grid configured (since evcc version 0.133.0)
|
||||
*/
|
||||
public boolean getGridConfigured() {
|
||||
return gridConfigured;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return home's power
|
||||
*/
|
||||
public float getHomePower() {
|
||||
return homePower;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return all configured loadpoints
|
||||
*/
|
||||
public Loadpoint[] getLoadpoints() {
|
||||
return loadpoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return all configured PVs
|
||||
*/
|
||||
public PV[] getPV() {
|
||||
return pv;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pv's power
|
||||
*/
|
||||
public float getPvPower() {
|
||||
return pvPower;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return site's title/name
|
||||
*/
|
||||
public String getSiteTitle() {
|
||||
return siteTitle;
|
||||
}
|
||||
|
||||
public Map<String, Vehicle> getVehicles() {
|
||||
Map<String, Vehicle> correctedMap = new HashMap<>();
|
||||
for (Entry<String, Vehicle> entry : vehicles.entrySet()) {
|
||||
// The key from the vehicles map is used as uid, so it should not contain any disallowed chars
|
||||
// If necessary replace the forbidden chars with hyphens
|
||||
String key = entry.getKey();
|
||||
if (!key.matches("[a-zA-Z0-9_-]+")) {
|
||||
key = key.replaceAll("[^a-zA-Z0-9_-]", "-");
|
||||
}
|
||||
correctedMap.put(key, entry.getValue());
|
||||
}
|
||||
return correctedMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return evcc version
|
||||
*/
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return evcc available version
|
||||
*/
|
||||
public String getAvailableVersion() {
|
||||
return availableVersion;
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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 the status response (/api/state).
|
||||
* This DTO was written for evcc version 0.117.0
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
public class Status {
|
||||
|
||||
@SerializedName("result")
|
||||
private Result result;
|
||||
|
||||
public Result getResult() {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
-80
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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("capacity")
|
||||
private float capacity;
|
||||
|
||||
@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 vehicle's capacity
|
||||
*/
|
||||
public float getCapacity() {
|
||||
return capacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return current plan for vehicle
|
||||
*/
|
||||
public Plan getPlan() {
|
||||
if (plans != null) {
|
||||
return plans[0];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.discovery;
|
||||
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.evcc.internal.discovery.mapper.BatteryDiscoveryMapper;
|
||||
import org.openhab.binding.evcc.internal.discovery.mapper.EvccDiscoveryMapper;
|
||||
import org.openhab.binding.evcc.internal.discovery.mapper.LoadpointDiscoveryMapper;
|
||||
import org.openhab.binding.evcc.internal.discovery.mapper.PvDiscoveryMapper;
|
||||
import org.openhab.binding.evcc.internal.discovery.mapper.SiteDiscoveryMapper;
|
||||
import org.openhab.binding.evcc.internal.discovery.mapper.StatisticsDiscoveryMapper;
|
||||
import org.openhab.binding.evcc.internal.discovery.mapper.VehicleDiscoveryMapper;
|
||||
import org.openhab.binding.evcc.internal.handler.EvccBridgeHandler;
|
||||
import org.openhab.core.config.discovery.AbstractThingHandlerDiscoveryService;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.ServiceScope;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link EvccDiscoveryService} is responsible for scanning the API response for things
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(scope = ServiceScope.PROTOTYPE, service = EvccDiscoveryService.class, configurationPid = "discovery.evcc")
|
||||
public class EvccDiscoveryService extends AbstractThingHandlerDiscoveryService<EvccBridgeHandler> {
|
||||
|
||||
private static final int TIMEOUT = 5;
|
||||
private static final int SCAN_INTERVAL_IN_SECONDS = 5; // We can scan every 5 seconds since we are using the cached
|
||||
// response
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private final List<EvccDiscoveryMapper> mappers = List.of(new LoadpointDiscoveryMapper(),
|
||||
new VehicleDiscoveryMapper(), new BatteryDiscoveryMapper(), new SiteDiscoveryMapper(),
|
||||
new PvDiscoveryMapper(), new StatisticsDiscoveryMapper());
|
||||
|
||||
private @Nullable ScheduledFuture<?> evccDiscoveryJob;
|
||||
|
||||
public EvccDiscoveryService() {
|
||||
super(EvccBridgeHandler.class, SUPPORTED_THING_TYPES, TIMEOUT, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startScan() {
|
||||
logger.debug("Starting evcc Discover");
|
||||
JsonObject state = thingHandler.getCachedEvccState();
|
||||
if (!state.isEmpty()) {
|
||||
for (EvccDiscoveryMapper mapper : mappers) {
|
||||
mapper.discover(state, thingHandler).forEach(thing -> {
|
||||
logger.debug("Thing discovered {}", thing);
|
||||
thingDiscovered(thing);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ThingTypeUID> getSupportedThingTypes() {
|
||||
return SUPPORTED_THING_TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startBackgroundDiscovery() {
|
||||
logger.debug("Start evcc background discovery");
|
||||
Optional.ofNullable(evccDiscoveryJob).ifPresentOrElse(job -> {
|
||||
if (job.isCancelled()) {
|
||||
startNewJob();
|
||||
}
|
||||
}, this::startNewJob);
|
||||
}
|
||||
|
||||
private void startNewJob() {
|
||||
evccDiscoveryJob = scheduler.scheduleWithFixedDelay(this::startScan, 0, SCAN_INTERVAL_IN_SECONDS,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stopBackgroundDiscovery() {
|
||||
logger.debug("Stop evcc device background discovery");
|
||||
Optional.ofNullable(evccDiscoveryJob)
|
||||
.ifPresent(backgroundScan -> backgroundScan.cancel(isBackgroundDiscoveryEnabled()));
|
||||
evccDiscoveryJob = null;
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.discovery;
|
||||
|
||||
import java.text.Normalizer;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link Utils} provides utility functions
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class Utils {
|
||||
|
||||
/**
|
||||
* This method removes specific local characters (like ä, ö, ü), so we get a sanitized string
|
||||
*
|
||||
* @param name that will be sanitized
|
||||
* @return a sanitized name that has replaced any invalid char
|
||||
*/
|
||||
public static String sanitizeName(String name) {
|
||||
String result = name;
|
||||
if (!Normalizer.isNormalized(name, Normalizer.Form.NFKD)) {
|
||||
result = Normalizer.normalize(name, Normalizer.Form.NFKD);
|
||||
result = result.replaceAll("\\p{M}", "");
|
||||
}
|
||||
return result.replaceAll("[^a-zA-Z0-9_]", "-").toLowerCase();
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.discovery.mapper;
|
||||
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.evcc.internal.EvccBindingConstants;
|
||||
import org.openhab.binding.evcc.internal.discovery.Utils;
|
||||
import org.openhab.binding.evcc.internal.handler.EvccBridgeHandler;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link BatteryDiscoveryMapper} iis responsible for mapping the discovered batteries to discovery results
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class BatteryDiscoveryMapper implements EvccDiscoveryMapper {
|
||||
|
||||
@Override
|
||||
public Collection<DiscoveryResult> discover(JsonObject state, EvccBridgeHandler bridgeHandler) {
|
||||
List<DiscoveryResult> results = new ArrayList<>();
|
||||
JsonArray batteries = state.getAsJsonArray(JSON_MEMBER_BATTERY);
|
||||
if (batteries == null) {
|
||||
return results;
|
||||
}
|
||||
for (int i = 0; i < batteries.size(); i++) {
|
||||
JsonObject battery = batteries.get(i).getAsJsonObject();
|
||||
String title = battery.has("title") ? battery.get("title").getAsString().toLowerCase(Locale.ROOT)
|
||||
: "battery" + i;
|
||||
|
||||
ThingUID uid = new ThingUID(EvccBindingConstants.THING_TYPE_BATTERY, bridgeHandler.getThing().getUID(),
|
||||
Utils.sanitizeName(title));
|
||||
DiscoveryResult result = DiscoveryResultBuilder.create(uid).withLabel(title)
|
||||
.withBridge(bridgeHandler.getThing().getUID()).withProperty(PROPERTY_INDEX, i)
|
||||
.withProperty(PROPERTY_TYPE, PROPERTY_TYPE_BATTERY).withProperty(PROPERTY_TITLE, title)
|
||||
.withRepresentationProperty(PROPERTY_TITLE).build();
|
||||
results.add(result);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.discovery.mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.evcc.internal.handler.EvccBridgeHandler;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link EvccDiscoveryMapper} is responsible mapping discovered things to discovery results
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface EvccDiscoveryMapper {
|
||||
/**
|
||||
* This method returns the discovered things from the JSON response
|
||||
*
|
||||
* @param state the JSON response from the API
|
||||
* @param bridgeHandler the bridge handler
|
||||
* @return Collection of discovery results
|
||||
*/
|
||||
Collection<DiscoveryResult> discover(JsonObject state, EvccBridgeHandler bridgeHandler);
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.discovery.mapper;
|
||||
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.evcc.internal.EvccBindingConstants;
|
||||
import org.openhab.binding.evcc.internal.discovery.Utils;
|
||||
import org.openhab.binding.evcc.internal.handler.EvccBridgeHandler;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link LoadpointDiscoveryMapper} is responsible for mapping the discovered loadpoints to discovery results
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class LoadpointDiscoveryMapper implements EvccDiscoveryMapper {
|
||||
|
||||
@Override
|
||||
public Collection<DiscoveryResult> discover(JsonObject state, EvccBridgeHandler bridgeHandler) {
|
||||
List<DiscoveryResult> results = new ArrayList<>();
|
||||
JsonArray loadpoints = state.getAsJsonArray(JSON_MEMBER_LOADPOINTS);
|
||||
if (loadpoints == null) {
|
||||
return results;
|
||||
}
|
||||
for (int i = 0; i < loadpoints.size(); i++) {
|
||||
JsonObject lp = loadpoints.get(i).getAsJsonObject();
|
||||
String title = lp.has("title") ? lp.get("title").getAsString().toLowerCase(Locale.ROOT) : "loadpoint" + i;
|
||||
|
||||
ThingUID uid = new ThingUID("DUMMY:DUMMY:DUMMY");
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put(PROPERTY_INDEX, i);
|
||||
properties.put(PROPERTY_TITLE, title);
|
||||
|
||||
if (lp.has(title) && lp.get("chargerFeatureHeating").getAsBoolean()) {
|
||||
uid = new ThingUID(EvccBindingConstants.THING_TYPE_HEATING, bridgeHandler.getThing().getUID(),
|
||||
Utils.sanitizeName(title));
|
||||
properties.put(PROPERTY_TYPE, PROPERTY_TYPE_HEATING);
|
||||
} else {
|
||||
uid = new ThingUID(EvccBindingConstants.THING_TYPE_LOADPOINT, bridgeHandler.getThing().getUID(),
|
||||
Utils.sanitizeName(title));
|
||||
properties.put(PROPERTY_TYPE, PROPERTY_TYPE_LOADPOINT);
|
||||
}
|
||||
|
||||
DiscoveryResult result = DiscoveryResultBuilder.create(uid).withLabel(title)
|
||||
.withBridge(bridgeHandler.getThing().getUID()).withProperties(properties)
|
||||
.withRepresentationProperty(PROPERTY_TITLE).build();
|
||||
|
||||
results.add(result);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.discovery.mapper;
|
||||
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.evcc.internal.EvccBindingConstants;
|
||||
import org.openhab.binding.evcc.internal.discovery.Utils;
|
||||
import org.openhab.binding.evcc.internal.handler.EvccBridgeHandler;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link PvDiscoveryMapper} is responsible for mapping the discovered photovoltaics to discovery results
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class PvDiscoveryMapper implements EvccDiscoveryMapper {
|
||||
|
||||
@Override
|
||||
public Collection<DiscoveryResult> discover(JsonObject state, EvccBridgeHandler bridgeHandler) {
|
||||
List<DiscoveryResult> results = new ArrayList<>();
|
||||
JsonArray pvs = state.getAsJsonArray(JSON_MEMBER_PV);
|
||||
if (pvs == null) {
|
||||
return results;
|
||||
}
|
||||
for (int i = 0; i < pvs.size(); i++) {
|
||||
JsonObject pv = pvs.get(i).getAsJsonObject();
|
||||
String title = pv.has("title") ? pv.get("title").getAsString().toLowerCase(Locale.ROOT) : "pv" + i;
|
||||
|
||||
ThingUID uid = new ThingUID(EvccBindingConstants.THING_TYPE_PV, bridgeHandler.getThing().getUID(),
|
||||
Utils.sanitizeName(title));
|
||||
DiscoveryResult result = DiscoveryResultBuilder.create(uid).withLabel(title)
|
||||
.withBridge(bridgeHandler.getThing().getUID()).withProperty(PROPERTY_INDEX, i)
|
||||
.withProperty(PROPERTY_TYPE, PROPERTY_TYPE_PV).withProperty(PROPERTY_TITLE, title)
|
||||
.withRepresentationProperty(PROPERTY_TITLE).build();
|
||||
|
||||
results.add(result);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.discovery.mapper;
|
||||
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.evcc.internal.EvccBindingConstants;
|
||||
import org.openhab.binding.evcc.internal.handler.EvccBridgeHandler;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link SiteDiscoveryMapper} is responsible for mapping the discovered site to a discovery result
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SiteDiscoveryMapper implements EvccDiscoveryMapper {
|
||||
|
||||
@Override
|
||||
public Collection<DiscoveryResult> discover(JsonObject state, EvccBridgeHandler bridgeHandler) {
|
||||
List<DiscoveryResult> results = new ArrayList<>();
|
||||
if (!state.has("siteTitle")) {
|
||||
return results;
|
||||
}
|
||||
String siteTitle = state.get("siteTitle").getAsString();
|
||||
ThingUID uid = new ThingUID(EvccBindingConstants.THING_TYPE_SITE, bridgeHandler.getThing().getUID(), "site");
|
||||
DiscoveryResult result = DiscoveryResultBuilder.create(uid).withLabel(siteTitle)
|
||||
.withBridge(bridgeHandler.getThing().getUID()).withProperty(PROPERTY_TYPE, PROPERTY_TYPE_SITE)
|
||||
.withProperty(PROPERTY_SITE_TITLE, siteTitle).withRepresentationProperty(PROPERTY_SITE_TITLE).build();
|
||||
results.add(result);
|
||||
return results;
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.discovery.mapper;
|
||||
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.evcc.internal.EvccBindingConstants;
|
||||
import org.openhab.binding.evcc.internal.handler.EvccBridgeHandler;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link StatisticsDiscoveryMapper} is responsible for mapping the discovered statistics to discovery results
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class StatisticsDiscoveryMapper implements EvccDiscoveryMapper {
|
||||
|
||||
@Override
|
||||
public Collection<DiscoveryResult> discover(JsonObject state, EvccBridgeHandler bridgeHandler) {
|
||||
List<DiscoveryResult> results = new ArrayList<>();
|
||||
JsonObject statistics = state.getAsJsonObject(JSON_MEMBER_STATISTICS);
|
||||
if (statistics == null) {
|
||||
return results;
|
||||
}
|
||||
ThingUID uid = new ThingUID(EvccBindingConstants.THING_TYPE_STATISTICS, bridgeHandler.getThing().getUID(),
|
||||
"statistics");
|
||||
DiscoveryResult result = DiscoveryResultBuilder.create(uid).withLabel("Statistics")
|
||||
.withBridge(bridgeHandler.getThing().getUID()).withProperty(PROPERTY_TYPE, PROPERTY_TYPE_STATISTICS)
|
||||
.withRepresentationProperty(PROPERTY_TYPE).build();
|
||||
results.add(result);
|
||||
return results;
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.discovery.mapper;
|
||||
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.JSON_MEMBER_VEHICLES;
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.PROPERTY_ID;
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.PROPERTY_TYPE;
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.PROPERTY_TYPE_VEHICLE;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.evcc.internal.EvccBindingConstants;
|
||||
import org.openhab.binding.evcc.internal.discovery.Utils;
|
||||
import org.openhab.binding.evcc.internal.handler.EvccBridgeHandler;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link VehicleDiscoveryMapper} is responsible for mapping the discovered vehicles to discovery results
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class VehicleDiscoveryMapper implements EvccDiscoveryMapper {
|
||||
|
||||
@Override
|
||||
public Collection<DiscoveryResult> discover(JsonObject state, EvccBridgeHandler bridgeHandler) {
|
||||
List<DiscoveryResult> results = new ArrayList<>();
|
||||
JsonObject vehicles = state.getAsJsonObject(JSON_MEMBER_VEHICLES);
|
||||
if (vehicles == null) {
|
||||
return results;
|
||||
}
|
||||
for (Map.Entry<String, JsonElement> entry : vehicles.entrySet()) {
|
||||
JsonObject v = entry.getValue().getAsJsonObject();
|
||||
String id = entry.getKey();
|
||||
String title = v.has("title") ? v.get("title").getAsString() : id;
|
||||
|
||||
ThingUID uid = new ThingUID(EvccBindingConstants.THING_TYPE_VEHICLE, bridgeHandler.getThing().getUID(),
|
||||
Utils.sanitizeName(title));
|
||||
DiscoveryResult result = DiscoveryResultBuilder.create(uid).withLabel(title)
|
||||
.withBridge(bridgeHandler.getThing().getUID()).withProperty(PROPERTY_TYPE, PROPERTY_TYPE_VEHICLE)
|
||||
.withProperty(PROPERTY_ID, id).withRepresentationProperty(PROPERTY_ID).build();
|
||||
|
||||
results.add(result);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
+396
@@ -0,0 +1,396 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.handler;
|
||||
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.measure.Unit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.openhab.core.i18n.TranslationProvider;
|
||||
import org.openhab.core.library.CoreItemFactory;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.library.unit.Units;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingStatusInfo;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.thing.binding.builder.ChannelBuilder;
|
||||
import org.openhab.core.thing.binding.builder.ThingBuilder;
|
||||
import org.openhab.core.thing.type.ChannelType;
|
||||
import org.openhab.core.thing.type.ChannelTypeRegistry;
|
||||
import org.openhab.core.thing.type.ChannelTypeUID;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link EvccBaseThingHandler} is responsible for building a base class with common methods for the thing handlers
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public abstract class EvccBaseThingHandler extends BaseThingHandler implements EvccThingLifecycleAware {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(EvccBaseThingHandler.class);
|
||||
private final ChannelTypeRegistry channelTypeRegistry;
|
||||
private final Gson gson = new Gson();
|
||||
protected @Nullable EvccBridgeHandler bridgeHandler;
|
||||
protected boolean isInitialized = false;
|
||||
protected String endpoint = "";
|
||||
protected String smartCostType = "";
|
||||
|
||||
public EvccBaseThingHandler(Thing thing, ChannelTypeRegistry channelTypeRegistry) {
|
||||
super(thing);
|
||||
this.channelTypeRegistry = channelTypeRegistry;
|
||||
}
|
||||
|
||||
protected void commonInitialize(JsonObject state) {
|
||||
ThingBuilder builder = editThing();
|
||||
|
||||
for (Map.Entry<@Nullable String, @Nullable JsonElement> entry : state.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
JsonElement value = entry.getValue();
|
||||
if (null == key || value == null) {
|
||||
continue;
|
||||
}
|
||||
String thingKey = getThingKey(key);
|
||||
|
||||
// Skip non-primitive values
|
||||
if (!value.isJsonPrimitive()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
createChannel(thingKey, builder, value);
|
||||
}
|
||||
|
||||
updateThing(builder.build());
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
isInitialized = true;
|
||||
Optional.ofNullable(bridgeHandler).ifPresentOrElse(handler -> handler.register(this),
|
||||
() -> logger.error("No bridgeHandler present when initializing the thing"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
if (getBridge() instanceof Bridge bridge && bridge.getHandler() instanceof EvccBridgeHandler handler) {
|
||||
bridgeHandler = handler;
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
Optional.ofNullable(bridgeHandler).ifPresent(handler -> handler.unregister(this));
|
||||
isInitialized = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (command instanceof RefreshType) {
|
||||
String key = Utils.getKeyFromChannelUID(channelUID);
|
||||
Optional.ofNullable(bridgeHandler).ifPresent(handler -> {
|
||||
JsonObject state = getStateFromCachedState(handler.getCachedEvccState());
|
||||
if (!state.isEmpty()) {
|
||||
JsonElement value = state.get(key);
|
||||
ItemTypeUnit typeUnit = getItemType(new ChannelTypeUID(BINDING_ID, channelUID.getId()));
|
||||
if (null != value) {
|
||||
setItemValue(typeUnit, channelUID, value);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void createChannel(String thingKey, ThingBuilder builder, JsonElement value) {
|
||||
ChannelTypeUID channelTypeUID = new ChannelTypeUID(BINDING_ID, thingKey);
|
||||
ItemTypeUnit typeUnit = getItemType(channelTypeUID);
|
||||
String itemType = typeUnit.itemType;
|
||||
|
||||
if (!"Unknown".equals(itemType)) {
|
||||
String label = getChannelLabel(thingKey);
|
||||
Channel channel = ChannelBuilder.create(new ChannelUID(getThing().getUID(), thingKey)).withLabel(label)
|
||||
.withType(channelTypeUID).withAcceptedItemType(itemType).build();
|
||||
if (getThing().getChannels().stream().noneMatch(c -> c.getUID().equals(channel.getUID()))) {
|
||||
builder.withChannel(channel);
|
||||
}
|
||||
} else {
|
||||
String valString = Objects.requireNonNullElse(value.toString(), "Null");
|
||||
logUnknownChannelXmlAsync(thingKey, "Hint for type: " + valString);
|
||||
}
|
||||
}
|
||||
|
||||
private String getChannelLabel(String thingKey) {
|
||||
String returnValue = thingKey;
|
||||
@Nullable
|
||||
String tmp = Optional.ofNullable(bridgeHandler).map(handler -> {
|
||||
String labelKey = "channel-type.evcc." + thingKey + ".label";
|
||||
BundleContext ctx = FrameworkUtil.getBundle(EvccBridgeHandler.class).getBundleContext();
|
||||
TranslationProvider tp = handler.getI18nProvider();
|
||||
Locale locale = handler.getLocaleProvider().getLocale();
|
||||
return tp.getText(ctx.getBundle(), labelKey, thingKey, locale);
|
||||
}).orElse(thingKey);
|
||||
if (null != tmp) {
|
||||
returnValue = tmp;
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private ItemTypeUnit getItemType(ChannelTypeUID channelTypeUID) {
|
||||
ChannelType channelType = channelTypeRegistry.getChannelType(channelTypeUID);
|
||||
if (null != channelType) {
|
||||
String itemType = channelType.getItemType();
|
||||
if (null != itemType) {
|
||||
Unit<?> unit = Utils.getUnitFromChannelType(itemType);
|
||||
return new ItemTypeUnit(channelType, unit);
|
||||
}
|
||||
}
|
||||
return new ItemTypeUnit(channelType, Units.ONE);
|
||||
}
|
||||
|
||||
private void setItemValue(ItemTypeUnit itemTypeUnit, ChannelUID channelUID, JsonElement value) {
|
||||
if (value.isJsonNull() || itemTypeUnit.itemType.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
switch (itemTypeUnit.itemType) {
|
||||
case CoreItemFactory.NUMBER:
|
||||
case NUMBER_CURRENCY:
|
||||
case NUMBER_ENERGY_PRICE:
|
||||
updateState(channelUID, new DecimalType(value.getAsDouble()));
|
||||
break;
|
||||
case NUMBER_DIMENSIONLESS:
|
||||
case NUMBER_ELECTRIC_CURRENT:
|
||||
case NUMBER_EMISSION_INTENSITY:
|
||||
case NUMBER_ENERGY:
|
||||
case NUMBER_LENGTH:
|
||||
case NUMBER_POWER:
|
||||
Double finalValue = "%".equals(itemTypeUnit.unitHint) ? value.getAsDouble() / 100 : value.getAsDouble();
|
||||
if (channelUID.getId().contains("capacity") || "km".equals(itemTypeUnit.unitHint)) {
|
||||
updateState(channelUID, new QuantityType<>(finalValue, itemTypeUnit.unit.multiply(1000)));
|
||||
} else if ("Wh".equals(itemTypeUnit.unitHint)) {
|
||||
updateState(channelUID, new QuantityType<>(finalValue, itemTypeUnit.unit.divide(1000)));
|
||||
} else {
|
||||
updateState(channelUID, new QuantityType<>(finalValue, itemTypeUnit.unit));
|
||||
}
|
||||
break;
|
||||
case NUMBER_TIME:
|
||||
updateState(channelUID, QuantityType.valueOf(value.getAsDouble() + " s"));
|
||||
break;
|
||||
case CoreItemFactory.DATETIME:
|
||||
updateState(channelUID, new DateTimeType(value.getAsString()));
|
||||
break;
|
||||
case CoreItemFactory.STRING:
|
||||
updateState(channelUID, new StringType(value.getAsString()));
|
||||
break;
|
||||
case CoreItemFactory.SWITCH:
|
||||
updateState(channelUID, value.getAsBoolean() ? OnOffType.ON : OnOffType.OFF);
|
||||
break;
|
||||
default:
|
||||
logUnknownChannelXmlAsync(channelUID.getId(), "Hint for type: " + value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
protected String getThingKey(String key) {
|
||||
Map<String, String> props = getThing().getProperties();
|
||||
if ("batteryGridChargeLimit".equals(key) || "smartCostLimit".equals(key)) {
|
||||
if ("co2".equals(smartCostType)) {
|
||||
key += "Co2";
|
||||
} else {
|
||||
key += "Price";
|
||||
}
|
||||
}
|
||||
return (props.get("type") + "-" + Utils.sanitizeChannelID(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFromEvccState(JsonObject state) {
|
||||
if (!isInitialized || state.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Map.Entry<@Nullable String, @Nullable JsonElement> entry : state.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
JsonElement value = entry.getValue();
|
||||
if (null == key || null == value || !value.isJsonPrimitive()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String thingKey = getThingKey(key);
|
||||
ChannelUID channelUID = channelUID(thingKey);
|
||||
Channel existingChannel = getThing().getChannel(channelUID.getId());
|
||||
if (existingChannel == null) {
|
||||
ThingBuilder builder = editThing();
|
||||
createChannel(thingKey, builder, value);
|
||||
updateThing(builder.build());
|
||||
}
|
||||
setItemValue(getItemType(new ChannelTypeUID(BINDING_ID, channelUID.getId())), channelUID, value);
|
||||
}
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
}
|
||||
|
||||
protected void sendCommand(String url) {
|
||||
Optional.ofNullable(bridgeHandler).ifPresent(handler -> {
|
||||
HttpClient httpClient = handler.getHttpClient();
|
||||
try {
|
||||
ContentResponse response = httpClient.newRequest(url).timeout(5, TimeUnit.SECONDS)
|
||||
.method(HttpMethod.POST).header(HttpHeader.ACCEPT, "application/json").send();
|
||||
|
||||
if (response.getStatus() == 200) {
|
||||
logger.debug("Sending command was successful");
|
||||
} else {
|
||||
@Nullable
|
||||
JsonObject responseJson = gson.fromJson(response.getContentAsString(), JsonObject.class);
|
||||
Optional.ofNullable(responseJson).ifPresent(json -> {
|
||||
if (json.has("error")) {
|
||||
logger.debug("Sending command was unsuccessful, got this error:\n {}",
|
||||
json.get("error").getAsString());
|
||||
updateStatus(getThing().getStatus(), ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
json.get("error").getAsString());
|
||||
} else {
|
||||
updateStatus(getThing().getStatus(), ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
logger.warn("evcc API error: HTTP {}", response.getStatus());
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("evcc bridge couldn't call the API", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private ChannelUID channelUID(String id) {
|
||||
return new ChannelUID(getThing().getUID(), id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bridgeStatusChanged(ThingStatusInfo statusInfo) {
|
||||
switch (statusInfo.getStatus()) {
|
||||
case OFFLINE:
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
|
||||
break;
|
||||
case UNINITIALIZED:
|
||||
updateStatus(ThingStatus.UNINITIALIZED, ThingStatusDetail.BRIDGE_UNINITIALIZED);
|
||||
break;
|
||||
case ONLINE:
|
||||
if (!isInitialized) {
|
||||
Bridge bridge = getBridge();
|
||||
if (bridge == null) {
|
||||
break;
|
||||
}
|
||||
logger.debug("Bridge {} is ONLINE again, initialize evcc {} again...", bridge.getUID(),
|
||||
getThing().getUID().getId());
|
||||
initialize();
|
||||
} else {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void logUnknownChannelXmlAsync(String key, String itemType) {
|
||||
CompletableFuture.runAsync(() -> logUnknownChannelXml(key, itemType));
|
||||
}
|
||||
|
||||
protected void logUnknownChannelXml(String key, String itemType) {
|
||||
String xmlSnippet = String.format("""
|
||||
<channel-type id="%s">
|
||||
<item-type unitHint="">%s</item-type>
|
||||
<label>%s</label>
|
||||
<description>Autogenerated placeholder</description>
|
||||
<state readOnly="true"></state>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
""", key, itemType, Utils.capitalizeWords(key));
|
||||
|
||||
Path filePath = Paths.get(System.getProperty("user.dir"), "evcc", "unknown-channels.xml");
|
||||
|
||||
try {
|
||||
// Ensure parent directory exists
|
||||
if (!Files.exists(filePath.getParent())) {
|
||||
Files.createDirectories(filePath.getParent());
|
||||
}
|
||||
|
||||
// Check if file exists and contains the ID
|
||||
if (Files.exists(filePath)) {
|
||||
String content = Files.readString(filePath, StandardCharsets.UTF_8);
|
||||
String idPattern = String.format("id=\"%s\"", key);
|
||||
if (content.contains(idPattern)) {
|
||||
logger.trace("Channel ID '{}' already exists in file.", key);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Append the snippet if it's not already present
|
||||
Files.writeString(filePath, xmlSnippet, StandardOpenOption.CREATE, StandardOpenOption.APPEND);
|
||||
logger.debug("Unknown channel definition written to file: {}", filePath.toAbsolutePath());
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to write unknown channel definition to file", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ItemTypeUnit {
|
||||
private final Unit<?> unit;
|
||||
private final String unitHint;
|
||||
private final String itemType;
|
||||
|
||||
public ItemTypeUnit(@Nullable ChannelType type, @Nullable Unit<?> unit) {
|
||||
if (null == type) {
|
||||
unitHint = "";
|
||||
itemType = "Unknown";
|
||||
} else {
|
||||
String tmp = type.getUnitHint();
|
||||
unitHint = null != tmp ? tmp : "";
|
||||
tmp = type.getItemType();
|
||||
itemType = null != tmp ? tmp : "Unknown";
|
||||
}
|
||||
this.unit = Objects.requireNonNullElse(unit, Units.ONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.handler;
|
||||
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.*;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.type.ChannelTypeRegistry;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link EvccBatteryHandler} is responsible for fetching the data from the API response for Battery things
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EvccBatteryHandler extends EvccBaseThingHandler {
|
||||
|
||||
private final int index;
|
||||
|
||||
public EvccBatteryHandler(Thing thing, ChannelTypeRegistry channelTypeRegistry) {
|
||||
super(thing, channelTypeRegistry);
|
||||
Map<String, String> props = thing.getProperties();
|
||||
String indexString = props.getOrDefault(PROPERTY_INDEX, "0");
|
||||
index = Integer.parseInt(indexString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
Optional.ofNullable(bridgeHandler).ifPresent(handler -> {
|
||||
JsonObject stateOpt = handler.getCachedEvccState();
|
||||
if (stateOpt.isEmpty()) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject state = stateOpt.getAsJsonArray(JSON_MEMBER_BATTERY).get(index).getAsJsonObject();
|
||||
commonInitialize(state);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFromEvccState(JsonObject state) {
|
||||
state = state.has(JSON_MEMBER_BATTERY) ? state.getAsJsonArray(JSON_MEMBER_BATTERY).get(index).getAsJsonObject()
|
||||
: new JsonObject();
|
||||
super.updateFromEvccState(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getStateFromCachedState(JsonObject state) {
|
||||
return state.getAsJsonArray(JSON_MEMBER_BATTERY).get(index).getAsJsonObject();
|
||||
}
|
||||
}
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.handler;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.openhab.binding.evcc.internal.EvccConfiguration;
|
||||
import org.openhab.binding.evcc.internal.discovery.EvccDiscoveryService;
|
||||
import org.openhab.core.i18n.LocaleProvider;
|
||||
import org.openhab.core.i18n.TranslationProvider;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseBridgeHandler;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerService;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link EvccBridgeHandler} is responsible for creating the bridge and thing
|
||||
* handlers.
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EvccBridgeHandler extends BaseBridgeHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(EvccBridgeHandler.class);
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
private final HttpClient httpClient;
|
||||
private final TranslationProvider i18nProvider;
|
||||
private final LocaleProvider localeProvider;
|
||||
private final CopyOnWriteArrayList<EvccThingLifecycleAware> listeners = new CopyOnWriteArrayList<>();
|
||||
private @Nullable ScheduledFuture<?> pollJob;
|
||||
private volatile JsonObject lastState = new JsonObject();
|
||||
private String endpoint = "";
|
||||
|
||||
public EvccBridgeHandler(Bridge bridge, HttpClientFactory httpClientFactory, TranslationProvider i18nProvider,
|
||||
LocaleProvider localeProvider) {
|
||||
super(bridge);
|
||||
httpClient = httpClientFactory.getCommonHttpClient();
|
||||
this.i18nProvider = i18nProvider;
|
||||
this.localeProvider = localeProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Class<? extends ThingHandlerService>> getServices() {
|
||||
return Set.of(EvccDiscoveryService.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
EvccConfiguration config = getConfigAs(EvccConfiguration.class);
|
||||
endpoint = config.scheme + "://" + config.host + ":" + config.port + "/api/state";
|
||||
|
||||
startPolling(config.pollInterval);
|
||||
|
||||
fetchEvccState().ifPresent(state -> {
|
||||
this.lastState = state;
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
Optional.ofNullable(pollJob).ifPresent(job -> job.cancel(true));
|
||||
listeners.clear();
|
||||
}
|
||||
|
||||
public HttpClient getHttpClient() {
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
public String getBaseURL() {
|
||||
return endpoint.substring(0, endpoint.lastIndexOf("/"));
|
||||
}
|
||||
|
||||
public TranslationProvider getI18nProvider() {
|
||||
return i18nProvider;
|
||||
}
|
||||
|
||||
public LocaleProvider getLocaleProvider() {
|
||||
return localeProvider;
|
||||
}
|
||||
|
||||
private void startPolling(int refreshInterval) {
|
||||
if (refreshInterval <= 0) {
|
||||
refreshInterval = 30;
|
||||
}
|
||||
pollJob = scheduler.scheduleWithFixedDelay(() -> fetchEvccState().ifPresent(state -> {
|
||||
if (!state.isEmpty() && state.has("siteTitle")) {
|
||||
notifyListeners(state);
|
||||
this.lastState = state;
|
||||
}
|
||||
}), refreshInterval, refreshInterval, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public Optional<JsonObject> fetchEvccState() {
|
||||
try {
|
||||
ContentResponse response = httpClient.newRequest(endpoint).timeout(5, TimeUnit.SECONDS)
|
||||
.header(HttpHeader.ACCEPT, "application/json").send();
|
||||
|
||||
if (response.getStatus() == 200) {
|
||||
@Nullable
|
||||
JsonObject returnValue = gson.fromJson(response.getContentAsString(), JsonObject.class);
|
||||
if (returnValue != null && !(returnValue.isEmpty() || returnValue.isJsonNull())) {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
JsonObject result = returnValue.has("result") ? returnValue.getAsJsonObject("result") : returnValue;
|
||||
return Optional.of(result);
|
||||
}
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
Integer.toString(response.getStatus()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getLocalizedMessage());
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private void notifyListeners(JsonObject state) {
|
||||
for (EvccThingLifecycleAware listener : listeners) {
|
||||
try {
|
||||
listener.updateFromEvccState(state);
|
||||
} catch (Exception e) {
|
||||
if (listener instanceof BaseThingHandler handler) {
|
||||
logger.warn("Listener {} couldn't parse evcc state", handler.getThing().getUID(), e);
|
||||
} else {
|
||||
logger.debug("Listener {} is not instance of BaseThingHandlder", listener, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JsonObject getCachedEvccState() {
|
||||
return lastState;
|
||||
}
|
||||
|
||||
public void register(EvccThingLifecycleAware handler) {
|
||||
listeners.addIfAbsent(handler);
|
||||
Optional.of(lastState).ifPresent(handler::updateFromEvccState);
|
||||
}
|
||||
|
||||
public void unregister(EvccThingLifecycleAware handler) {
|
||||
listeners.remove(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
; // No commands to handle!
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.handler;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.type.ChannelTypeRegistry;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link EvccHeatingHandler} is responsible for fetching the data from the API response for Heating things
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EvccHeatingHandler extends EvccLoadpointHandler {
|
||||
|
||||
public EvccHeatingHandler(Thing thing, ChannelTypeRegistry channelTypeRegistry) {
|
||||
super(thing, channelTypeRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFromEvccState(JsonObject state) {
|
||||
super.updateFromEvccState(state);
|
||||
}
|
||||
}
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.handler;
|
||||
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.*;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.type.ChannelTypeRegistry;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link EvccLoadpointHandler} is responsible for fetching the data from the API response for Loadpoint things
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EvccLoadpointHandler extends EvccBaseThingHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(EvccLoadpointHandler.class);
|
||||
protected final int index;
|
||||
private int[] version = {};
|
||||
|
||||
public EvccLoadpointHandler(Thing thing, ChannelTypeRegistry channelTypeRegistry) {
|
||||
super(thing, channelTypeRegistry);
|
||||
Map<String, String> props = thing.getProperties();
|
||||
String indexString = props.getOrDefault(PROPERTY_INDEX, "0");
|
||||
index = Integer.parseInt(indexString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
Optional.ofNullable(bridgeHandler).ifPresent(handler -> {
|
||||
endpoint = handler.getBaseURL() + API_PATH_LOADPOINTS + "/" + (index + 1);
|
||||
JsonObject stateOpt = handler.getCachedEvccState();
|
||||
if (stateOpt.isEmpty()) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject state = stateOpt.getAsJsonArray(JSON_MEMBER_LOADPOINTS).get(index).getAsJsonObject();
|
||||
|
||||
modifyJSON(state);
|
||||
commonInitialize(state);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (command instanceof State) {
|
||||
String datapoint = Utils.getKeyFromChannelUID(channelUID).toLowerCase();
|
||||
// Backwardscompatibility for phasesConfigured
|
||||
if ("configuredPhases".equals(datapoint) && version[0] == 0 && version[1] < 200) {
|
||||
datapoint = "phases";
|
||||
}
|
||||
// Special Handling for enable and disable endpoints
|
||||
if (datapoint.contains("enable")) {
|
||||
datapoint += "/enable/" + datapoint.replace("enable", "");
|
||||
} else if (datapoint.contains("disable")) {
|
||||
datapoint += "/disable/" + datapoint.replace("disable", "");
|
||||
}
|
||||
String value = "";
|
||||
if (command instanceof OnOffType) {
|
||||
value = command == OnOffType.ON ? "true" : "false";
|
||||
} else {
|
||||
value = command.toString();
|
||||
if (value.contains(" ")) {
|
||||
value = value.substring(0, command.toString().indexOf(" "));
|
||||
}
|
||||
}
|
||||
String url = endpoint + "/" + datapoint + "/" + value;
|
||||
logger.debug("Sending command to this url: {}", url);
|
||||
sendCommand(url);
|
||||
} else {
|
||||
super.handleCommand(channelUID, command);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFromEvccState(JsonObject state) {
|
||||
version = Utils.convertVersionStringToIntArray(state.get("version").getAsString().split(" ")[0]);
|
||||
state = state.getAsJsonArray(JSON_MEMBER_LOADPOINTS).get(index).getAsJsonObject();
|
||||
modifyJSON(state);
|
||||
super.updateFromEvccState(state);
|
||||
}
|
||||
|
||||
public void modifyJSON(JsonObject state) {
|
||||
// This is for backward compatibility with older evcc versions
|
||||
if (state.has("chargeCurrent")) {
|
||||
state.addProperty("offeredCurrent", state.get("chargeCurrent").getAsDouble());
|
||||
state.remove("chargeCurrent");
|
||||
}
|
||||
if (state.has("vehiclePresent")) {
|
||||
state.add("connected", state.get("vehiclePresent"));
|
||||
}
|
||||
if (state.has("enabled")) {
|
||||
state.add("charging", state.get("enabled"));
|
||||
}
|
||||
if (state.has("phases")) {
|
||||
state.add("phasesConfigured", state.get("phases"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getStateFromCachedState(JsonObject state) {
|
||||
return state.has(JSON_MEMBER_LOADPOINTS)
|
||||
? state.getAsJsonArray(JSON_MEMBER_LOADPOINTS).get(index).getAsJsonObject()
|
||||
: new JsonObject();
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.handler;
|
||||
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.*;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.type.ChannelTypeRegistry;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link EvccPvHandler} is responsible for fetching the data from the API response for PV things
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EvccPvHandler extends EvccBaseThingHandler {
|
||||
|
||||
private final int index;
|
||||
|
||||
public EvccPvHandler(Thing thing, ChannelTypeRegistry channelTypeRegistry) {
|
||||
super(thing, channelTypeRegistry);
|
||||
Map<String, String> props = thing.getProperties();
|
||||
String indexString = props.getOrDefault(PROPERTY_INDEX, "0");
|
||||
index = Integer.parseInt(indexString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
Optional.ofNullable(bridgeHandler).ifPresent(handler -> {
|
||||
JsonObject stateOpt = handler.getCachedEvccState();
|
||||
if (stateOpt.isEmpty()) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject state = stateOpt.getAsJsonArray(JSON_MEMBER_PV).get(index).getAsJsonObject();
|
||||
commonInitialize(state);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFromEvccState(JsonObject state) {
|
||||
state = state.getAsJsonArray(JSON_MEMBER_PV).get(index).getAsJsonObject();
|
||||
super.updateFromEvccState(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getStateFromCachedState(JsonObject state) {
|
||||
return state.has(JSON_MEMBER_PV) ? state.getAsJsonArray(JSON_MEMBER_PV).get(index).getAsJsonObject()
|
||||
: new JsonObject();
|
||||
}
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.handler;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.type.ChannelTypeRegistry;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link EvccSiteHandler} is responsible for fetching the data from the API response for Site things
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EvccSiteHandler extends EvccBaseThingHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(EvccSiteHandler.class);
|
||||
|
||||
public EvccSiteHandler(Thing thing, ChannelTypeRegistry channelTypeRegistry) {
|
||||
super(thing, channelTypeRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (command instanceof State) {
|
||||
String datapoint = Utils.getKeyFromChannelUID(channelUID).toLowerCase();
|
||||
String value = "";
|
||||
if (command instanceof OnOffType) {
|
||||
value = command == OnOffType.ON ? "true" : "false";
|
||||
} else {
|
||||
value = command.toString();
|
||||
if (value.contains(" ")) {
|
||||
value = value.substring(0, command.toString().indexOf(" "));
|
||||
}
|
||||
}
|
||||
String url = endpoint + "/" + datapoint + "/" + value;
|
||||
logger.debug("Sending command to this url: {}", url);
|
||||
sendCommand(url);
|
||||
} else {
|
||||
super.handleCommand(channelUID, command);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFromEvccState(JsonObject state) {
|
||||
if (state.has("gridConfigured")) {
|
||||
modifyJSON(state);
|
||||
}
|
||||
super.updateFromEvccState(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
Optional.ofNullable(bridgeHandler).ifPresent(handler -> {
|
||||
endpoint = handler.getBaseURL();
|
||||
JsonObject state = handler.getCachedEvccState();
|
||||
if (state.isEmpty()) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the smart cost type
|
||||
if (state.has("smartCostType")) {
|
||||
smartCostType = state.get("smartCostType").getAsString();
|
||||
}
|
||||
|
||||
if (state.has("gridConfigured")) {
|
||||
modifyJSON(state);
|
||||
}
|
||||
commonInitialize(state);
|
||||
});
|
||||
}
|
||||
|
||||
private void modifyJSON(JsonObject state) {
|
||||
state.add("gridPower", state.getAsJsonObject("grid").get("power"));
|
||||
state.remove("gridConfigured");
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getStateFromCachedState(JsonObject state) {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.handler;
|
||||
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.*;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.thing.ChannelGroupUID;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.type.ChannelTypeRegistry;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link EvccStatisticsHandler} is responsible for fetching the data from the API response for Site things
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EvccStatisticsHandler extends EvccBaseThingHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(EvccStatisticsHandler.class);
|
||||
|
||||
public EvccStatisticsHandler(Thing thing, ChannelTypeRegistry channelTypeRegistry) {
|
||||
super(thing, channelTypeRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
Optional.ofNullable(bridgeHandler).ifPresent(handler -> {
|
||||
handler.register(this);
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
isInitialized = true;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getStateFromCachedState(JsonObject state) {
|
||||
return new JsonObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFromEvccState(JsonObject state) {
|
||||
state = state.has(JSON_MEMBER_STATISTICS) ? state.getAsJsonObject(JSON_MEMBER_STATISTICS) : new JsonObject();
|
||||
for (String statisticsKey : state.keySet()) {
|
||||
JsonObject statistic = state.getAsJsonObject(statisticsKey);
|
||||
logger.debug("Extracting statistics for {}", statisticsKey);
|
||||
for (Map.Entry<@Nullable String, @Nullable JsonElement> entry : statistic.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
JsonElement value = entry.getValue();
|
||||
if (null != key && null != value) {
|
||||
ChannelGroupUID channelGroupUID = new ChannelGroupUID(thing.getUID(),
|
||||
Utils.sanitizeChannelID(statisticsKey));
|
||||
if ("chargedKWh".equals(key)) {
|
||||
key = "chargedEnergy";
|
||||
}
|
||||
ChannelUID channelUID = new ChannelUID(channelGroupUID, Utils.sanitizeChannelID(key));
|
||||
updateState(channelUID, new DecimalType(value.getAsDouble()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.handler;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link EvccThingLifecycleAware} is responsible for sharing the evcc api response
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface EvccThingLifecycleAware {
|
||||
/**
|
||||
* This method shall update the channels from the JSON received from the evcc API
|
||||
*
|
||||
* @param state the responded JSON
|
||||
*/
|
||||
void updateFromEvccState(JsonObject state);
|
||||
|
||||
/**
|
||||
* This method shall return the to the thing corresponding JSON object
|
||||
*
|
||||
* @param state the cached API JSON response
|
||||
* @return to the thing corresponding JSON object
|
||||
*/
|
||||
JsonObject getStateFromCachedState(JsonObject state);
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.handler;
|
||||
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.*;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.type.ChannelTypeRegistry;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* The {@link EvccVehicleHandler} is responsible for fetching the data from the API response for Vehicle things
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EvccVehicleHandler extends EvccBaseThingHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(EvccVehicleHandler.class);
|
||||
|
||||
private final @Nullable String vehicleId;
|
||||
|
||||
private String endpoint = "";
|
||||
|
||||
public EvccVehicleHandler(Thing thing, ChannelTypeRegistry channelTypeRegistry) {
|
||||
super(thing, channelTypeRegistry);
|
||||
vehicleId = thing.getProperties().get(PROPERTY_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (command instanceof State) {
|
||||
String datapoint = Utils.getKeyFromChannelUID(channelUID).toLowerCase();
|
||||
String value = command.toString();
|
||||
if (value.contains(" ")) {
|
||||
value = value.substring(0, command.toString().indexOf(" "));
|
||||
}
|
||||
String url = endpoint + "/" + vehicleId + "/" + datapoint + "/" + value;
|
||||
logger.debug("Sending command to this url: {}", url);
|
||||
sendCommand(url);
|
||||
} else {
|
||||
super.handleCommand(channelUID, command);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFromEvccState(JsonObject state) {
|
||||
state = state.getAsJsonObject(JSON_MEMBER_VEHICLES).getAsJsonObject(vehicleId);
|
||||
super.updateFromEvccState(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
Optional.ofNullable(bridgeHandler).ifPresent(handler -> {
|
||||
endpoint = handler.getBaseURL() + API_PATH_VEHICLES;
|
||||
JsonObject stateOpt = handler.getCachedEvccState();
|
||||
if (stateOpt.isEmpty()) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject state = stateOpt.getAsJsonObject(JSON_MEMBER_VEHICLES).getAsJsonObject(vehicleId);
|
||||
commonInitialize(state);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getStateFromCachedState(JsonObject state) {
|
||||
return state.has(JSON_MEMBER_VEHICLES) ? state.getAsJsonObject(JSON_MEMBER_VEHICLES).getAsJsonObject(vehicleId)
|
||||
: new JsonObject();
|
||||
}
|
||||
}
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.handler;
|
||||
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.NUMBER_DIMENSIONLESS;
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.NUMBER_ELECTRIC_CURRENT;
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.NUMBER_EMISSION_INTENSITY;
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.NUMBER_ENERGY;
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.NUMBER_LENGTH;
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.NUMBER_POWER;
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.NUMBER_TIME;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
import javax.measure.Unit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.library.unit.SIUnits;
|
||||
import org.openhab.core.library.unit.Units;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
|
||||
/**
|
||||
* The {@link Utils} provides utility methods
|
||||
*
|
||||
* @author Marcel Goerentz - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class Utils {
|
||||
|
||||
private static final Map<String, Unit<?>> UNIT_MAP = Map.of(NUMBER_LENGTH, SIUnits.METRE, NUMBER_POWER, Units.WATT,
|
||||
NUMBER_ENERGY, Units.WATT_HOUR, NUMBER_TIME, Units.SECOND, NUMBER_ELECTRIC_CURRENT, Units.AMPERE,
|
||||
NUMBER_DIMENSIONLESS, Units.ONE, NUMBER_EMISSION_INTENSITY, SIUnits.GRAM.divide(Units.KILOWATT_HOUR));
|
||||
|
||||
/**
|
||||
* This method retrieves the unit for the corresponding item type
|
||||
*
|
||||
* @param itemType the unit will be received for
|
||||
* @return Unit<?> that is mapped to the item type
|
||||
*/
|
||||
public static Unit<?> getUnitFromChannelType(String itemType) {
|
||||
Unit<?> unit = UNIT_MAP.get(itemType);
|
||||
return Objects.requireNonNullElse(unit, Units.ONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will capitalize the words of a given string
|
||||
*
|
||||
* @param input string containing hyphenized words
|
||||
* @return A string with spaces instead of hyphens and the first letter of each word is capitalized
|
||||
*/
|
||||
public static String capitalizeWords(String input) {
|
||||
String[] allParts = input.split("-");
|
||||
String[] parts = Arrays.stream(allParts, 1, allParts.length).toArray(String[]::new);
|
||||
StringJoiner joiner = new StringJoiner(" ");
|
||||
|
||||
for (String part : parts) {
|
||||
if (!part.isEmpty()) {
|
||||
joiner.add(Character.toUpperCase(part.charAt(0)) + part.substring(1));
|
||||
}
|
||||
}
|
||||
|
||||
return joiner.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will sanitize a given string for a channel ID
|
||||
*
|
||||
* @param input camel case string
|
||||
* @return A string that contains hyphens
|
||||
*/
|
||||
public static String sanitizeChannelID(String input) {
|
||||
return input.replaceAll("(?<!^)(?=[A-Z])", "-").toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will get the key from a ChannelUID
|
||||
*
|
||||
* @param channelUID which the key shall be retrieved from
|
||||
* @return the key in camel case
|
||||
*/
|
||||
public static String getKeyFromChannelUID(ChannelUID channelUID) {
|
||||
String[] split = channelUID.getIdWithoutGroup().split("-");
|
||||
String[] parts = Arrays.stream(split, 1, split.length).toArray(String[]::new);
|
||||
|
||||
StringBuilder camelCase = new StringBuilder();
|
||||
for (int i = 0; i < parts.length; i++) {
|
||||
String part = parts[i];
|
||||
if (i == 0) {
|
||||
camelCase.append(part.toLowerCase());
|
||||
} else {
|
||||
camelCase.append(part.substring(0, 1).toUpperCase());
|
||||
camelCase.append(part.substring(1).toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
return camelCase.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will convert the version string into an int array
|
||||
* If the input is blank, the method will return 0, 0, 0
|
||||
*
|
||||
* @param input version string
|
||||
* @return int array of size 3
|
||||
*/
|
||||
public static int[] convertVersionStringToIntArray(String input) {
|
||||
if (input.isEmpty()) {
|
||||
return new int[] { 0, 0, 0 };
|
||||
}
|
||||
return Arrays.stream(input.split("\\.")).mapToInt(Integer::parseInt).toArray();
|
||||
}
|
||||
}
|
||||
@@ -5,189 +5,386 @@ addon.evcc.description = This is the binding for evcc (electric vehicle charging
|
||||
|
||||
# thing types
|
||||
|
||||
thing-type.evcc.device.label = evcc installation
|
||||
thing-type.evcc.device.description = A running evcc installation
|
||||
thing-type.evcc.battery.label = Battery
|
||||
thing-type.evcc.battery.description = A battery configured in your evcc instance
|
||||
thing-type.evcc.heating.label = Heating - Loadpoint
|
||||
thing-type.evcc.heating.description = A heating loadpoint configured in your evcc instance
|
||||
thing-type.evcc.loadpoint.label = Loadpoint
|
||||
thing-type.evcc.loadpoint.description = A loadpoint configured in your evcc instance
|
||||
thing-type.evcc.pv.label = Photovoltaic
|
||||
thing-type.evcc.pv.description = A photovoltaic system configured in your evcc instance
|
||||
thing-type.evcc.server.label = Server
|
||||
thing-type.evcc.server.description = Connection to evcc instance
|
||||
thing-type.evcc.site.label = Site
|
||||
thing-type.evcc.site.description = The site configured in your evcc instance
|
||||
thing-type.evcc.statistics.label = Statistics
|
||||
thing-type.evcc.statistics.description = Statistics about your evcc instance
|
||||
thing-type.evcc.statistics.group.30d.label = Last 30 Days
|
||||
thing-type.evcc.statistics.group.30d.description = Statistics from the last 30 days
|
||||
thing-type.evcc.statistics.group.365d.label = Last 365 Days
|
||||
thing-type.evcc.statistics.group.365d.description = Statistics from the last 365days
|
||||
thing-type.evcc.statistics.group.this-year.label = Last Year
|
||||
thing-type.evcc.statistics.group.this-year.description = Statistics from the last year
|
||||
thing-type.evcc.statistics.group.total.label = Total
|
||||
thing-type.evcc.statistics.group.total.description = Total statistics
|
||||
thing-type.evcc.vehicle.label = Vehicle
|
||||
thing-type.evcc.vehicle.description = A vehicle configured in your evcc instance
|
||||
|
||||
# thing types config
|
||||
|
||||
thing-type.config.evcc.device.refreshInterval.label = Refresh Interval
|
||||
thing-type.config.evcc.device.refreshInterval.description = Interval the status is polled in seconds.
|
||||
thing-type.config.evcc.device.url.label = URL
|
||||
thing-type.config.evcc.device.url.description = URL of evcc web UI, e.g. https://demo.evcc.io
|
||||
thing-type.config.evcc.server.host.label = Hostname or IP
|
||||
thing-type.config.evcc.server.host.description = Address of your evcc instance, for example evcc.local or 192.168.1.2
|
||||
thing-type.config.evcc.server.pollInterval.label = Polling Interval
|
||||
thing-type.config.evcc.server.pollInterval.description = How often should the state be polled? (in seconds, default is 30s)
|
||||
thing-type.config.evcc.server.port.label = Port
|
||||
thing-type.config.evcc.server.port.description = HTTP-Port of your instance (Default: 7070)
|
||||
thing-type.config.evcc.server.scheme.label = Protocol Scheme
|
||||
thing-type.config.evcc.server.scheme.description = The protocol scheme that should be used to connect to your instance
|
||||
thing-type.config.evcc.server.scheme.option.http = HTTP
|
||||
thing-type.config.evcc.server.scheme.option.https = HTTPS
|
||||
|
||||
# channel group types
|
||||
|
||||
channel-group-type.evcc.general.label = General Data
|
||||
channel-group-type.evcc.loadpoint0.label = Loadpoint 0
|
||||
channel-group-type.evcc.loadpoint0current.label = Loadpoint 0: Current
|
||||
channel-group-type.evcc.loadpoint1.label = Loadpoint 1
|
||||
channel-group-type.evcc.loadpoint1current.label = Loadpoint 1: Current
|
||||
channel-group-type.evcc.loadpoint2.label = Loadpoint 2
|
||||
channel-group-type.evcc.loadpoint2current.label = Loadpoint 2: Current
|
||||
channel-group-type.evcc.loadpoint3.label = Loadpoint 3
|
||||
channel-group-type.evcc.loadpoint3current.label = Loadpoint 3: Current
|
||||
channel-group-type.evcc.loadpoint4.label = Loadpoint 4
|
||||
channel-group-type.evcc.loadpoint4current.label = Loadpoint 4: Current
|
||||
channel-group-type.evcc.loadpoint5.label = Loadpoint 5
|
||||
channel-group-type.evcc.loadpoint5current.label = Loadpoint 5: Current
|
||||
channel-group-type.evcc.loadpoint6.label = Loadpoint 6
|
||||
channel-group-type.evcc.loadpoint6current.label = Loadpoint 6: Current
|
||||
channel-group-type.evcc.loadpoint7.label = Loadpoint 7
|
||||
channel-group-type.evcc.loadpoint7current.label = Loadpoint 7: Current
|
||||
channel-group-type.evcc.loadpoint8.label = Loadpoint 8
|
||||
channel-group-type.evcc.loadpoint8current.label = Loadpoint 8: Current
|
||||
channel-group-type.evcc.loadpoint9.label = Loadpoint 9
|
||||
channel-group-type.evcc.loadpoint9current.label = Loadpoint 9: Current
|
||||
channel-group-type.evcc.statistics-group.label = Statistics Group
|
||||
|
||||
# channel types
|
||||
|
||||
channel-type.evcc.activePhases.label = Charging Active Phases
|
||||
channel-type.evcc.activePhases.description = Current number of active phases while charging
|
||||
channel-type.evcc.availableVersion.label = Available Version
|
||||
channel-type.evcc.availableVersion.description = Available evcc update version
|
||||
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.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
|
||||
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 limit SoC is reached
|
||||
channel-type.evcc.chargeRemainingEnergy.label = Charging Remaining Energy
|
||||
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.chargerFeatureHeating.label = Charger Feature: Heating
|
||||
channel-type.evcc.chargerFeatureHeating.description = 'True' for heating device: State of Charge in Degree instead of Percent
|
||||
channel-type.evcc.chargerFeatureHeating.state.option.ON = True
|
||||
channel-type.evcc.chargerFeatureHeating.state.option.OFF = False
|
||||
channel-type.evcc.chargerFeatureIntegratedDevice.label = Charger Feature: Integrated Device
|
||||
channel-type.evcc.chargerFeatureIntegratedDevice.description = 'True' for integrated device: Operate without a "vehicle" (e.g. heat pump, eBike)
|
||||
channel-type.evcc.chargerFeatureIntegratedDevice.state.option.ON = True
|
||||
channel-type.evcc.chargerFeatureIntegratedDevice.state.option.OFF = False
|
||||
channel-type.evcc.charging.label = Charging State
|
||||
channel-type.evcc.charging.description = Loadpoint is currently charging
|
||||
channel-type.evcc.charging.state.option.ON = Charging
|
||||
channel-type.evcc.charging.state.option.OFF = Not charging
|
||||
channel-type.evcc.effectiveLimitSoC.label = Effective Charging Limit
|
||||
channel-type.evcc.effectiveLimitSoC.description = Effective state of charge (SoC) until which the vehicle will be charged
|
||||
channel-type.evcc.effectiveLimitTemperature.label = Effective Charging Limit Temperature
|
||||
channel-type.evcc.effectiveLimitTemperature.description = Effective Temperature until which the heating device will be charged
|
||||
channel-type.evcc.enabled.label = Charging Enabled
|
||||
channel-type.evcc.enabled.description = Charging enabled (mode not "off")
|
||||
channel-type.evcc.enabled.state.option.ON = Enabled
|
||||
channel-type.evcc.enabled.state.option.OFF = Disabled
|
||||
channel-type.evcc.gridPower.label = Grid Power
|
||||
channel-type.evcc.gridPower.description = Current power from grid (negative means feed-in)
|
||||
channel-type.evcc.heatingCapacity.label = Heating Capacity
|
||||
channel-type.evcc.heatingCapacity.description = Capacity of heating device
|
||||
channel-type.evcc.heatingLimitTemperature.label = Charging Temperature Limit
|
||||
channel-type.evcc.heatingLimitTemperature.description = Until which Temperature should the specific heating device be charged
|
||||
channel-type.evcc.heatingMinTemperature.label = Heating Min Temperature
|
||||
channel-type.evcc.heatingMinTemperature.description = Minimum Temperature a heating device should have
|
||||
channel-type.evcc.heatingPlanEnabled.label = Heating Plan Enabled
|
||||
channel-type.evcc.heatingPlanEnabled.description = Plan for charging enabled
|
||||
channel-type.evcc.heatingPlanEnabled.state.option.ON = Enabled
|
||||
channel-type.evcc.heatingPlanEnabled.state.option.OFF = Disabled
|
||||
channel-type.evcc.heatingPlanTemperature.label = Heating Plan Temperature
|
||||
channel-type.evcc.heatingPlanTemperature.description = Until which Temperature should heating device be charged in plan
|
||||
channel-type.evcc.heatingPlanTime.label = Heating Plan Time
|
||||
channel-type.evcc.heatingPlanTime.description = When the plan Temperature should be reached
|
||||
channel-type.evcc.heatingTitle.label = Heating Title
|
||||
channel-type.evcc.heatingTitle.description = Title of heating device
|
||||
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.limitTemperature.label = Charging Limit Temperature
|
||||
channel-type.evcc.limitTemperature.description = Until which Temperature should the heating device 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.mode.label = Charging Mode
|
||||
channel-type.evcc.mode.description = Charging mode: "off", "now", "minpv", "pv"
|
||||
channel-type.evcc.mode.state.option.off = Off
|
||||
channel-type.evcc.mode.state.option.now = Fast
|
||||
channel-type.evcc.mode.state.option.minpv = Min + PV
|
||||
channel-type.evcc.mode.state.option.pv = Only PV
|
||||
channel-type.evcc.phases.label = Charging Enabled Phases
|
||||
channel-type.evcc.phases.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.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
|
||||
channel-type.evcc.vehicleCapacity.description = Capacity of EV battery
|
||||
channel-type.evcc.vehicleConnected.label = Vehicle Connected
|
||||
channel-type.evcc.vehicleConnected.description = Whether vehicle is connected to loadpoint
|
||||
channel-type.evcc.vehicleConnected.state.option.ON = Connected
|
||||
channel-type.evcc.vehicleConnected.state.option.OFF = Not connected
|
||||
channel-type.evcc.vehicleConnectedDuration.label = Vehicle Connected Duration
|
||||
channel-type.evcc.vehicleConnectedDuration.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
|
||||
channel-type.evcc.vehiclePresent.state.option.OFF = No data access
|
||||
channel-type.evcc.vehicleRange.label = Vehicle Range
|
||||
channel-type.evcc.vehicleRange.description = Battery range for EV
|
||||
channel-type.evcc.vehicleSoC.label = Vehicle SoC
|
||||
channel-type.evcc.vehicleSoC.description = Current State of Charge of EV
|
||||
channel-type.evcc.vehicleTemperature.label = Temperature
|
||||
channel-type.evcc.vehicleTemperature.description = Current Temperature of the heating device
|
||||
channel-type.evcc.vehicleTitle.label = Vehicle Title
|
||||
channel-type.evcc.vehicleTitle.description = Title of vehicle
|
||||
channel-type.evcc.version.label = Version
|
||||
channel-type.evcc.version.description = Current evcc version
|
||||
channel-type.evcc.avg-co2-type.label = Average C02
|
||||
channel-type.evcc.avg-price-type.label = Average Price
|
||||
channel-type.evcc.battery-capacity.label = Battery Capacity
|
||||
channel-type.evcc.battery-capacity.description = Capacity of this battery
|
||||
channel-type.evcc.battery-controllable.label = Battery Controllable
|
||||
channel-type.evcc.battery-controllable.description = Indicates whether this battery is controllable or not
|
||||
channel-type.evcc.battery-controllable.state.option.ON = Controllable
|
||||
channel-type.evcc.battery-controllable.state.option.OFF = Not Controllable
|
||||
channel-type.evcc.battery-power.label = Battery Power
|
||||
channel-type.evcc.battery-power.description = Current power from this battery
|
||||
channel-type.evcc.battery-soc.label = Battery SoC
|
||||
channel-type.evcc.battery-soc.description = Current state of charge of this battery
|
||||
channel-type.evcc.battery-title.label = Title
|
||||
channel-type.evcc.battery-title.description = Battery name displayed in the UI
|
||||
channel-type.evcc.charged-energy-type.label = Charged Energy
|
||||
channel-type.evcc.loadpoint-battery-boost.label = Battery Boost
|
||||
channel-type.evcc.loadpoint-battery-boost.description = Controls and indicates whether battery boost is active or not
|
||||
channel-type.evcc.loadpoint-battery-boost.state.option.ON = Activated
|
||||
channel-type.evcc.loadpoint-battery-boost.state.option.OFF = Deactivated
|
||||
channel-type.evcc.loadpoint-charge-duration.label = Charging Duration
|
||||
channel-type.evcc.loadpoint-charge-duration.description = Time passed since start of the charging
|
||||
channel-type.evcc.loadpoint-charge-power.label = Charging Power
|
||||
channel-type.evcc.loadpoint-charge-power.description = Current power of charging
|
||||
channel-type.evcc.loadpoint-charge-remaining-duration.label = Charging Remaining Duration
|
||||
channel-type.evcc.loadpoint-charge-remaining-duration.description = Remaining duration until limit SoC is reached
|
||||
channel-type.evcc.loadpoint-charge-remaining-energy.label = Charging Remaining Energy
|
||||
channel-type.evcc.loadpoint-charge-remaining-energy.description = Remaining energy until limit SoC is reached
|
||||
channel-type.evcc.loadpoint-charge-total-import.label = Charge Total Import
|
||||
channel-type.evcc.loadpoint-charge-total-import.description = Total imported energy
|
||||
channel-type.evcc.loadpoint-charged-energy.label = Charged Energy
|
||||
channel-type.evcc.loadpoint-charged-energy.description = Energy charged since plugged-in
|
||||
channel-type.evcc.loadpoint-charger-feature-heating.label = Heating
|
||||
channel-type.evcc.loadpoint-charger-feature-heating.description = Indicates whether the loadpoint is configured for a heating device
|
||||
channel-type.evcc.loadpoint-charger-feature-heating.state.option.ON = True
|
||||
channel-type.evcc.loadpoint-charger-feature-heating.state.option.OFF = False
|
||||
channel-type.evcc.loadpoint-charger-feature-integrated-device.label = Integrated Device
|
||||
channel-type.evcc.loadpoint-charger-feature-integrated-device.description = Loadpoint has an integrated device and runs without a vehicle (e.g. heatpump, e-bike)
|
||||
channel-type.evcc.loadpoint-charger-feature-integrated-device.state.option.ON = True
|
||||
channel-type.evcc.loadpoint-charger-feature-integrated-device.state.option.OFF = False
|
||||
channel-type.evcc.loadpoint-charger-icon.label = Charger Icon
|
||||
channel-type.evcc.loadpoint-charger-icon.description = Icon used in the UI for this charger
|
||||
channel-type.evcc.loadpoint-charger-phases1p3p.label = Phase Switching
|
||||
channel-type.evcc.loadpoint-charger-phases1p3p.description = Indicates that the loadpoint can switch between 1 and 3 phases
|
||||
channel-type.evcc.loadpoint-charger-phases1p3p.state.option.ON = True
|
||||
channel-type.evcc.loadpoint-charger-phases1p3p.state.option.OFF = False
|
||||
channel-type.evcc.loadpoint-charger-single-phase.label = 1 Phase Charging
|
||||
channel-type.evcc.loadpoint-charger-single-phase.description = Indicates that the charger can only charge with 1 phase
|
||||
channel-type.evcc.loadpoint-charger-single-phase.state.option.ON = True
|
||||
channel-type.evcc.loadpoint-charger-single-phase.state.option.OFF = False
|
||||
channel-type.evcc.loadpoint-charger-status-reason.label = Charger Status Reason
|
||||
channel-type.evcc.loadpoint-charger-status-reason.description = Hint why the charging has not started yet
|
||||
channel-type.evcc.loadpoint-charger-status-reason.state.option.unknown = Unknown
|
||||
channel-type.evcc.loadpoint-charger-status-reason.state.option.waitingforauthorization = Waiting for authorization
|
||||
channel-type.evcc.loadpoint-charger-status-reason.state.option.disconnectrequired = Disconnect required
|
||||
channel-type.evcc.loadpoint-charging.label = Charging State
|
||||
channel-type.evcc.loadpoint-charging.description = Indicates whether the loadpoint is charging or not
|
||||
channel-type.evcc.loadpoint-charging.state.option.ON = Charging
|
||||
channel-type.evcc.loadpoint-charging.state.option.OFF = Not charging
|
||||
channel-type.evcc.loadpoint-connected-duration.label = Vehicle Conn. Duration
|
||||
channel-type.evcc.loadpoint-connected-duration.description = Duration the vehicle is connected to the loadpoint
|
||||
channel-type.evcc.loadpoint-connected.label = Vehicle Connected
|
||||
channel-type.evcc.loadpoint-connected.description = Indicates whether a vehicle is connected or not
|
||||
channel-type.evcc.loadpoint-connected.state.option.ON = Connected
|
||||
channel-type.evcc.loadpoint-connected.state.option.OFF = Not connected
|
||||
channel-type.evcc.loadpoint-disable-delay.label = Disable Delay
|
||||
channel-type.evcc.loadpoint-disable-delay.description = Delay in PV mode before stopping the charging if not enough power is available
|
||||
channel-type.evcc.loadpoint-disable-threshold.label = Disable Threshold
|
||||
channel-type.evcc.loadpoint-disable-threshold.description = Threshold for the disable delay (negative values means feed in)
|
||||
channel-type.evcc.loadpoint-effective-limit-soc.label = Active Charging Limit
|
||||
channel-type.evcc.loadpoint-effective-limit-soc.description = Active state of charge the vehicle will be charged to
|
||||
channel-type.evcc.loadpoint-effective-limit-temperature.label = Effective Charging Limit Temperature
|
||||
channel-type.evcc.loadpoint-effective-limit-temperature.description = Effective Temperature until which the heating device will be charged
|
||||
channel-type.evcc.loadpoint-effective-max-current.label = Active Maximum Current
|
||||
channel-type.evcc.loadpoint-effective-max-current.description = Effective maximum amperage per connected phase that can be provided to the vehicle
|
||||
channel-type.evcc.loadpoint-effective-min-current.label = Active Minimum Current
|
||||
channel-type.evcc.loadpoint-effective-min-current.description = Effective minimum amperage per connected phase that will be provided to the vehicle
|
||||
channel-type.evcc.loadpoint-effective-plan-id.label = Active Plan ID
|
||||
channel-type.evcc.loadpoint-effective-plan-id.description = ID of the currently active charging plan
|
||||
channel-type.evcc.loadpoint-effective-plan-soc.label = Active Plan SoC
|
||||
channel-type.evcc.loadpoint-effective-plan-soc.description = State of charge limit for the currently active charging plan
|
||||
channel-type.evcc.loadpoint-effective-plan-time.label = Active Plan Time
|
||||
channel-type.evcc.loadpoint-effective-plan-time.description = Indicating when the next charge slot starts
|
||||
channel-type.evcc.loadpoint-effective-priority.label = Active Priority
|
||||
channel-type.evcc.loadpoint-effective-priority.description = Effective priority of this loadpoint
|
||||
channel-type.evcc.loadpoint-enable-delay.label = Enable Delay
|
||||
channel-type.evcc.loadpoint-enable-delay.description = Delay in PV mode before starting the charging when enough power is available
|
||||
channel-type.evcc.loadpoint-enable-threshold.label = Enable Threshold
|
||||
channel-type.evcc.loadpoint-enable-threshold.description = Threshold for the enable delay
|
||||
channel-type.evcc.loadpoint-enabled.label = Loadpoint Enabled
|
||||
channel-type.evcc.loadpoint-enabled.description = Indicates whether the charger is locked or released
|
||||
channel-type.evcc.loadpoint-enabled.state.option.ON = Released
|
||||
channel-type.evcc.loadpoint-enabled.state.option.OFF = Locked
|
||||
channel-type.evcc.loadpoint-limit-energy.label = Energy Limit
|
||||
channel-type.evcc.loadpoint-limit-energy.description = Energy limit when charging the vehicle
|
||||
channel-type.evcc.loadpoint-limit-soc.label = SoC Limit
|
||||
channel-type.evcc.loadpoint-limit-soc.description = State of charge limit when charging the vehicle
|
||||
channel-type.evcc.loadpoint-limit-temperature.label = Temperature Limit
|
||||
channel-type.evcc.loadpoint-limit-temperature.description = Temperature to which the heating device is charged
|
||||
channel-type.evcc.loadpoint-max-current.label = Maximum Current
|
||||
channel-type.evcc.loadpoint-max-current.description = Maximum amperage per connected phase that can be provided to the vehicle
|
||||
channel-type.evcc.loadpoint-min-current.label = Minimum Current
|
||||
channel-type.evcc.loadpoint-min-current.description = Minimum amperage per connected phase that will be provided to the vehicle
|
||||
channel-type.evcc.loadpoint-mode.label = Mode
|
||||
channel-type.evcc.loadpoint-mode.description = Charging Mode
|
||||
channel-type.evcc.loadpoint-mode.state.option.off = Off
|
||||
channel-type.evcc.loadpoint-mode.state.option.now = Fast
|
||||
channel-type.evcc.loadpoint-mode.state.option.minpv = Min + PV
|
||||
channel-type.evcc.loadpoint-mode.state.option.pv = Only PV
|
||||
channel-type.evcc.loadpoint-offered-current.label = Offered Current
|
||||
channel-type.evcc.loadpoint-offered-current.description = Current amperage per connected phase offered to the vehicle
|
||||
channel-type.evcc.loadpoint-phase-action.label = Phase Scaling
|
||||
channel-type.evcc.loadpoint-phase-action.description = Indicates phase switching from 1 to 3 or 3 to 1 phases
|
||||
channel-type.evcc.loadpoint-phase-action.state.option.scale1p = Switching to 1 phase
|
||||
channel-type.evcc.loadpoint-phase-action.state.option.scale3p = Switching to 3 phases
|
||||
channel-type.evcc.loadpoint-phase-remaining.label = Phase Remaining Timer
|
||||
channel-type.evcc.loadpoint-phase-remaining.description = Time until phase switching will occure
|
||||
channel-type.evcc.loadpoint-phases-active.label = Active Phases
|
||||
channel-type.evcc.loadpoint-phases-active.description = Current number of active phases
|
||||
channel-type.evcc.loadpoint-phases-configured.label = Configured Phases
|
||||
channel-type.evcc.loadpoint-phases-configured.description = Number of configured phases
|
||||
channel-type.evcc.loadpoint-plan-active.label = Plan Activated
|
||||
channel-type.evcc.loadpoint-plan-active.description = Indicates whether a plan is active or not
|
||||
channel-type.evcc.loadpoint-plan-active.state.option.ON = Activated
|
||||
channel-type.evcc.loadpoint-plan-active.state.option.OFF = Deactivated
|
||||
channel-type.evcc.loadpoint-plan-energy.label = Plan Energy
|
||||
channel-type.evcc.loadpoint-plan-energy.description = Charge plan energy goal
|
||||
channel-type.evcc.loadpoint-plan-overrun.label = Plan Overrun
|
||||
channel-type.evcc.loadpoint-plan-overrun.description = Indicates that the charge plan goal is not reachable in time
|
||||
channel-type.evcc.loadpoint-plan-precondition.label = Plan Precondition
|
||||
channel-type.evcc.loadpoint-plan-precondition.description = Duration for preconditioning the battery
|
||||
channel-type.evcc.loadpoint-plan-projected-end.label = Plan Projected End
|
||||
channel-type.evcc.loadpoint-plan-projected-end.description = Projected end of charging
|
||||
channel-type.evcc.loadpoint-plan-projected-start.label = Plan Projected Start
|
||||
channel-type.evcc.loadpoint-plan-projected-start.description = Projected start of charging
|
||||
channel-type.evcc.loadpoint-priority.label = Priority
|
||||
channel-type.evcc.loadpoint-priority.description = Priority of this loadpoint
|
||||
channel-type.evcc.loadpoint-pv-action.label = PV Action
|
||||
channel-type.evcc.loadpoint-pv-action.description = Indicates whether pv charging gets enabled or disabled
|
||||
channel-type.evcc.loadpoint-pv-action.state.option.inactive = Inactive
|
||||
channel-type.evcc.loadpoint-pv-action.state.option.pvEnable = Enable PV Timer
|
||||
channel-type.evcc.loadpoint-pv-action.state.option.pvDisable = Disable PV Timer
|
||||
channel-type.evcc.loadpoint-pv-remaining.label = Pv Remaining
|
||||
channel-type.evcc.loadpoint-pv-remaining.description = Timer for enabling or disabling pv charging
|
||||
channel-type.evcc.loadpoint-session-co2-per-k-wh.label = Session CO2 Per kWh
|
||||
channel-type.evcc.loadpoint-session-co2-per-k-wh.description = Current session emitted carbon dioxide per kWh
|
||||
channel-type.evcc.loadpoint-session-energy.label = Session Energy
|
||||
channel-type.evcc.loadpoint-session-energy.description = Charged energy in the current charging session
|
||||
channel-type.evcc.loadpoint-session-price-per-k-wh.label = Session Price Per kWh
|
||||
channel-type.evcc.loadpoint-session-price-per-k-wh.description = Current session charging price per kWh
|
||||
channel-type.evcc.loadpoint-session-price.label = Session Price
|
||||
channel-type.evcc.loadpoint-session-price.description = Costs of the current charging session
|
||||
channel-type.evcc.loadpoint-session-solar-percentage.label = Session Solar Percentage
|
||||
channel-type.evcc.loadpoint-session-solar-percentage.description = Percentage of solar energy for the current charging session
|
||||
channel-type.evcc.loadpoint-smart-cost-active.label = Smart Cost Active
|
||||
channel-type.evcc.loadpoint-smart-cost-active.description = Indicates whether smart charging is active or not
|
||||
channel-type.evcc.loadpoint-smart-cost-active.state.option.ON = Active
|
||||
channel-type.evcc.loadpoint-smart-cost-active.state.option.OFF = Inactive
|
||||
channel-type.evcc.loadpoint-smart-cost-limit-co2.label = Smart Cost Limit
|
||||
channel-type.evcc.loadpoint-smart-cost-limit-co2.description = Below this limit the smart charging will start
|
||||
channel-type.evcc.loadpoint-smart-cost-limit-price.label = Smart Cost Limit
|
||||
channel-type.evcc.loadpoint-smart-cost-limit-price.description = Below this limit the smart charging will start
|
||||
channel-type.evcc.loadpoint-smart-cost-next-start.label = Smart Cost Next Start
|
||||
channel-type.evcc.loadpoint-smart-cost-next-start.description = Startpoint for the next smart charging
|
||||
channel-type.evcc.loadpoint-smart-feed-in-priority-active.label = Smart Feed In Priority Active
|
||||
channel-type.evcc.loadpoint-smart-feed-in-priority-active.description = Indicates that smart feed in has priority
|
||||
channel-type.evcc.loadpoint-title.label = Title
|
||||
channel-type.evcc.loadpoint-title.description = Name of the loadpoint as displayed in the UI
|
||||
channel-type.evcc.loadpoint-vehicle-climater-active.label = Vehicle Climate Active
|
||||
channel-type.evcc.loadpoint-vehicle-climater-active.description = Indicates whether the climate control is active or not for the connected vehicle
|
||||
channel-type.evcc.loadpoint-vehicle-climater-active.state.option.ON = Active
|
||||
channel-type.evcc.loadpoint-vehicle-climater-active.state.option.OFF = Inactive
|
||||
channel-type.evcc.loadpoint-vehicle-detection-active.label = Vehicle Detection Active
|
||||
channel-type.evcc.loadpoint-vehicle-detection-active.description = Indicates whether the vehicle detection is active or not
|
||||
channel-type.evcc.loadpoint-vehicle-detection-active.state.option.ON = Active
|
||||
channel-type.evcc.loadpoint-vehicle-detection-active.state.option.OFF = Inactive
|
||||
channel-type.evcc.loadpoint-vehicle-identity.label = Vehicle Identity
|
||||
channel-type.evcc.loadpoint-vehicle-identity.description = Transferred vehicle identity
|
||||
channel-type.evcc.loadpoint-vehicle-limit-soc.label = Vehicle API SoC Limit
|
||||
channel-type.evcc.loadpoint-vehicle-limit-soc.description = Current vehicle API state of charge limit
|
||||
channel-type.evcc.loadpoint-vehicle-name.label = Vehicle Name
|
||||
channel-type.evcc.loadpoint-vehicle-name.description = The unique identifier of the vehicle used in the evcc configuration (containing no whitespaces nor special characters)
|
||||
channel-type.evcc.loadpoint-vehicle-odometer.label = Vehicle Odometer
|
||||
channel-type.evcc.loadpoint-vehicle-odometer.description = Total distance travelled by the vehicle
|
||||
channel-type.evcc.loadpoint-vehicle-range.label = Vehicle Range
|
||||
channel-type.evcc.loadpoint-vehicle-range.description = Current range of the vehicle
|
||||
channel-type.evcc.loadpoint-vehicle-soc.label = Vehicle API SoC
|
||||
channel-type.evcc.loadpoint-vehicle-soc.description = Current state of charge of the vehicle
|
||||
channel-type.evcc.loadpoint-vehicle-temperature.label = Temperature
|
||||
channel-type.evcc.loadpoint-vehicle-temperature.description = Current temperature of the heating device
|
||||
channel-type.evcc.loadpoint-vehicle-title.label = Vehicle Title
|
||||
channel-type.evcc.loadpoint-vehicle-title.description = The name of the vehicle as displayed in the UI
|
||||
channel-type.evcc.loadpoint-vehicle-welcome-active.label = Vehicle Welcome Active
|
||||
channel-type.evcc.loadpoint-vehicle-welcome-active.description = Indicates whether the charger performs an initial charge or not when the vehicle gets connected
|
||||
channel-type.evcc.loadpoint-vehicle-welcome-active.state.option.ON = Active
|
||||
channel-type.evcc.loadpoint-vehicle-welcome-active.state.option.OFF = Inactive
|
||||
channel-type.evcc.pv-power.label = PV Power
|
||||
channel-type.evcc.pv-power.description = Current power of this photovoltaic system in Watt
|
||||
channel-type.evcc.pv-title.label = Title
|
||||
channel-type.evcc.pv-title.description = Name of the photovoltaic system as displayed in the UI
|
||||
channel-type.evcc.site-available-version.label = Available Version
|
||||
channel-type.evcc.site-available-version.description = Available evcc update version
|
||||
channel-type.evcc.site-battery-capacity.label = Site Battery Capacity
|
||||
channel-type.evcc.site-battery-capacity.description = Accumulated battery capacity for this site
|
||||
channel-type.evcc.site-battery-discharge-control.label = Battery Discharge Control
|
||||
channel-type.evcc.site-battery-discharge-control.description = Enable or disable battery discharge control
|
||||
channel-type.evcc.site-battery-discharge-control.state.option.ON = Enabled
|
||||
channel-type.evcc.site-battery-discharge-control.state.option.OFF = Disabled
|
||||
channel-type.evcc.site-battery-energy.label = Battery Energy
|
||||
channel-type.evcc.site-battery-energy.description = Energy provided from the battery(ies)
|
||||
channel-type.evcc.site-battery-grid-charge-active.label = Grid Charging Active
|
||||
channel-type.evcc.site-battery-grid-charge-active.description = Indicates whether the battery gets charged from the grid or not
|
||||
channel-type.evcc.site-battery-grid-charge-active.state.option.ON = Active
|
||||
channel-type.evcc.site-battery-grid-charge-active.state.option.OFF = Inactive
|
||||
channel-type.evcc.site-battery-grid-charge-limit-co2.label = Grid Charging Limit
|
||||
channel-type.evcc.site-battery-grid-charge-limit-co2.description = Below this smart cost limit the charging from grid will start (currency or co2)
|
||||
channel-type.evcc.site-battery-grid-charge-limit-price.label = Grid Charging Limit
|
||||
channel-type.evcc.site-battery-grid-charge-limit-price.description = Below this smart cost limit the charging from grid will start (currency or co2)
|
||||
channel-type.evcc.site-battery-mode-external.label = Battery Mode
|
||||
channel-type.evcc.site-battery-mode-external.description = Current battery mode cached from external
|
||||
channel-type.evcc.site-battery-mode-external.state.option.unknow = Unknown
|
||||
channel-type.evcc.site-battery-mode-external.state.option.normal = Normal
|
||||
channel-type.evcc.site-battery-mode-external.state.option.hold = Locked
|
||||
channel-type.evcc.site-battery-mode-external.state.option.charge = Charging
|
||||
channel-type.evcc.site-battery-mode.label = Battery Mode
|
||||
channel-type.evcc.site-battery-mode.description = Current battery mode for the site
|
||||
channel-type.evcc.site-battery-mode.state.option.unknow = Unknown
|
||||
channel-type.evcc.site-battery-mode.state.option.normal = Normal
|
||||
channel-type.evcc.site-battery-mode.state.option.hold = Locked
|
||||
channel-type.evcc.site-battery-mode.state.option.charge = Charging
|
||||
channel-type.evcc.site-battery-power.label = Battery Power
|
||||
channel-type.evcc.site-battery-power.description = Accumulated power distributed by the battery(ies)
|
||||
channel-type.evcc.site-battery-soc.label = Battery SoC
|
||||
channel-type.evcc.site-battery-soc.description = Current state of charge of battery(ies)
|
||||
channel-type.evcc.site-buffer-soc.label = Battery Buffer SoC
|
||||
channel-type.evcc.site-buffer-soc.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.site-buffer-start-soc.label = Battery Buffer Start SoC
|
||||
channel-type.evcc.site-buffer-start-soc.description = State of charge for which a charging session in "pv" mode is started, even if there is insufficient solar surplus
|
||||
channel-type.evcc.site-currency.label = Currency
|
||||
channel-type.evcc.site-currency.description = Current configured currency
|
||||
channel-type.evcc.site-demo-mode.label = Demo Mode
|
||||
channel-type.evcc.site-demo-mode.description = Indicates whether demo mode is active or not
|
||||
channel-type.evcc.site-demo-mode.state.option.ON = Active
|
||||
channel-type.evcc.site-demo-mode.state.option.OFF = Inactive
|
||||
channel-type.evcc.site-eebus.label = EEBUS
|
||||
channel-type.evcc.site-eebus.description = Indicates whether EEBUS is configured or not
|
||||
channel-type.evcc.site-eebus.state.option.ON = Configured
|
||||
channel-type.evcc.site-eebus.state.option.OFF = Not configured
|
||||
channel-type.evcc.site-green-share-home.label = Green Share Home
|
||||
channel-type.evcc.site-green-share-home.description = Indicates whether green power is available for home
|
||||
channel-type.evcc.site-green-share-loadpoints.label = Green Share Loadpoints
|
||||
channel-type.evcc.site-green-share-loadpoints.description = Indicates whether green power is available for loadpoints
|
||||
channel-type.evcc.site-grid-power.label = Grid Power
|
||||
channel-type.evcc.site-grid-power.description = Current power from grid (negative means feed-in)
|
||||
channel-type.evcc.site-home-power.label = Home Power
|
||||
channel-type.evcc.site-home-power.description = Current power consumption by home
|
||||
channel-type.evcc.site-interval.label = Interval
|
||||
channel-type.evcc.site-interval.description = Refresh interval configured for evcc
|
||||
channel-type.evcc.site-messaging.label = Site Messaging
|
||||
channel-type.evcc.site-messaging.description = Indicates whether messaging has been configured or not
|
||||
channel-type.evcc.site-messaging.state.option.ON = Configured
|
||||
channel-type.evcc.site-messaging.state.option.OFF = Not configured
|
||||
channel-type.evcc.site-priority-soc.label = Battery Priority SoC
|
||||
channel-type.evcc.site-priority-soc.description = State of charge for which the battery has priority over charging the vehicle when charging mode is "pv"
|
||||
channel-type.evcc.site-pv-energy.label = PV Energy
|
||||
channel-type.evcc.site-pv-energy.description = Accumulated energy provided through photovoltaic systems
|
||||
channel-type.evcc.site-pv-power.label = PV Power
|
||||
channel-type.evcc.site-pv-power.description = Accumulated current power from photovoltaic systems
|
||||
channel-type.evcc.site-residual-power.label = Grid Residual Power
|
||||
channel-type.evcc.site-residual-power.description = Target operating point of the surplus regulation at the grid connection (grid meter)
|
||||
channel-type.evcc.site-site-title.label = Site Title
|
||||
channel-type.evcc.site-site-title.description = Name of the site as displayed in the UI
|
||||
channel-type.evcc.site-smart-cost-available.label = Smart Cost Available
|
||||
channel-type.evcc.site-smart-cost-available.description = Indicates whether smart costs are available or not
|
||||
channel-type.evcc.site-smart-cost-available.state.option.ON = Available
|
||||
channel-type.evcc.site-smart-cost-available.state.option.OFF = Not Available
|
||||
channel-type.evcc.site-smart-cost-type.label = Smart Cost Type
|
||||
channel-type.evcc.site-smart-cost-type.description = Indicates the smart cost type (price or co2)
|
||||
channel-type.evcc.site-smart-cost-type.state.option.priceforecast = Price Forecast
|
||||
channel-type.evcc.site-smart-cost-type.state.option.pricedynamic = Price Dynamic
|
||||
channel-type.evcc.site-smart-cost-type.state.option.co2 = CO2
|
||||
channel-type.evcc.site-smart-feed-in-priority-available.label = Smart Feed In Priority Available
|
||||
channel-type.evcc.site-smart-feed-in-priority-available.description = Indicates whether there is priority for smart feed in or not
|
||||
channel-type.evcc.site-smart-feed-in-priority-available.state.option.ON = Available
|
||||
channel-type.evcc.site-smart-feed-in-priority-available.state.option.OFF = Not Available
|
||||
channel-type.evcc.site-startup.label = Start Up
|
||||
channel-type.evcc.site-startup.description = Indicates whether restart is needed or not
|
||||
channel-type.evcc.site-startup.state.option.ON = True
|
||||
channel-type.evcc.site-startup.state.option.OFF = False
|
||||
channel-type.evcc.site-tariff-co2-home.label = CO2 Concentration Home
|
||||
channel-type.evcc.site-tariff-co2-home.description = Indicates the current carbon dioxide concentration per kWh for your home
|
||||
channel-type.evcc.site-tariff-co2-loadpoints.label = CO2 Concentration Loadpoints
|
||||
channel-type.evcc.site-tariff-co2-loadpoints.description = Indicates the current carbon dioxide concentration per kWh for your loadpoints
|
||||
channel-type.evcc.site-tariff-co2.label = CO2 Concentration
|
||||
channel-type.evcc.site-tariff-co2.description = Indicates the current carbon dioxide concentration per kWh
|
||||
channel-type.evcc.site-tariff-feed-in.label = Feed in price per kWh
|
||||
channel-type.evcc.site-tariff-feed-in.description = Indicates the current price per kWh for feed-in to the grid
|
||||
channel-type.evcc.site-tariff-grid.label = Grid Price
|
||||
channel-type.evcc.site-tariff-grid.description = Indicates the current price per kWh for consuming from the grid
|
||||
channel-type.evcc.site-tariff-price-home.label = Home Price
|
||||
channel-type.evcc.site-tariff-price-home.description = Indicates the current price per kWh for your home
|
||||
channel-type.evcc.site-tariff-price-loadpoints.label = Loadpoint price per kWh
|
||||
channel-type.evcc.site-tariff-price-loadpoints.description = Indicates the current price per kWh for loadpoints
|
||||
channel-type.evcc.site-tariff-solar.label = Solar Tariff
|
||||
channel-type.evcc.site-tariff-solar.description = Current solar power forecast
|
||||
channel-type.evcc.site-version.label = Version
|
||||
channel-type.evcc.site-version.description = Current evcc version
|
||||
channel-type.evcc.solar-percentage-type.label = Solar Percentage
|
||||
channel-type.evcc.vehicle-capacity.label = Vehicle Capacity
|
||||
channel-type.evcc.vehicle-capacity.description = Capacity of vehicle battery
|
||||
channel-type.evcc.vehicle-icon.label = Vehicle Icon
|
||||
channel-type.evcc.vehicle-icon.description = Used icon for this vehicle in the UI
|
||||
channel-type.evcc.vehicle-limit-soc.label = Vehicle Limit SoC
|
||||
channel-type.evcc.vehicle-limit-soc.description = State of charge to which the vehicle is charged
|
||||
channel-type.evcc.vehicle-max-current.label = Vehicle Max Current
|
||||
channel-type.evcc.vehicle-max-current.description = Maximum allowed current that can be provided to charge the vehicle
|
||||
channel-type.evcc.vehicle-min-current.label = Vehicle Min Current
|
||||
channel-type.evcc.vehicle-min-current.description = Minimum current that needs to provided to charge the vehicle
|
||||
channel-type.evcc.vehicle-min-soc.label = Vehicle Min SoC
|
||||
channel-type.evcc.vehicle-min-soc.description = Minimum state of charge a vehicle should have (fast charging until this limit)
|
||||
channel-type.evcc.vehicle-plan-precondition.label = Plan Precondition Duration
|
||||
channel-type.evcc.vehicle-plan-precondition.description = Configured duration for charging the vehicle before departure (preconditioning the battery)
|
||||
channel-type.evcc.vehicle-plan-soc.label = Planned SoC
|
||||
channel-type.evcc.vehicle-plan-soc.description = Planned state of charge to which the vehicle will be charged (can be greater than the Vehicle Limit SoC)
|
||||
channel-type.evcc.vehicle-plan-time.label = Plan Datetime
|
||||
channel-type.evcc.vehicle-plan-time.description = Planned date and time when the charging should be started
|
||||
channel-type.evcc.vehicle-title.label = Vehicle Title
|
||||
channel-type.evcc.vehicle-title.description = Name of the vehicle as displayed in the UI
|
||||
|
||||
# channel group types
|
||||
# thing types config
|
||||
|
||||
channel-group-type.evcc.loadpoint.label = Loadpoint
|
||||
thing-type.config.evcc.server.schema.label = Protocol schema
|
||||
thing-type.config.evcc.server.schema.description = The protocol schema that should be used to connect to your instance
|
||||
thing-type.config.evcc.server.schema.option.http = HTTP
|
||||
thing-type.config.evcc.server.schema.option.https = HTTPS
|
||||
|
||||
# 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
|
||||
|
||||
offline.configuration-error.no-host = No host configured
|
||||
offline.communication-error.request-failed = Request failed
|
||||
channel-type.evcc.site-battery-grid-charge-limit.label = Grid Charging Limit
|
||||
channel-type.evcc.site-battery-grid-charge-limit.description = Below this smart cost limit the charging from grid will start (currency or co2)
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="evcc"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<thing-type id="battery" listed="false">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="server"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Battery</label>
|
||||
<description>A battery configured in your evcc instance</description>
|
||||
</thing-type>
|
||||
<channel-type id="battery-capacity">
|
||||
<item-type unitHint="kWh">Number:Energy</item-type>
|
||||
<label>Battery Capacity</label>
|
||||
<description>Capacity of this battery</description>
|
||||
<category>Energy</category>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="battery-controllable">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Battery Controllable</label>
|
||||
<description>Indicates whether this battery is controllable or not</description>
|
||||
<category>Switch</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Mode</tag>
|
||||
</tags>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">Controllable</option>
|
||||
<option value="OFF">Not Controllable</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="battery-power">
|
||||
<item-type unitHint="W">Number:Power</item-type>
|
||||
<label>Battery Power</label>
|
||||
<description>Current power from this battery</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Power</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="battery-soc">
|
||||
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||
<label>Battery SoC</label>
|
||||
<description>Current state of charge of this battery</description>
|
||||
<category>BatteryLevel</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="battery-title">
|
||||
<item-type>String</item-type>
|
||||
<label>Title</label>
|
||||
<description>Battery name displayed in the UI</description>
|
||||
<category>Settings</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Info</tag>
|
||||
</tags>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="evcc"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<thing-type id="heating" listed="false">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="server"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Heating - Loadpoint</label>
|
||||
<description>A heating loadpoint configured in your evcc instance</description>
|
||||
<representation-property>index</representation-property>
|
||||
</thing-type>
|
||||
<!-- This thing is currently using the same channels as a loadpoint does -->
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,783 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="evcc"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<thing-type id="loadpoint" listed="false">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="server"/>
|
||||
</supported-bridge-type-refs>
|
||||
<label>Loadpoint</label>
|
||||
<description>A loadpoint configured in your evcc instance</description>
|
||||
<representation-property>index</representation-property>
|
||||
</thing-type>
|
||||
<channel-type id="loadpoint-battery-boost">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Battery Boost</label>
|
||||
<description>Controls and indicates whether battery boost is active or not</description>
|
||||
<category>Switch</category>
|
||||
<tags>
|
||||
<tag>Switch</tag>
|
||||
<tag>Enabled</tag>
|
||||
</tags>
|
||||
<state>
|
||||
<options>
|
||||
<option value="ON">Activated</option>
|
||||
<option value="OFF">Deactivated</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-charge-duration">
|
||||
<item-type unitHint="h">Number:Time</item-type>
|
||||
<label>Charging Duration</label>
|
||||
<description>Time passed since start of the charging</description>
|
||||
<category>Time</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Duration</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-charge-power">
|
||||
<item-type unitHint="W">Number:Power</item-type>
|
||||
<label>Charging Power</label>
|
||||
<description>Current power of charging</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Power</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-charge-total-import">
|
||||
<item-type unitHint="kWh">Number:Energy</item-type>
|
||||
<label>Charge Total Import</label>
|
||||
<description>Total imported energy</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-charge-remaining-duration">
|
||||
<item-type unitHint="h">Number:Time</item-type>
|
||||
<label>Charging Remaining Duration</label>
|
||||
<description>Remaining duration until limit SoC is reached</description>
|
||||
<category>Time</category>
|
||||
<tags>
|
||||
<tag>Forecast</tag>
|
||||
<tag>Duration</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-charge-remaining-energy">
|
||||
<item-type unitHint="Wh">Number:Energy</item-type>
|
||||
<label>Charging Remaining Energy</label>
|
||||
<description>Remaining energy until limit SoC is reached</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Calculation</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-charged-energy">
|
||||
<item-type unitHint="kWh">Number:Energy</item-type>
|
||||
<label>Charged Energy</label>
|
||||
<description>Energy charged since plugged-in</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-charger-icon">
|
||||
<item-type>String</item-type>
|
||||
<label>Charger Icon</label>
|
||||
<description>Icon used in the UI for this charger</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-charger-feature-heating">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Heating</label>
|
||||
<description>Indicates whether the loadpoint is configured for a heating device</description>
|
||||
<category>Switch</category>
|
||||
<tags>
|
||||
<tag>Switch</tag>
|
||||
<tag>Enabled</tag>
|
||||
</tags>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">True</option>
|
||||
<option value="OFF">False</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-charger-feature-integrated-device">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Integrated Device</label>
|
||||
<description>Loadpoint has an integrated device and runs without a vehicle (e.g. heatpump, e-bike)</description>
|
||||
<category>Switch</category>
|
||||
<tags>
|
||||
<tag>Switch</tag>
|
||||
<tag>Enabled</tag>
|
||||
</tags>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">True</option>
|
||||
<option value="OFF">False</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-charger-phases1p3p">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Phase Switching</label>
|
||||
<description>Indicates that the loadpoint can switch between 1 and 3 phases</description>
|
||||
<category>Switch</category>
|
||||
<tags>
|
||||
<tag>Switch</tag>
|
||||
<tag>Enabled</tag>
|
||||
</tags>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">True</option>
|
||||
<option value="OFF">False</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-charger-single-phase">
|
||||
<item-type>Switch</item-type>
|
||||
<label>1 Phase Charging</label>
|
||||
<description>Indicates that the charger can only charge with 1 phase</description>
|
||||
<category>Switch</category>
|
||||
<tags>
|
||||
<tag>Switch</tag>
|
||||
<tag>Enabled</tag>
|
||||
</tags>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">True</option>
|
||||
<option value="OFF">False</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-charger-status-reason">
|
||||
<item-type>String</item-type>
|
||||
<label>Charger Status Reason</label>
|
||||
<description>Hint why the charging has not started yet</description>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Info</tag>
|
||||
</tags>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="unknown">Unknown</option>
|
||||
<option value="waitingforauthorization">Waiting for authorization</option>
|
||||
<option value="disconnectrequired">Disconnect required</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-charging">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Charging State</label>
|
||||
<description>Indicates whether the loadpoint is charging or not</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Mode</tag>
|
||||
</tags>
|
||||
<state pattern="%f %unit%" readOnly="true">
|
||||
<options>
|
||||
<option value="ON">Charging</option>
|
||||
<option value="OFF">Not charging</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-connected">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Vehicle Connected</label>
|
||||
<description>Indicates whether a vehicle is connected or not</description>
|
||||
<category>Switch</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Enabled</tag>
|
||||
</tags>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">Connected</option>
|
||||
<option value="OFF">Not connected</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-connected-duration">
|
||||
<item-type unitHint="h">Number:Time</item-type>
|
||||
<label>Vehicle Conn. Duration</label>
|
||||
<description>Duration the vehicle is connected to the loadpoint</description>
|
||||
<category>Time</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Duration</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-disable-delay">
|
||||
<item-type unitHint="s">Number:Time</item-type>
|
||||
<label>Disable Delay</label>
|
||||
<description>Delay in PV mode before stopping the charging if not enough power is available</description>
|
||||
<category>Time</category>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Duration</tag>
|
||||
</tags>
|
||||
<state pattern="%.0f %unit%"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-disable-threshold">
|
||||
<item-type unitHint="W">Number:Power</item-type>
|
||||
<label>Disable Threshold</label>
|
||||
<description>Threshold for the disable delay (negative values means feed in)</description>
|
||||
<category>Energy</category>
|
||||
<state pattern="%.0f %unit%"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-effective-limit-soc">
|
||||
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||
<label>Active Charging Limit</label>
|
||||
<description>Active state of charge the vehicle will be charged to</description>
|
||||
<category>BatteryLevel</category>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-effective-max-current">
|
||||
<item-type unitHint="A">Number:ElectricCurrent</item-type>
|
||||
<label>Active Maximum Current</label>
|
||||
<description>Effective maximum amperage per connected phase that can be provided to the vehicle</description>
|
||||
<category>Energy</category>
|
||||
<state min="0" step="1" pattern="%.0f %unit%"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-effective-min-current">
|
||||
<item-type unitHint="A">Number:ElectricCurrent</item-type>
|
||||
<label>Active Minimum Current</label>
|
||||
<description>Effective minimum amperage per connected phase that will be provided to the vehicle</description>
|
||||
<category>Energy</category>
|
||||
<state min="0" step="1" pattern="%.0f %unit%"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-effective-plan-id">
|
||||
<item-type>Number</item-type>
|
||||
<label>Active Plan ID</label>
|
||||
<description>ID of the currently active charging plan</description>
|
||||
<state min="0" step="1" max="10" pattern="%.0f" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-effective-plan-soc">
|
||||
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||
<label>Active Plan SoC</label>
|
||||
<description>State of charge limit for the currently active charging plan</description>
|
||||
<category>BatteryLevel</category>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-effective-plan-time">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>Active Plan Time</label>
|
||||
<description>Indicating when the next charge slot starts</description>
|
||||
<tags>
|
||||
<tag>Calculation</tag>
|
||||
<tag>Timestamp</tag>
|
||||
</tags>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-plan-projected-end">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>Plan Projected End</label>
|
||||
<description>Projected end of charging</description>
|
||||
<tags>
|
||||
<tag>Calculation</tag>
|
||||
<tag>Timestamp</tag>
|
||||
</tags>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-plan-projected-start">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>Plan Projected Start</label>
|
||||
<description>Projected start of charging</description>
|
||||
<tags>
|
||||
<tag>Calculation</tag>
|
||||
<tag>Timestamp</tag>
|
||||
</tags>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-effective-priority">
|
||||
<item-type>Number</item-type>
|
||||
<label>Active Priority</label>
|
||||
<description>Effective priority of this loadpoint</description>
|
||||
<state pattern="%d" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-enable-delay">
|
||||
<item-type unitHint="s">Number:Time</item-type>
|
||||
<label>Enable Delay</label>
|
||||
<description>Delay in PV mode before starting the charging when enough power is available</description>
|
||||
<category>Time</category>
|
||||
<state pattern="%.0f %unit%"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-enable-threshold">
|
||||
<item-type unitHint="W">Number:Power</item-type>
|
||||
<label>Enable Threshold</label>
|
||||
<description>Threshold for the enable delay</description>
|
||||
<category>Energy</category>
|
||||
<state pattern="%.0f %unit%"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-enabled">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Loadpoint Enabled</label>
|
||||
<description>Indicates whether the charger is locked or released</description>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">Released</option>
|
||||
<option value="OFF">Locked</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-limit-energy">
|
||||
<item-type unitHint="kWh">Number:Energy</item-type>
|
||||
<label>Energy Limit</label>
|
||||
<description>Energy limit when charging the vehicle</description>
|
||||
<category>BatteryLevel</category>
|
||||
<tags>
|
||||
<tag>Control</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state min="0" pattern="%.0f %unit%"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-limit-soc">
|
||||
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||
<label>SoC Limit</label>
|
||||
<description>State of charge limit when charging the vehicle</description>
|
||||
<category>BatteryLevel</category>
|
||||
<tags>
|
||||
<tag>Control</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-max-current">
|
||||
<item-type unitHint="A">Number:ElectricCurrent</item-type>
|
||||
<label>Maximum Current</label>
|
||||
<description>Maximum amperage per connected phase that can be provided to the vehicle</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Current</tag>
|
||||
</tags>
|
||||
<state min="0" step="1" pattern="%.0f %unit%"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-min-current">
|
||||
<item-type unitHint="A">Number:ElectricCurrent</item-type>
|
||||
<label>Minimum Current</label>
|
||||
<description>Minimum amperage per connected phase that will be provided to the vehicle</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Current</tag>
|
||||
</tags>
|
||||
<state min="0" step="1" pattern="%.0f %unit%"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-mode">
|
||||
<item-type>String</item-type>
|
||||
<label>Mode</label>
|
||||
<description>Charging Mode</description>
|
||||
<category>Settings</category>
|
||||
<tags>
|
||||
<tag>Control</tag>
|
||||
<tag>Mode</tag>
|
||||
</tags>
|
||||
<state>
|
||||
<options>
|
||||
<option value="off">Off</option>
|
||||
<option value="now">Fast</option>
|
||||
<option value="minpv">Min + PV</option>
|
||||
<option value="pv">Only PV</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-offered-current">
|
||||
<item-type unitHint="A">Number:ElectricCurrent</item-type>
|
||||
<label>Offered Current</label>
|
||||
<description>Current amperage per connected phase offered to the vehicle</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Current</tag>
|
||||
</tags>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-phase-action">
|
||||
<item-type>String</item-type>
|
||||
<label>Phase Scaling</label>
|
||||
<description>Indicates phase switching from 1 to 3 or 3 to 1 phases</description>
|
||||
<state>
|
||||
<options>
|
||||
<option value="scale1p">Switching to 1 phase</option>
|
||||
<option value="scale3p">Switching to 3 phases</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-phase-remaining">
|
||||
<item-type unitHint="s">Number:Time</item-type>
|
||||
<label>Phase Remaining Timer</label>
|
||||
<description>Time until phase switching will occure</description>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Duration</tag>
|
||||
</tags>
|
||||
<state pattern="%d" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-phases-active">
|
||||
<item-type>Number</item-type>
|
||||
<label>Active Phases</label>
|
||||
<description>Current number of active phases</description>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Info</tag>
|
||||
</tags>
|
||||
<state pattern="%d" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-phases-configured">
|
||||
<item-type>Number</item-type>
|
||||
<label>Configured Phases</label>
|
||||
<description>Number of configured phases</description>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Info</tag>
|
||||
</tags>
|
||||
<state pattern="%d" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-plan-active">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Plan Activated</label>
|
||||
<description>Indicates whether a plan is active or not</description>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Enabled</tag>
|
||||
</tags>
|
||||
<state>
|
||||
<options>
|
||||
<option value="ON">Activated</option>
|
||||
<option value="OFF">Deactivated</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-plan-energy">
|
||||
<item-type unitHint="kWh">Number:Energy</item-type>
|
||||
<label>Plan Energy</label>
|
||||
<description>Charge plan energy goal</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state pattern="%.2f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-plan-overrun">
|
||||
<item-type unitHint="s">Number:Time</item-type>
|
||||
<label>Plan Overrun</label>
|
||||
<description>Indicates that the charge plan goal is not reachable in time</description>
|
||||
<tags>
|
||||
<tag>Forecast</tag>
|
||||
<tag>Duration</tag>
|
||||
</tags>
|
||||
<state pattern="%d %unit%"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-plan-precondition">
|
||||
<item-type unitHint="s">Number:Time</item-type>
|
||||
<label>Plan Precondition</label>
|
||||
<description>Duration for preconditioning the battery</description>
|
||||
<category>Time</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Duration</tag>
|
||||
</tags>
|
||||
<state pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-priority">
|
||||
<item-type>Number</item-type>
|
||||
<label>Priority</label>
|
||||
<description>Priority of this loadpoint</description>
|
||||
<tags>
|
||||
<tag>Info</tag>
|
||||
</tags>
|
||||
<state pattern="%d" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-pv-action">
|
||||
<item-type>String</item-type>
|
||||
<label>PV Action</label>
|
||||
<description>Indicates whether pv charging gets enabled or disabled</description>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Info</tag>
|
||||
</tags>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="inactive">Inactive</option>
|
||||
<option value="pvEnable">Enable PV Timer</option>
|
||||
<option value="pvDisable">Disable PV Timer</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-pv-remaining">
|
||||
<item-type unitHint="s">Number:Time</item-type>
|
||||
<label>Pv Remaining</label>
|
||||
<description>Timer for enabling or disabling pv charging</description>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-session-co2-per-k-wh">
|
||||
<item-type unitHint="g/kWh">Number:EmissionIntensity</item-type>
|
||||
<label>Session CO2 Per kWh</label>
|
||||
<description>Current session emitted carbon dioxide per kWh</description>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Info</tag>
|
||||
</tags>
|
||||
<state pattern="%.3f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-session-energy">
|
||||
<item-type unitHint="kWh">Number:Energy</item-type>
|
||||
<label>Session Energy</label>
|
||||
<description>Charged energy in the current charging session</description>
|
||||
<tags>
|
||||
<tag>Forecast</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state pattern="%.2f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-session-solar-percentage">
|
||||
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||
<label>Session Solar Percentage</label>
|
||||
<description>Percentage of solar energy for the current charging session</description>
|
||||
<tags>
|
||||
<tag>Forecast</tag>
|
||||
<tag>Info</tag>
|
||||
</tags>
|
||||
<state pattern="%.2f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-session-price">
|
||||
<item-type>Number:Currency</item-type>
|
||||
<label>Session Price</label>
|
||||
<description>Costs of the current charging session</description>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Info</tag>
|
||||
</tags>
|
||||
<state pattern="%.2f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-session-price-per-k-wh">
|
||||
<item-type>Number:EnergyPrice</item-type>
|
||||
<label>Session Price Per kWh</label>
|
||||
<description>Current session charging price per kWh</description>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Info</tag>
|
||||
</tags>
|
||||
<state pattern="%.3f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-smart-cost-active">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Smart Cost Active</label>
|
||||
<description>Indicates whether smart charging is active or not</description>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Enabled</tag>
|
||||
</tags>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">Active</option>
|
||||
<option value="OFF">Inactive</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-smart-cost-limit-co2">
|
||||
<item-type>Number:EmissionIntensity</item-type>
|
||||
<label>Smart Cost Limit</label>
|
||||
<description>Below this limit the smart charging will start</description>
|
||||
<state pattern="%d" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-smart-cost-limit-price">
|
||||
<item-type>Number:EnergyPrice</item-type>
|
||||
<label>Smart Cost Limit</label>
|
||||
<description>Below this limit the smart charging will start</description>
|
||||
<state pattern="%.3f" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-smart-cost-next-start">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>Smart Cost Next Start</label>
|
||||
<description>Startpoint for the next smart charging</description>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Timestamp</tag>
|
||||
</tags>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-smart-feed-in-priority-active">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Smart Feed In Priority Active</label>
|
||||
<description>Indicates that smart feed in has priority</description>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Enabled</tag>
|
||||
</tags>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-title">
|
||||
<item-type>String</item-type>
|
||||
<label>Title</label>
|
||||
<description>Name of the loadpoint as displayed in the UI</description>
|
||||
<category>Text</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-vehicle-climater-active">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Vehicle Climate Active</label>
|
||||
<description>Indicates whether the climate control is active or not for the connected vehicle</description>
|
||||
<tags>
|
||||
<tag>Airconditioning</tag>
|
||||
<tag>Status</tag>
|
||||
</tags>
|
||||
<state>
|
||||
<options>
|
||||
<option value="ON">Active</option>
|
||||
<option value="OFF">Inactive</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-vehicle-detection-active">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Vehicle Detection Active</label>
|
||||
<description>Indicates whether the vehicle detection is active or not</description>
|
||||
<tags>
|
||||
<tag>Switch</tag>
|
||||
<tag>Enabled</tag>
|
||||
</tags>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">Active</option>
|
||||
<option value="OFF">Inactive</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-vehicle-identity">
|
||||
<item-type>String</item-type>
|
||||
<label>Vehicle Identity</label>
|
||||
<description>Transferred vehicle identity</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-vehicle-limit-soc">
|
||||
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||
<label>Vehicle API SoC Limit</label>
|
||||
<description>Current vehicle API state of charge limit</description>
|
||||
<category>BatteryLevel</category>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-vehicle-name">
|
||||
<item-type>String</item-type>
|
||||
<label>Vehicle Name</label>
|
||||
<description>The unique identifier of the vehicle used in the evcc configuration (containing no whitespaces nor
|
||||
special
|
||||
characters)</description>
|
||||
<category>Settings</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Info</tag>
|
||||
</tags>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-vehicle-odometer">
|
||||
<item-type unitHint="km">Number:Length</item-type>
|
||||
<label>Vehicle Odometer</label>
|
||||
<description>Total distance travelled by the vehicle</description>
|
||||
<category>MoveControl</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Info</tag>
|
||||
</tags>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-vehicle-range">
|
||||
<item-type unitHint="km">Number:Length</item-type>
|
||||
<label>Vehicle Range</label>
|
||||
<description>Current range of the vehicle</description>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-vehicle-soc">
|
||||
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||
<label>Vehicle API SoC</label>
|
||||
<description>Current state of charge of the vehicle</description>
|
||||
<category>BatteryLevel</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-vehicle-title">
|
||||
<item-type>String</item-type>
|
||||
<label>Vehicle Title</label>
|
||||
<description>The name of the vehicle as displayed in the UI</description>
|
||||
<category>Settings</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-vehicle-welcome-active">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Vehicle Welcome Active</label>
|
||||
<description>Indicates whether the charger performs an initial charge or not when the vehicle gets connected</description>
|
||||
<tags>
|
||||
<tag>Switch</tag>
|
||||
<tag>Enabled</tag>
|
||||
</tags>
|
||||
<state>
|
||||
<options>
|
||||
<option value="ON">Active</option>
|
||||
<option value="OFF">Inactive</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<!-- Heating relevant channels -->
|
||||
<channel-type id="loadpoint-effective-limit-temperature">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>Effective Charging Limit Temperature</label>
|
||||
<description>Effective Temperature until which the heating device will be charged</description>
|
||||
<category>Temperature</category>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Temperature</tag>
|
||||
</tags>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-limit-temperature">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>Temperature Limit</label>
|
||||
<description>Temperature to which the heating device is charged</description>
|
||||
<category>Temperature</category>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Temperature</tag>
|
||||
</tags>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%"/>
|
||||
</channel-type>
|
||||
<channel-type id="loadpoint-vehicle-temperature">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>Temperature</label>
|
||||
<description>Current temperature of the heating device</description>
|
||||
<category>Temperature</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Temperature</tag>
|
||||
</tags>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="evcc"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<thing-type id="pv" listed="false">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="server"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Photovoltaic</label>
|
||||
<description>A photovoltaic system configured in your evcc instance</description>
|
||||
</thing-type>
|
||||
<!-- Already declared in site.xml maybe evcc is going to change it in the future -->
|
||||
<channel-type id="pv-power">
|
||||
<item-type unitHint="W">Number:Power</item-type>
|
||||
<label>PV Power</label>
|
||||
<description>Current power of this photovoltaic system in Watt</description>
|
||||
<category>Power</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Power</tag>
|
||||
</tags>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="pv-title">
|
||||
<item-type>String</item-type>
|
||||
<label>Title</label>
|
||||
<description>Name of the photovoltaic system as displayed in the UI</description>
|
||||
<category>Text</category>
|
||||
<state readOnly="true"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="evcc"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<bridge-type id="server">
|
||||
<label>Server</label>
|
||||
<description>Connection to evcc instance</description>
|
||||
<config-description>
|
||||
<parameter name="scheme" type="text">
|
||||
<label>Protocol Scheme</label>
|
||||
<description>The protocol scheme that should be used to connect to your instance</description>
|
||||
<default>http</default>
|
||||
<options>
|
||||
<option value="http">HTTP</option>
|
||||
<option value="https">HTTPS</option>
|
||||
</options>
|
||||
</parameter>
|
||||
<parameter name="host" type="text" required="true">
|
||||
<label>Hostname or IP</label>
|
||||
<description>Address of your evcc instance, for example evcc.local or 192.168.1.2</description>
|
||||
</parameter>
|
||||
<parameter name="port" type="integer" required="false">
|
||||
<advanced>true</advanced>
|
||||
<label>Port</label>
|
||||
<default>7070</default>
|
||||
<description>HTTP-Port of your instance (Default: 7070)</description>
|
||||
</parameter>
|
||||
<parameter name="pollInterval" type="integer" required="false">
|
||||
<advanced>true</advanced>
|
||||
<label>Polling Interval</label>
|
||||
<default>30</default>
|
||||
<description>How often should the state be polled? (in seconds, default is 30s)</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</bridge-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,414 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="evcc"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<thing-type id="site" listed="false">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="server"/>
|
||||
</supported-bridge-type-refs>
|
||||
<label>Site</label>
|
||||
<description>The site configured in your evcc instance</description>
|
||||
</thing-type>
|
||||
<channel-type id="site-available-version">
|
||||
<item-type>String</item-type>
|
||||
<label>Available Version</label>
|
||||
<description>Available evcc update version</description>
|
||||
<category>Text</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-battery-capacity">
|
||||
<item-type unitHint="kWh">Number:Energy</item-type>
|
||||
<label>Site Battery Capacity</label>
|
||||
<description>Accumulated battery capacity for this site</description>
|
||||
<category>Energy</category>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-battery-discharge-control">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Battery Discharge Control</label>
|
||||
<description>Enable or disable battery discharge control</description>
|
||||
<category>Switch</category>
|
||||
<tags>
|
||||
<tag>Switch</tag>
|
||||
<tag>Mode</tag>
|
||||
</tags>
|
||||
<state>
|
||||
<options>
|
||||
<option value="ON">Enabled</option>
|
||||
<option value="OFF">Disabled</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="site-battery-energy">
|
||||
<item-type unitHint="Wh">Number:Energy</item-type>
|
||||
<label>Battery Energy</label>
|
||||
<description>Energy provided from the battery(ies)</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Energy</tag>
|
||||
<tag>Measurement</tag>
|
||||
</tags>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-battery-grid-charge-active">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Grid Charging Active</label>
|
||||
<description>Indicates whether the battery gets charged from the grid or not</description>
|
||||
<category>Switch</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Enabled</tag>
|
||||
</tags>
|
||||
<state pattern="%.0f" readOnly="true">
|
||||
<options>
|
||||
<option value="ON">Active</option>
|
||||
<option value="OFF">Inactive</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="site-battery-grid-charge-limit-co2">
|
||||
<item-type>Number:EmissionIntensity</item-type>
|
||||
<label>Grid Charging Limit</label>
|
||||
<description>Below this smart cost limit the charging from grid will start (currency or co2)</description>
|
||||
<tags>
|
||||
<tag>Control</tag>
|
||||
</tags>
|
||||
<state pattern="%.0f" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-battery-grid-charge-limit-price">
|
||||
<item-type>Number:EnergyPrice</item-type>
|
||||
<label>Grid Charging Limit</label>
|
||||
<description>Below this smart cost limit the charging from grid will start (currency or co2)</description>
|
||||
<tags>
|
||||
<tag>Control</tag>
|
||||
</tags>
|
||||
<state pattern="%.3f" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-battery-mode">
|
||||
<item-type>String</item-type>
|
||||
<label>Battery Mode</label>
|
||||
<description>Current battery mode for the site</description>
|
||||
<category>Battery</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="unknow">Unknown</option>
|
||||
<option value="normal">Normal</option>
|
||||
<option value="hold">Locked</option>
|
||||
<option value="charge">Charging</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="site-battery-mode-external">
|
||||
<item-type>String</item-type>
|
||||
<label>Battery Mode</label>
|
||||
<description>Current battery mode cached from external</description>
|
||||
<category>Battery</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="unknow">Unknown</option>
|
||||
<option value="normal">Normal</option>
|
||||
<option value="hold">Locked</option>
|
||||
<option value="charge">Charging</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="site-battery-power">
|
||||
<item-type unitHint="W">Number:Power</item-type>
|
||||
<label>Battery Power</label>
|
||||
<description>Accumulated power distributed by the battery(ies)</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Power</tag>
|
||||
<tag>Measurement</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-battery-soc">
|
||||
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||
<label>Battery SoC</label>
|
||||
<description>Current state of charge of battery(ies)</description>
|
||||
<category>BatteryLevel</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-buffer-soc">
|
||||
<item-type unitHint="%">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%"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-buffer-start-soc">
|
||||
<item-type unitHint="%">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%"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-currency">
|
||||
<item-type>String</item-type>
|
||||
<label>Currency</label>
|
||||
<description>Current configured currency</description>
|
||||
<category>Text</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-demo-mode">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Demo Mode</label>
|
||||
<description>Indicates whether demo mode is active or not</description>
|
||||
<category>Settings</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">Active</option>
|
||||
<option value="OFF">Inactive</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="site-eebus">
|
||||
<item-type>Switch</item-type>
|
||||
<label>EEBUS</label>
|
||||
<description>Indicates whether EEBUS is configured or not</description>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">Configured</option>
|
||||
<option value="OFF">Not configured</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="site-green-share-home">
|
||||
<item-type>Number</item-type>
|
||||
<label>Green Share Home</label>
|
||||
<description>Indicates whether green power is available for home</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-green-share-loadpoints">
|
||||
<item-type>Number</item-type>
|
||||
<label>Green Share Loadpoints</label>
|
||||
<description>Indicates whether green power is available for loadpoints</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-grid-power">
|
||||
<item-type unitHint="W">Number:Power</item-type>
|
||||
<label>Grid Power</label>
|
||||
<description>Current power from grid (negative means feed-in)</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Power</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-home-power">
|
||||
<item-type unitHint="W">Number:Power</item-type>
|
||||
<label>Home Power</label>
|
||||
<description>Current power consumption by home</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Power</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-messaging">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Site Messaging</label>
|
||||
<description>Indicates whether messaging has been configured or not</description>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">Configured</option>
|
||||
<option value="OFF">Not configured</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="site-priority-soc">
|
||||
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||
<label>Battery Priority SoC</label>
|
||||
<description>State of charge for which the battery has priority over charging the vehicle when charging mode is "pv"
|
||||
</description>
|
||||
<category>BatteryLevel</category>
|
||||
<state min="0" step="0.1" max="100" pattern="%.0f %unit%"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-interval">
|
||||
<item-type>Number</item-type>
|
||||
<label>Interval</label>
|
||||
<description>Refresh interval configured for evcc</description>
|
||||
<category>Settings</category>
|
||||
<state pattern="%d" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-pv-energy">
|
||||
<item-type unitHint="Wh">Number:Energy</item-type>
|
||||
<label>PV Energy</label>
|
||||
<description>Accumulated energy provided through photovoltaic systems</description>
|
||||
<category>Energy</category>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-pv-power">
|
||||
<item-type unitHint="W">Number:Power</item-type>
|
||||
<label>PV Power</label>
|
||||
<description>Accumulated current power from photovoltaic systems</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Power</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-residual-power">
|
||||
<item-type unitHint="W">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>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Power</tag>
|
||||
</tags>
|
||||
<state min="0" step="1" pattern="%.0f %unit%"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-smart-cost-available">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Smart Cost Available</label>
|
||||
<description>Indicates whether smart costs are available or not</description>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Enabled</tag>
|
||||
</tags>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">Available</option>
|
||||
<option value="OFF">Not Available</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="site-smart-cost-type">
|
||||
<item-type>String</item-type>
|
||||
<label>Smart Cost Type</label>
|
||||
<description>Indicates the smart cost type (price or co2)</description>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="priceforecast">Price Forecast</option>
|
||||
<option value="pricedynamic">Price Dynamic</option>
|
||||
<option value="co2">CO2</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="site-smart-feed-in-priority-available">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Smart Feed In Priority Available</label>
|
||||
<description>Indicates whether there is priority for smart feed in or not</description>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Enabled</tag>
|
||||
</tags>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">Available</option>
|
||||
<option value="OFF">Not Available</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="site-startup">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Start Up</label>
|
||||
<description>Indicates whether restart is needed or not</description>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Enabled</tag>
|
||||
</tags>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">True</option>
|
||||
<option value="OFF">False</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="site-tariff-co2">
|
||||
<item-type unitHint="g/kWh">Number:EmissionIntensity</item-type>
|
||||
<label>CO2 Concentration</label>
|
||||
<description>Indicates the current carbon dioxide concentration per kWh</description>
|
||||
<category>co2</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>CO2</tag>
|
||||
</tags>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-tariff-co2-home">
|
||||
<item-type unitHint="g/kWh">Number:EmissionIntensity</item-type>
|
||||
<label>CO2 Concentration Home</label>
|
||||
<description>Indicates the current carbon dioxide concentration per kWh for your home</description>
|
||||
<category>co2</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>CO2</tag>
|
||||
</tags>
|
||||
<state pattern="%.2f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-tariff-co2-loadpoints">
|
||||
<item-type unitHint="g/kWh">Number:EmissionIntensity</item-type>
|
||||
<label>CO2 Concentration Loadpoints</label>
|
||||
<description>Indicates the current carbon dioxide concentration per kWh for your loadpoints</description>
|
||||
<category>co2</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>CO2</tag>
|
||||
</tags>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-tariff-feed-in">
|
||||
<item-type>Number:EnergyPrice</item-type>
|
||||
<label>Feed in price per kWh</label>
|
||||
<description>Indicates the current price per kWh for feed-in to the grid</description>
|
||||
<state pattern="%.2f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-tariff-grid">
|
||||
<item-type>Number:EnergyPrice</item-type>
|
||||
<label>Grid Price</label>
|
||||
<description>Indicates the current price per kWh for consuming from the grid</description>
|
||||
<state pattern="%.2f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-tariff-price-home">
|
||||
<item-type>Number:EnergyPrice</item-type>
|
||||
<label>Home Price</label>
|
||||
<description>Indicates the current price per kWh for your home</description>
|
||||
<state pattern="%.2f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-tariff-price-loadpoints">
|
||||
<item-type>Number:EnergyPrice</item-type>
|
||||
<label>Loadpoint price per kWh</label>
|
||||
<description>Indicates the current price per kWh for loadpoints</description>
|
||||
<state pattern="%.2f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-tariff-solar">
|
||||
<item-type unitHint="W">Number:Power</item-type>
|
||||
<label>Solar Tariff</label>
|
||||
<description>Current solar power forecast</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Forecast</tag>
|
||||
<tag>Power</tag>
|
||||
</tags>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-site-title">
|
||||
<item-type>String</item-type>
|
||||
<label>Site Title</label>
|
||||
<description>Name of the site as displayed in the UI</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="site-version">
|
||||
<item-type>String</item-type>
|
||||
<label>Version</label>
|
||||
<description>Current evcc version</description>
|
||||
<category>Text</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="evcc"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<thing-type id="statistics" listed="false">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="server"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Statistics</label>
|
||||
<description>Statistics about your evcc instance</description>
|
||||
<channel-groups>
|
||||
<channel-group id="30d" typeId="statistics-group">
|
||||
<label>Last 30 Days</label>
|
||||
<description>Statistics from the last 30 days</description>
|
||||
</channel-group>
|
||||
<channel-group id="365d" typeId="statistics-group">
|
||||
<label>Last 365 Days</label>
|
||||
<description>Statistics from the last 365days</description>
|
||||
</channel-group>
|
||||
<channel-group id="this-year" typeId="statistics-group">
|
||||
<label>Last Year</label>
|
||||
<description>Statistics from the last year</description>
|
||||
</channel-group>
|
||||
<channel-group id="total" typeId="statistics-group">
|
||||
<label>Total</label>
|
||||
<description>Total statistics</description>
|
||||
</channel-group>
|
||||
</channel-groups>
|
||||
</thing-type>
|
||||
|
||||
<channel-group-type id="statistics-group">
|
||||
<label>Statistics Group</label>
|
||||
<channels>
|
||||
<channel id="avg-co2" typeId="avg-co2-type"/>
|
||||
<channel id="avg-price" typeId="avg-price-type"/>
|
||||
<channel id="charged-energy" typeId="charged-energy-type"/>
|
||||
<channel id="solar-percentage" typeId="solar-percentage-type"/>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-type id="avg-co2-type">
|
||||
<item-type unitHint="g/kWh">Number:EmissionIntensity</item-type>
|
||||
<label>Average C02</label>
|
||||
<tags>
|
||||
<tag>Calculation</tag>
|
||||
<tag>Info</tag>
|
||||
</tags>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="avg-price-type">
|
||||
<item-type>Number:EnergyPrice</item-type>
|
||||
<label>Average Price</label>
|
||||
<tags>
|
||||
<tag>Calculation</tag>
|
||||
<tag>Info</tag>
|
||||
</tags>
|
||||
<state pattern="%.2f %unit%"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="charged-energy-type">
|
||||
<item-type unitHint="kWh">Number:Energy</item-type>
|
||||
<label>Charged Energy</label>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="solar-percentage-type">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Solar Percentage</label>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state pattern="%.2f %unit%"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -1,751 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="evcc"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="device">
|
||||
|
||||
<label>evcc installation</label>
|
||||
<description>A running evcc installation</description>
|
||||
<semantic-equipment-tag>EVSE</semantic-equipment-tag>
|
||||
|
||||
<channel-groups>
|
||||
<channel-group id="general" typeId="general"/>
|
||||
<channel-group id="loadpoint0" typeId="loadpoint0"/>
|
||||
<channel-group id="loadpoint1" typeId="loadpoint1"/>
|
||||
<channel-group id="loadpoint2" typeId="loadpoint2"/>
|
||||
<channel-group id="loadpoint3" typeId="loadpoint3"/>
|
||||
<channel-group id="loadpoint4" typeId="loadpoint4"/>
|
||||
<channel-group id="loadpoint5" typeId="loadpoint5"/>
|
||||
<channel-group id="loadpoint6" typeId="loadpoint6"/>
|
||||
<channel-group id="loadpoint7" typeId="loadpoint7"/>
|
||||
<channel-group id="loadpoint8" typeId="loadpoint8"/>
|
||||
<channel-group id="loadpoint9" typeId="loadpoint9"/>
|
||||
<channel-group id="loadpoint0current" typeId="loadpoint0current"/>
|
||||
<channel-group id="loadpoint1current" typeId="loadpoint1current"/>
|
||||
<channel-group id="loadpoint2current" typeId="loadpoint2current"/>
|
||||
<channel-group id="loadpoint3current" typeId="loadpoint3current"/>
|
||||
<channel-group id="loadpoint4current" typeId="loadpoint4current"/>
|
||||
<channel-group id="loadpoint5current" typeId="loadpoint5current"/>
|
||||
<channel-group id="loadpoint6current" typeId="loadpoint6current"/>
|
||||
<channel-group id="loadpoint7current" typeId="loadpoint7current"/>
|
||||
<channel-group id="loadpoint8current" typeId="loadpoint8current"/>
|
||||
<channel-group id="loadpoint9current" typeId="loadpoint9current"/>
|
||||
</channel-groups>
|
||||
|
||||
<config-description>
|
||||
<parameter name="url" type="text" required="true">
|
||||
<context>network-address</context>
|
||||
<label>URL</label>
|
||||
<description>URL of evcc web UI, e.g. https://demo.evcc.io</description>
|
||||
</parameter>
|
||||
<parameter name="refreshInterval" type="integer" unit="s" min="15">
|
||||
<label>Refresh Interval</label>
|
||||
<description>Interval the status is polled in seconds.</description>
|
||||
<default>60</default>
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
<channel-group-type id="general">
|
||||
<label>General Data</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint0">
|
||||
<label>Loadpoint 0</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint1">
|
||||
<label>Loadpoint 1</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint2">
|
||||
<label>Loadpoint 2</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint3">
|
||||
<label>Loadpoint 3</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint4">
|
||||
<label>Loadpoint 4</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint5">
|
||||
<label>Loadpoint 5</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint6">
|
||||
<label>Loadpoint 6</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint7">
|
||||
<label>Loadpoint 7</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint8">
|
||||
<label>Loadpoint 8</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint9">
|
||||
<label>Loadpoint 9</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint0current">
|
||||
<label>Loadpoint 0: Current</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint1current">
|
||||
<label>Loadpoint 1: Current</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint2current">
|
||||
<label>Loadpoint 2: Current</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint3current">
|
||||
<label>Loadpoint 3: Current</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint4current">
|
||||
<label>Loadpoint 4: Current</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint5current">
|
||||
<label>Loadpoint 5: Current</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint6current">
|
||||
<label>Loadpoint 6: Current</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint7current">
|
||||
<label>Loadpoint 7: Current</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint8current">
|
||||
<label>Loadpoint 8: Current</label>
|
||||
</channel-group-type>
|
||||
<channel-group-type id="loadpoint9current">
|
||||
<label>Loadpoint 9: Current</label>
|
||||
</channel-group-type>
|
||||
|
||||
<!-- Units and description on: https://docs.evcc.io/docs/reference/configuration/messaging/#msg -->
|
||||
<channel-type id="batteryCapacity">
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>Battery Capacity</label>
|
||||
<description>Capacity of (home) battery</description>
|
||||
<category>Energy</category>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="batteryPower">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Battery Power</label>
|
||||
<description>Current power from battery</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Power</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="batterySoC">
|
||||
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||
<label>Battery SoC</label>
|
||||
<description>Current State of Charge of battery</description>
|
||||
<category>BatteryLevel</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<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>
|
||||
<tags>
|
||||
<tag>Switch</tag>
|
||||
<tag>Mode</tag>
|
||||
</tags>
|
||||
<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>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Mode</tag>
|
||||
</tags>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="prioritySoC">
|
||||
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||
<label>Battery Priority SoC</label>
|
||||
<description>State of Charge for which the battery has priority over charging the EV when charging mode is "pv"
|
||||
</description>
|
||||
<category>BatteryLevel</category>
|
||||
<state min="0" step="0.1" max="100" pattern="%.0f %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
<channel-type id="bufferSoC">
|
||||
<item-type unitHint="%">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 unitHint="%">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>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Power</tag>
|
||||
</tags>
|
||||
<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>
|
||||
<description>Current power from grid (negative means feed-in)</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Power</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="homePower">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Home Power</label>
|
||||
<description>Current power taken by home</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Power</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="pvPower">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>PV Power</label>
|
||||
<description>Current power from photovoltaik</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Power</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="version">
|
||||
<item-type>String</item-type>
|
||||
<label>Version</label>
|
||||
<description>Current evcc version</description>
|
||||
<category>Text</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="availableVersion">
|
||||
<item-type>String</item-type>
|
||||
<label>Available Version</label>
|
||||
<description>Available evcc update version</description>
|
||||
<category>Text</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<!-- Channel Types for loadpoints -->
|
||||
<channel-type id="activePhases">
|
||||
<item-type>Number</item-type>
|
||||
<label>Charging Active Phases</label>
|
||||
<description>Current number of active phases while charging</description>
|
||||
<category></category>
|
||||
<state pattern="%d" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="chargeCurrent">
|
||||
<item-type>Number:ElectricCurrent</item-type>
|
||||
<label>Charging Current</label>
|
||||
<description>Current amperage per connected phase while charging</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Current</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="chargeDuration">
|
||||
<item-type>Number:Time</item-type>
|
||||
<label>Charging Duration</label>
|
||||
<description>Charging duration</description>
|
||||
<category>Time</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Duration</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f min" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="chargePower">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Charging Power</label>
|
||||
<description>Current power of charging</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Power</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="chargeRemainingDuration">
|
||||
<item-type>Number:Time</item-type>
|
||||
<label>Charging Remaining Duration</label>
|
||||
<description>Remaining duration until limit SoC is reached</description>
|
||||
<category>Time</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Progress</tag>
|
||||
</tags>
|
||||
<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 limit SoC is reached</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="chargedEnergy">
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>Charged Energy</label>
|
||||
<description>Energy charged since plugged-in</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="charging">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Charging State</label>
|
||||
<description>Loadpoint is currently charging</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state pattern="%f %unit%" readOnly="true">
|
||||
<options>
|
||||
<option value="ON">Charging</option>
|
||||
<option value="OFF">Not charging</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="enabled">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Charging Enabled</label>
|
||||
<description>Charging enabled (mode not "off")</description>
|
||||
<category>Switch</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Enabled</tag>
|
||||
</tags>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">Enabled</option>
|
||||
<option value="OFF">Disabled</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="maxCurrent">
|
||||
<item-type>Number:ElectricCurrent</item-type>
|
||||
<label>Charging max Current</label>
|
||||
<description>Maximum amperage per connected phase with which the car should be charged</description>
|
||||
<category>Energy</category>
|
||||
<state min="0" step="1" pattern="%.0f %unit%" readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="minCurrent">
|
||||
<item-type>Number:ElectricCurrent</item-type>
|
||||
<label>Charging min Current</label>
|
||||
<description>Minimum amperage per connected phase with which the car should be charged</description>
|
||||
<category>Energy</category>
|
||||
<state min="0" step="1" pattern="%.0f %unit%" readOnly="false"/>
|
||||
<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>Heating</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Mode</tag>
|
||||
</tags>
|
||||
<state readOnly="false">
|
||||
<options>
|
||||
<option value="off">Off</option>
|
||||
<option value="now">Fast</option>
|
||||
<option value="minpv">Min + PV</option>
|
||||
<option value="pv">Only PV</option>
|
||||
</options>
|
||||
</state>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="phases">
|
||||
<item-type>Number</item-type>
|
||||
<label>Charging Enabled Phases</label>
|
||||
<description>The maximum number of phases which can be used</description>
|
||||
<category>Energy</category>
|
||||
<state min="0" step="1" max="3" pattern="%d" readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="limitEnergy">
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>Charging Limit Energy</label>
|
||||
<description>Amount of energy to charge the vehicle with</description>
|
||||
<category>BatteryLevel</category>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state min="0" pattern="%.0f %unit%" readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="limitSoC">
|
||||
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||
<label>Charging Limit SoC</label>
|
||||
<description>Until which state of charge (SoC) should the vehicle be charged</description>
|
||||
<category>BatteryLevel</category>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="limitTemperature">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>Charging Limit Temperature</label>
|
||||
<description>Until which Temperature should the heating device be charged</description>
|
||||
<category>Temperature</category>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Temperature</tag>
|
||||
</tags>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="effectiveLimitSoC">
|
||||
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||
<label>Effective Charging Limit</label>
|
||||
<description>Effective state of charge (SoC) until which the vehicle will be charged</description>
|
||||
<category>BatteryLevel</category>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="effectiveLimitTemperature">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>Effective Charging Limit Temperature</label>
|
||||
<description>Effective Temperature until which the heating device will be charged</description>
|
||||
<category>Temperature</category>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Temperature</tag>
|
||||
</tags>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="title">
|
||||
<item-type>String</item-type>
|
||||
<label>Loadpoint Title</label>
|
||||
<description>Title of loadpoint</description>
|
||||
<category>PowerOutlet</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Power</tag>
|
||||
</tags>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="vehicleConnected">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Vehicle Connected</label>
|
||||
<description>Whether vehicle is connected to loadpoint</description>
|
||||
<category>Switch</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">Connected</option>
|
||||
<option value="OFF">Not connected</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="vehicleConnectedDuration">
|
||||
<item-type>Number:Time</item-type>
|
||||
<label>Vehicle Connected Duration</label>
|
||||
<description>Duration the vehicle is connected to loadpoint</description>
|
||||
<category>Time</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Duration</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="vehicleOdometer">
|
||||
<item-type>Number:Length</item-type>
|
||||
<label>Vehicle Odometer</label>
|
||||
<description>Total distance travelled by EV</description>
|
||||
<category>MoveControl</category>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="vehiclePresent">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Vehicle Data Access</label>
|
||||
<description>Whether evcc is able to get data from vehicle</description>
|
||||
<category>Switch</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">Data access</option>
|
||||
<option value="OFF">No data access</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="vehicleRange">
|
||||
<item-type>Number:Length</item-type>
|
||||
<label>Vehicle Range</label>
|
||||
<description>Battery range for EV</description>
|
||||
<category></category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Power</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="vehicleSoC">
|
||||
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||
<label>Vehicle SoC</label>
|
||||
<description>Current State of Charge of EV</description>
|
||||
<category>BatteryLevel</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="vehicleTemperature">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>Temperature</label>
|
||||
<description>Current Temperature of the heating device</description>
|
||||
<category>Temperature</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Temperature</tag>
|
||||
</tags>
|
||||
<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-type id="chargerFeatureHeating">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Charger Feature: Heating</label>
|
||||
<description>'True' for heating device: State of Charge in Degree instead of Percent</description>
|
||||
<category>Switch</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">True</option>
|
||||
<option value="OFF">False</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="chargerFeatureIntegratedDevice">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Charger Feature: Integrated Device</label>
|
||||
<description>'True' for integrated device: Operate without a "vehicle" (e.g. heat pump, eBike)</description>
|
||||
<category>Switch</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">True</option>
|
||||
<option value="OFF">False</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<!-- Channel Types for vehicles -->
|
||||
<channel-type id="vehicleTitle">
|
||||
<item-type>String</item-type>
|
||||
<label>Vehicle Title</label>
|
||||
<description>Title of vehicle</description>
|
||||
<category>GarageDoor</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="heatingTitle">
|
||||
<item-type>String</item-type>
|
||||
<label>Heating Title</label>
|
||||
<description>Title of heating device</description>
|
||||
<category>Heating</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="vehicleMinSoC">
|
||||
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||
<label>Vehicle Min SoC</label>
|
||||
<description>Minimum state of charge (SoC) a vehicle should have</description>
|
||||
<category>BatteryLevel</category>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="heatingMinTemperature">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>Heating Min Temperature</label>
|
||||
<description>Minimum Temperature a heating device should have</description>
|
||||
<category>Temperature</category>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Temperature</tag>
|
||||
</tags>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="vehicleLimitSoC">
|
||||
<item-type unitHint="%">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>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="heatingLimitTemperature">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>Charging Temperature Limit</label>
|
||||
<description>Until which Temperature should the specific heating device be charged</description>
|
||||
<category>Temperature</category>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Temperature</tag>
|
||||
</tags>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="vehicleCapacity">
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>Vehicle Capacity</label>
|
||||
<description>Capacity of EV battery</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="heatingCapacity">
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>Heating Capacity</label>
|
||||
<description>Capacity of heating device</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</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>
|
||||
<tags>
|
||||
<tag>Switch</tag>
|
||||
<tag>Enabled</tag>
|
||||
</tags>
|
||||
<state readOnly="false">
|
||||
<options>
|
||||
<option value="ON">Enabled</option>
|
||||
<option value="OFF">Disabled</option>
|
||||
</options>
|
||||
</state>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="heatingPlanEnabled">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Heating Plan Enabled</label>
|
||||
<description>Plan for charging enabled</description>
|
||||
<category>Switch</category>
|
||||
<tags>
|
||||
<tag>Switch</tag>
|
||||
<tag>Enabled</tag>
|
||||
</tags>
|
||||
<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 unitHint="%">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>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="heatingPlanTemperature">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>Heating Plan Temperature</label>
|
||||
<description>Until which Temperature should heating device be charged in plan</description>
|
||||
<category>Temperature</category>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Temperature</tag>
|
||||
</tags>
|
||||
<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>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Timestamp</tag>
|
||||
</tags>
|
||||
<state readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="heatingPlanTime">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>Heating Plan Time</label>
|
||||
<description>When the plan Temperature should be reached</description>
|
||||
<category>Time</category>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Timestamp</tag>
|
||||
</tags>
|
||||
<state readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="evcc"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<thing-type id="vehicle" listed="false">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="server"/>
|
||||
</supported-bridge-type-refs>
|
||||
<label>Vehicle</label>
|
||||
<description>A vehicle configured in your evcc instance</description>
|
||||
<representation-property>id</representation-property>
|
||||
</thing-type>
|
||||
<channel-type id="vehicle-capacity">
|
||||
<item-type unitHint="kWh">Number:Energy</item-type>
|
||||
<label>Vehicle Capacity</label>
|
||||
<description>Capacity of vehicle battery</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="vehicle-icon">
|
||||
<item-type>String</item-type>
|
||||
<label>Vehicle Icon</label>
|
||||
<description>Used icon for this vehicle in the UI</description>
|
||||
<category>Text</category>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Info</tag>
|
||||
</tags>
|
||||
<state readOnly="true"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="vehicle-limit-soc">
|
||||
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||
<label>Vehicle Limit SoC</label>
|
||||
<description>State of charge to which the vehicle is charged</description>
|
||||
<category>BatteryLevel</category>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="vehicle-min-soc">
|
||||
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||
<label>Vehicle Min SoC</label>
|
||||
<description>Minimum state of charge a vehicle should have (fast charging until this limit)</description>
|
||||
<category>BatteryLevel</category>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="vehicle-max-current">
|
||||
<item-type unitHint="A">Number:ElectricCurrent</item-type>
|
||||
<label>Vehicle Max Current</label>
|
||||
<description>Maximum allowed current that can be provided to charge the vehicle</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Control</tag>
|
||||
<tag>Current</tag>
|
||||
</tags>
|
||||
<state min="6" step="1" max="32" readOnly="true"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="vehicle-min-current">
|
||||
<item-type unitHint="A">Number:ElectricCurrent</item-type>
|
||||
<label>Vehicle Min Current</label>
|
||||
<description>Minimum current that needs to provided to charge the vehicle</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Control</tag>
|
||||
<tag>Current</tag>
|
||||
</tags>
|
||||
<state min="6" step="1" max="32" readOnly="true"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="vehicle-plan-precondition">
|
||||
<item-type>Number:Time</item-type>
|
||||
<label>Plan Precondition Duration</label>
|
||||
<description>Configured duration for charging the vehicle before departure (preconditioning the battery)</description>
|
||||
<category>Time</category>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Duration</tag>
|
||||
</tags>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="vehicle-plan-soc">
|
||||
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||
<label>Planned SoC</label>
|
||||
<description>Planned state of charge to which the vehicle will be charged (can be greater than the Vehicle Limit SoC)</description>
|
||||
<tags>
|
||||
<tag>Setpoint</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state readOnly="true"></state>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="vehicle-plan-time">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>Plan Datetime</label>
|
||||
<description>Planned date and time when the charging should be started</description>
|
||||
<state readOnly="true"></state>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="vehicle-title">
|
||||
<item-type>String</item-type>
|
||||
<label>Vehicle Title</label>
|
||||
<description>Name of the vehicle as displayed in the UI</description>
|
||||
<category>Text</category>
|
||||
<state readOnly="true"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
Reference in New Issue
Block a user