mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[evcc] Initial contribution (#12611)
Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
This commit is contained in:
parent
9c0541c2c9
commit
2e1fbdd86f
@ -90,6 +90,7 @@
|
||||
/bundles/org.openhab.binding.enturno/ @klocsson
|
||||
/bundles/org.openhab.binding.epsonprojector/ @mlobstein
|
||||
/bundles/org.openhab.binding.etherrain/ @dfad1469
|
||||
/bundles/org.openhab.binding.evcc/ @florian-h05
|
||||
/bundles/org.openhab.binding.evohome/ @Nebula83
|
||||
/bundles/org.openhab.binding.exec/ @kgoderis
|
||||
/bundles/org.openhab.binding.feed/ @svilenvul
|
||||
|
@ -441,6 +441,11 @@
|
||||
<artifactId>org.openhab.binding.etherrain</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.binding.evcc</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.binding.evohome</artifactId>
|
||||
|
13
bundles/org.openhab.binding.evcc/NOTICE
Normal file
13
bundles/org.openhab.binding.evcc/NOTICE
Normal file
@ -0,0 +1,13 @@
|
||||
This content is produced and maintained by the openHAB project.
|
||||
|
||||
* Project home: https://www.openhab.org
|
||||
|
||||
== Declared Project Licenses
|
||||
|
||||
This program and the accompanying materials are made available under the terms
|
||||
of the Eclipse Public License 2.0 which is available at
|
||||
https://www.eclipse.org/legal/epl-2.0/.
|
||||
|
||||
== Source Code
|
||||
|
||||
https://github.com/openhab/openhab-addons
|
171
bundles/org.openhab.binding.evcc/README.md
Normal file
171
bundles/org.openhab.binding.evcc/README.md
Normal file
@ -0,0 +1,171 @@
|
||||
# evcc Binding
|
||||
|
||||
This binding integrates [evcc - electric vehicle charging control](https://evcc.io), a project that provides a control center for electric vehicle charging.
|
||||
|
||||
evcc controls your wallbox(es) with multiple charging modes and allows you to charge your ev with your photovoltaik'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.
|
||||
For more advanced features like calculated savings, you have to visit the web UI of evcc.
|
||||
|
||||
## Supported Things
|
||||
|
||||
- `device`: A running evcc installation.
|
||||
|
||||
## Discovery
|
||||
|
||||
No auto discovery supported.
|
||||
|
||||
## Thing Configuration
|
||||
|
||||
### `device` Thing Configuration
|
||||
|
||||
| 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 60 seconds.
|
||||
|
||||
## 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#batteryPower | Number:Power | R | Current power from battery. |
|
||||
| general#batterySoC | Number:Dimensionless | R | Current State of Charge of battery. |
|
||||
| general#batteryPrioritySoC | Number:Dimensionless | R | State of State of Charge for which the battery has priority over charging the ev when charging mode is "pv". |
|
||||
| general#gridPower | Number:Power | R | Current power from grid (negative means feed-in) |
|
||||
| general#homePower | Number:Power | R | Current power taken by home. |
|
||||
| general#pvPower | Number:Power | R | Current power from photovoltaik. |
|
||||
|
||||
|
||||
### Loadpoint channels
|
||||
|
||||
Those channels exist per configured loadpoint.
|
||||
Please note that you have to replace *N* with your loadpoint number.
|
||||
|
||||
| Channel | Type | Read/Write | Description |
|
||||
|-------------------------------------|------------------------|------------|-----------------------------------------------------------------------------------------------------|
|
||||
| loadpointN#activePhases | Number | R | Current number of active phases while charging |
|
||||
| loadpointN#chargeCurrent | Number:ElectricCurrent | R | Current amperage per connected phase while charging |
|
||||
| loadpointN#chargeDuration | Number:Time | R | Charging duration |
|
||||
| loadpointN#chargeRemainingDuration | Number:Time | R | Remaining duration until target SoC is reached |
|
||||
| loadpointN#chargeRemainingEnergy | Number:Energy | R | Remaining energy until target SoC is reached |
|
||||
| loadpointN#chargePower | Number:Power | R | Current power of charging |
|
||||
| loadpointN#chargedEnergy | Number:Energy | R | Energy charged since plugged-in |
|
||||
| loadpointN#charging | Switch | R | Loadpoint is currently charging |
|
||||
| loadpointN#enabled | Switch | R | Charging enabled (mode is not "off") |
|
||||
| loadpointN#hasVehicle | Switch | R | Whether vehicle is configured for loadpoint |
|
||||
| loadpointN#maxCurrent | Number:ElectricCurrent | RW | Maximum amperage per connected phase with which the car should be charged |
|
||||
| loadpointN#minCurrent | Number:ElectricCurrent | RW | Minimum amperage per connected phase with which the car should be charged |
|
||||
| loadpointN#minSoC | Number:Dimensionless | RW | Charge immediately with maximum power up to the defined SoC, if the charge mode is not set to "off" |
|
||||
| loadpointN#mode | String | RW | Charging mode: "off", "now", "minpv", "pv" |
|
||||
| loadpointN#phases | Number | RW | The maximum number of phases which can be used |
|
||||
| loadpointN#targetSoC | Number:Dimensionless | RW | Until which state of charge (SoC) should the vehicle be charged |
|
||||
| loadpointN#targetTime | DateTime | RW | When the target SoC should be reached |
|
||||
| loadpointN#targetTimeEnabled | Switch | RW | Target time for charging enabled |
|
||||
| loadpointN#title | String | R | Title of loadpoint |
|
||||
| loadpointN#vehicleConnected | Switch | R | Whether vehicle is connected to loadpoint |
|
||||
| loadpointN#vehicleConnectedDuration | Number:Time | R | Duration the vehicle is connected to loadpoint |
|
||||
| loadpointN#vehicleCapacity | Number:Energy | R | Capacity of EV battery |
|
||||
| loadpointN#vehicleOdometer | Number:Length | R | Total distance travelled by EV |
|
||||
| loadpointN#vehiclePresent | Switch | R | Whether evcc is able to get data from vehicle |
|
||||
| loadpointN#vehicleRange | Number:Length | R | Battery range for EV |
|
||||
| loadpointN#vehicleSoC | Number:Dimensionless | R | Current State of Charge of EV |
|
||||
| loadpointN#vehicleTitle | String | R | Name of EV |
|
||||
|
||||
## Full Example
|
||||
|
||||
### Thing(s)
|
||||
|
||||
```
|
||||
Thing evcc:device:demo "evcc Demo" [url="https://demo.evcc.io", refreshInterval=60]
|
||||
```
|
||||
|
||||
### Items
|
||||
|
||||
```
|
||||
// General
|
||||
Number:Power evcc_demo_batteryPower "Battery Power [%.1f kW]" <energy> {channel="evcc:device:demo:general#batteryPower"}
|
||||
Number:Dimensionless evcc_demo_batterySoC "Battery SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:general#batterySoC"}
|
||||
Number:Dimensionless evcc_demo_batteryPrioritySoC "Battery Priority SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:general#batteryPrioritySoC"}
|
||||
Number:Power evcc_demo_gridPower "Grid Power [%.1f kW]" <energy> {channel="evcc:device:demo:general#gridPower"}
|
||||
Number:Power evcc_demo_homePower "Home Power [%.1f kW]" <energy> {channel="evcc:device:demo:general#homePower"}
|
||||
Number:Power evcc_demo_pvPower "PV Power [%.1f kW]" <energy> {channel="evcc:device:demo:general#pvPower"}
|
||||
|
||||
// Loadpoint
|
||||
Number evcc_demo_loadpoint0_activePhases "Active Phases [%d]" {channel="evcc:device:demo:loadpoint0#activePhases"}
|
||||
Number:ElectricCurrent evcc_demo_loadpoint0_chargeCurrent "Charging current [%.0f A]" <energy> {channel="evcc:device:demo:loadpoint0#chargeCurrent"}
|
||||
Number:Time evcc_demo_loadpoint0_chargeDuration "Charging duration [%1$tH:%1$tM]" <time> {channel="evcc:device:demo:loadpoint0#chargeDuration"}
|
||||
Number:Time evcc_demo_loadpoint0_chargeRemainingDuration "Charging remaining duration [%1$tH:%1$tM]" <time> {channel="evcc:device:demo:loadpoint0#chargeRemainingDuration"}
|
||||
Number:Energy evcc_demo_loadpoint0_chargeRemainingEnergy "Charging remaining energy [%.1f kWh]" <energy> {channel="evcc:device:demo:loadpoint0#chargeRemainingEnergy"}
|
||||
Number:Power evcc_demo_loadpoint0_chargePower "Charging power [%.1f kW]" <energy> {channel="evcc:device:demo:loadpoint0#chargePower"}
|
||||
Number:Energy evcc_demo_loadpoint0_chargedEnergy "Charged energy [%.1f kWh]" <energy> {channel="evcc:device:demo:loadpoint0#chargedEnergy"}
|
||||
Switch evcc_demo_loadpoint0_charging "Currently charging [%s]" <battery> {channel="evcc:device:demo:loadpoint0#charging"}
|
||||
Switch evcc_demo_loadpoint0_enabled "Charging enabled [%s]" <switch> {channel="evcc:device:demo:loadpoint0#enabled"}
|
||||
Switch evcc_demo_loadpoint0_hasVehicle "Vehicle configured [%s]" <switch> {channel="evcc:device:demo:loadpoint0#hasVehicle"}
|
||||
Number:ElectricCurrent evcc_demo_loadpoint0_maxCurrent "Maximum current [%.0f A]" <energy> {channel="evcc:device:demo:loadpoint0#maxCurrent"}
|
||||
Number:ElectricCurrent evcc_demo_loadpoint0_minCurrent "Minimum current [%.0f A]" <energy> {channel="evcc:device:demo:loadpoint0#minCurrent"}
|
||||
Number:Dimensionless evcc_demo_loadpoint0_minSoC "Minimum SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:loadpoint0#minSoC"}
|
||||
String evcc_demo_loadpoint0_mode "Mode [%s]" {channel="evcc:device:demo:loadpoint0#mode"}
|
||||
Number evcc_demo_loadpoint0_phases "Enabled phases [%d]" {channel="evcc:device:demo:loadpoint0#phases"}
|
||||
Number:Dimensionless evcc_demo_loadpoint0_targetSoC "Target SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:loadpoint0#targetSoC"}
|
||||
DateTime evcc_demo_loadpoint0_targetTime "Target time [%1$td.%1$tm.%1$tY, %1$tH:%1$tM]" <time> {channel="evcc:device:demo:loadpoint0#targetTime"}
|
||||
Switch evcc_demo_loadpoint0_targetTimeEnabled "Target time enabled [%s]" <switch> {channel="evcc:device:demo:loadpoint0#targetTimeEnabled"}
|
||||
String evcc_demo_loadpoint0_title "Loadpoint title [%s]" <text> {channel="evcc:device:demo:loadpoint0#title"}
|
||||
// Vehicle on loadpoint
|
||||
Switch evcc_demo_loadpoint0_vehicleConnected "Vehicle connected [%s]" <switch> {channel="evcc:device:demo:loadpoint0#vehicleConnected"}
|
||||
Number:Time evcc_demo_loadpoint0_vehicleConnectedDuration "Vehicle connected duration [%.1f h]" <time> {channel="evcc:device:demo:loadpoint0#vehicleConnectedDuration"}
|
||||
Number:Energy evcc_demo_loadpoint0_vehicleCapacity "Vehicle capacity [%.0f kWH]" <batterylevel> {channel="evcc:device:demo:loadpoint0#vehicleCapacity"}
|
||||
Number:Length evcc_demo_loadpoint0_vehicleOdometer "Vehicle odometer [%.1f km]" {channel="evcc:device:demo:loadpoint0#vehicleOdometer"}
|
||||
Switch evcc_demo_loadpoint0_vehiclePresent "Vehicle present [%s]" <switch> {channel="evcc:device:demo:loadpoint0#vehiclePresent"}
|
||||
Number:Length evcc_demo_loadpoint0_vehicleRange "Vehicle Range [%.0f km]" {channel="evcc:device:demo:loadpoint0#vehicleRange"}
|
||||
Number:Dimensionless evcc_demo_loadpoint0_vehicleSoC "Vehicle SoC [%d %%]" <batterylevel> {channel="evcc:device:demo:loadpoint0#vehicleSoC"}
|
||||
String evcc_demo_loadpoint0_vehicleName "Vehicle name [%s]" <text> {channel="evcc:device:demo:loadpoint0#vehicleTitle"}
|
||||
```
|
||||
|
||||
### Sitemap
|
||||
|
||||
```
|
||||
sitemap evcc label="evcc Demo" {
|
||||
Frame label="General" {
|
||||
Text item=evcc_demo_batteryPower
|
||||
Text item=evcc_demo_batterySoC
|
||||
Text item=evcc_demo_gridPower
|
||||
Text item=evcc_demo_homePower
|
||||
Text item=evcc_demo_pvPower
|
||||
}
|
||||
Frame label="Loadpoint 0" {
|
||||
Text item=evcc_demo_loadpoint0_title
|
||||
Text item=evcc_demo_loadpoint0_enabled label="Charging" {
|
||||
Text item=evcc_demo_loadpoint0_charging
|
||||
Text item=evcc_demo_loadpoint0_chargePower
|
||||
Text item=evcc_demo_loadpoint0_chargeCurrent
|
||||
Text item=evcc_demo_loadpoint0_activePhases
|
||||
Text item=evcc_demo_loadpoint0_chargeDuration
|
||||
Text item=evcc_demo_loadpoint0_chargeRemainingDuration
|
||||
Text item=evcc_demo_loadpoint0_chargeRemainingEnergy
|
||||
}
|
||||
Switch item=evcc_demo_loadpoint0_mode mappings=["off"="Stop","now"="Now","minpv"="Min + PV", "pv"="Only PV"]
|
||||
Text label="Charging settings" icon="settings" {
|
||||
Setpoint item=evcc_demo_loadpoint0_targetSoC minValue=5 maxValue=100 step=5
|
||||
Setpoint item=evcc_demo_loadpoint0_minCurrent minValue=6 maxValue=96 step=2
|
||||
Setpoint item=evcc_demo_loadpoint0_maxCurrent minValue=6 maxValue=96 step=2
|
||||
Setpoint item=evcc_demo_loadpoint0_minSoC minValue=0 maxValue=100 step=5
|
||||
Setpoint item=evcc_demo_loadpoint0_phases minValue=1 maxValue=3 step=2
|
||||
}
|
||||
Text item=evcc_demo_loadpoint0_vehicleName label="Vehicle" {
|
||||
Text item=evcc_demo_loadpoint0_vehicleCapacity
|
||||
Text item=evcc_demo_loadpoint0_vehicleOdometer
|
||||
Text item=evcc_demo_loadpoint0_vehicleRange
|
||||
Text item=evcc_demo_loadpoint0_vehicleSoC
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
17
bundles/org.openhab.binding.evcc/pom.xml
Normal file
17
bundles/org.openhab.binding.evcc/pom.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.binding.evcc</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Bundles :: evcc Binding</name>
|
||||
|
||||
</project>
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.evcc-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||
|
||||
<feature name="openhab-binding-evcc" description="evcc Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.evcc/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
@ -0,0 +1,131 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2022 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;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
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.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EvccBindingConstants {
|
||||
|
||||
private static final String BINDING_ID = "evcc";
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
public static final ThingTypeUID THING_TYPE_DEVICE = new ThingTypeUID(BINDING_ID, "device");
|
||||
|
||||
// List of all Channel Type UIDs
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_BATTERY_POWER = new ChannelTypeUID(BINDING_ID, "batteryPower");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_BATTERY_SOC = new ChannelTypeUID(BINDING_ID, "batterySoC");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_BATTERY_PRIORITY_SOC = new ChannelTypeUID(BINDING_ID,
|
||||
"batteryPrioritySoC");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_GRID_POWER = new ChannelTypeUID(BINDING_ID, "gridPower");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_HOME_POWER = new ChannelTypeUID(BINDING_ID, "homePower");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_PV_POWER = new ChannelTypeUID(BINDING_ID, "pvPower");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_ACTIVE_PHASES = new ChannelTypeUID(BINDING_ID,
|
||||
"activePhases");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_CHARGE_CURRENT = new ChannelTypeUID(BINDING_ID,
|
||||
"chargeCurrent");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_CHARGE_DURATION = new ChannelTypeUID(BINDING_ID,
|
||||
"chargeDuration");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_CHARGE_POWER = new ChannelTypeUID(BINDING_ID,
|
||||
"chargePower");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_CHARGE_REMAINING_DURATION = new ChannelTypeUID(
|
||||
BINDING_ID, "chargeRemainingDuration");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_CHARGE_REMAINING_ENERGY = new ChannelTypeUID(
|
||||
BINDING_ID, "chargeRemainingEnergy");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_CHARGED_ENERGY = new ChannelTypeUID(BINDING_ID,
|
||||
"chargedEnergy");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_CHARGING = new ChannelTypeUID(BINDING_ID, "charging");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_CONNECTED = new ChannelTypeUID(BINDING_ID,
|
||||
"vehicleConnected");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_CONNECTED_DURATION = new ChannelTypeUID(BINDING_ID,
|
||||
"vehicleConnectedDuration");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_ENABLED = new ChannelTypeUID(BINDING_ID, "enabled");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_HAS_VEHICLE = new ChannelTypeUID(BINDING_ID,
|
||||
"hasVehicle");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_MAX_CURRENT = new ChannelTypeUID(BINDING_ID,
|
||||
"maxCurrent");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_MIN_CURRENT = new ChannelTypeUID(BINDING_ID,
|
||||
"minCurrent");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_MIN_SOC = new ChannelTypeUID(BINDING_ID, "minSoC");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_MODE = new ChannelTypeUID(BINDING_ID, "mode");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_PHASES = new ChannelTypeUID(BINDING_ID, "phases");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_TARGET_SOC = new ChannelTypeUID(BINDING_ID,
|
||||
"targetSoC");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_TARGET_TIME = new ChannelTypeUID(BINDING_ID,
|
||||
"targetTime");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_TARGET_TIME_ENABLED = new ChannelTypeUID(BINDING_ID,
|
||||
"targetTimeEnabled");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_TITLE = new ChannelTypeUID(BINDING_ID, "title");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_CAPACITY = new ChannelTypeUID(BINDING_ID,
|
||||
"vehicleCapacity");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_ODOMETER = new ChannelTypeUID(BINDING_ID,
|
||||
"vehicleOdometer");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_PRESENT = new ChannelTypeUID(BINDING_ID,
|
||||
"vehiclePresent");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_RANGE = new ChannelTypeUID(BINDING_ID,
|
||||
"vehicleRange");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_SOC = new ChannelTypeUID(BINDING_ID,
|
||||
"vehicleSoC");
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_TITLE = new ChannelTypeUID(BINDING_ID,
|
||||
"vehicleTitle");
|
||||
|
||||
// List of all Channel ids
|
||||
public static final String CHANNEL_BATTERY_POWER = "batteryPower";
|
||||
public static final String CHANNEL_BATTERY_SOC = "batterySoC";
|
||||
public static final String CHANNEL_BATTERY_PRIORITY_SOC = "batteryPrioritySoC";
|
||||
public static final String CHANNEL_GRID_POWER = "gridPower";
|
||||
public static final String CHANNEL_HOME_POWER = "homePower";
|
||||
public static final String CHANNEL_PV_POWER = "pvPower";
|
||||
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_HAS_VEHICLE = "hasVehicle";
|
||||
public static final String CHANNEL_LOADPOINT_MAX_CURRENT = "maxCurrent";
|
||||
public static final String CHANNEL_LOADPOINT_MIN_CURRENT = "minCurrent";
|
||||
public static final String CHANNEL_LOADPOINT_MIN_SOC = "minSoC";
|
||||
public static final String CHANNEL_LOADPOINT_MODE = "mode";
|
||||
public static final String CHANNEL_LOADPOINT_PHASES = "phases";
|
||||
public static final String CHANNEL_LOADPOINT_TARGET_SOC = "targetSoC";
|
||||
public static final String CHANNEL_LOADPOINT_TARGET_TIME = "targetTime";
|
||||
/**
|
||||
* Whether a target time is set on loadpoint.
|
||||
*/
|
||||
public static final String CHANNEL_LOADPOINT_TARGET_TIME_ENABLED = "targetTimeEnabled";
|
||||
public static final String CHANNEL_LOADPOINT_TITLE = "title";
|
||||
public static final String CHANNEL_LOADPOINT_VEHICLE_CAPACITY = "vehicleCapacity";
|
||||
public static final String CHANNEL_LOADPOINT_VEHICLE_ODOMETER = "vehicleOdometer";
|
||||
public static final String CHANNEL_LOADPOINT_VEHICLE_PRESENT = "vehiclePresent";
|
||||
public static final String CHANNEL_LOADPOINT_VEHICLE_RANGE = "vehicleRange";
|
||||
public static final String CHANNEL_LOADPOINT_VEHICLE_SOC = "vehicleSoC";
|
||||
public static final String CHANNEL_LOADPOINT_VEHICLE_TITLE = "vehicleTitle";
|
||||
|
||||
public static final int CONNECTION_TIMEOUT_MILLISEC = 5000;
|
||||
public static final int LONG_CONNECTION_TIMEOUT_MILLISEC = 60000;
|
||||
public static final String EVCC_REST_API = "/api/";
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2022 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;
|
||||
|
||||
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
|
||||
*/
|
||||
@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;
|
||||
}
|
@ -0,0 +1,448 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2022 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;
|
||||
|
||||
import static org.openhab.binding.evcc.internal.EvccBindingConstants.*;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeParseException;
|
||||
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.api.EvccAPI;
|
||||
import org.openhab.binding.evcc.internal.api.EvccApiException;
|
||||
import org.openhab.binding.evcc.internal.api.dto.Loadpoint;
|
||||
import org.openhab.binding.evcc.internal.api.dto.Result;
|
||||
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.MetricPrefix;
|
||||
import org.openhab.core.library.unit.SIUnits;
|
||||
import org.openhab.core.library.unit.Units;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.thing.binding.builder.ChannelBuilder;
|
||||
import org.openhab.core.thing.binding.builder.ThingBuilder;
|
||||
import org.openhab.core.thing.type.ChannelTypeUID;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link EvccHandler} is responsible for handling commands, which are
|
||||
* sent to one of the channels.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EvccHandler extends BaseThingHandler {
|
||||
private final Logger logger = LoggerFactory.getLogger(EvccHandler.class);
|
||||
private @Nullable EvccAPI evccAPI;
|
||||
private @Nullable ScheduledFuture<?> statePollingJob;
|
||||
|
||||
private @Nullable Result result;
|
||||
|
||||
private boolean batteryConfigured = false;
|
||||
private boolean gridConfigured = false;
|
||||
private boolean pvConfigured = false;
|
||||
|
||||
private int targetSoC = 100;
|
||||
private boolean targetTimeEnabled = false;
|
||||
private ZonedDateTime targetTimeZDT = ZonedDateTime.now().plusHours(12);
|
||||
|
||||
public EvccHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (command.equals(RefreshType.REFRESH)) {
|
||||
refresh();
|
||||
} else {
|
||||
logger.debug("Handling command {} ({}) for channel {}", command, command.getClass(), channelUID);
|
||||
String groupId = channelUID.getGroupId();
|
||||
if (groupId == null) {
|
||||
return;
|
||||
}
|
||||
String channelIdWithoutGroup = channelUID.getIdWithoutGroup();
|
||||
int loadpoint = Integer.parseInt(groupId.toString().substring(9));
|
||||
EvccAPI evccAPI = this.evccAPI;
|
||||
if (evccAPI == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
switch (channelIdWithoutGroup) {
|
||||
case CHANNEL_LOADPOINT_MODE:
|
||||
if (command instanceof StringType) {
|
||||
evccAPI.setMode(loadpoint, command.toString());
|
||||
}
|
||||
break;
|
||||
case CHANNEL_LOADPOINT_MIN_SOC:
|
||||
if (command instanceof QuantityType) {
|
||||
evccAPI.setMinSoC(loadpoint, ((QuantityType<?>) command).intValue());
|
||||
}
|
||||
break;
|
||||
case CHANNEL_LOADPOINT_TARGET_SOC:
|
||||
if (command instanceof QuantityType) {
|
||||
evccAPI.setTargetSoC(loadpoint, ((QuantityType<?>) command).intValue());
|
||||
}
|
||||
break;
|
||||
case CHANNEL_LOADPOINT_TARGET_TIME:
|
||||
if (command instanceof DateTimeType) {
|
||||
targetTimeZDT = ((DateTimeType) command).getZonedDateTime();
|
||||
ChannelUID channel = new ChannelUID(getThing().getUID(), "loadpoint" + loadpoint,
|
||||
CHANNEL_LOADPOINT_TARGET_TIME);
|
||||
updateState(channel, new DateTimeType(targetTimeZDT));
|
||||
if (targetTimeEnabled) {
|
||||
try {
|
||||
evccAPI.setTargetCharge(loadpoint, targetSoC, targetTimeZDT);
|
||||
} catch (DateTimeParseException e) {
|
||||
logger.debug("Failed to set target charge", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CHANNEL_LOADPOINT_TARGET_TIME_ENABLED:
|
||||
if (command == OnOffType.ON) {
|
||||
evccAPI.setTargetCharge(loadpoint, targetSoC, targetTimeZDT);
|
||||
targetTimeEnabled = true;
|
||||
} else if (command == OnOffType.OFF) {
|
||||
evccAPI.unsetTargetCharge(loadpoint);
|
||||
targetTimeEnabled = false;
|
||||
}
|
||||
break;
|
||||
case CHANNEL_LOADPOINT_PHASES:
|
||||
if (command instanceof DecimalType) {
|
||||
evccAPI.setPhases(loadpoint, ((DecimalType) command).intValue());
|
||||
}
|
||||
break;
|
||||
case CHANNEL_LOADPOINT_MIN_CURRENT:
|
||||
if (command instanceof QuantityType) {
|
||||
evccAPI.setMinCurrent(loadpoint, ((QuantityType<?>) command).intValue());
|
||||
}
|
||||
break;
|
||||
case CHANNEL_LOADPOINT_MAX_CURRENT:
|
||||
if (command instanceof QuantityType) {
|
||||
evccAPI.setMaxCurrent(loadpoint, ((QuantityType<?>) command).intValue());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
} catch (EvccApiException e) {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause == null) {
|
||||
logger.debug("Failed to handle command {} for channel {}: {}", command, channelUID, e.getMessage());
|
||||
} else {
|
||||
logger.debug("Failed to handle command {} for channel {}: {} -> {}", command, channelUID,
|
||||
e.getMessage(), cause.getMessage());
|
||||
}
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
EvccConfiguration config = getConfigAs(EvccConfiguration.class);
|
||||
String url = config.url;
|
||||
if (url == null || url.isBlank()) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR,
|
||||
"@text/offline.configuration-error.no-host");
|
||||
} else {
|
||||
this.evccAPI = new EvccAPI(url);
|
||||
logger.debug("Setting up refresh job ...");
|
||||
statePollingJob = scheduler.scheduleWithFixedDelay(this::refresh, 0, config.refreshInterval,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes from evcc.
|
||||
*
|
||||
* First, checks connection and updates Thing status.
|
||||
* Second, creates all available channels.
|
||||
* Third, updates all channels.
|
||||
*/
|
||||
private void refresh() {
|
||||
logger.debug("Running refresh job ...");
|
||||
EvccAPI evccAPI = null;
|
||||
evccAPI = this.evccAPI;
|
||||
if (evccAPI == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.result = evccAPI.getResult();
|
||||
} catch (EvccApiException e) {
|
||||
logger.debug("Failed to get state");
|
||||
}
|
||||
Result result = this.result;
|
||||
if (result == null) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
|
||||
"@text/offline.communication-error.request-failed");
|
||||
} else {
|
||||
String sitename = result.getSiteTitle();
|
||||
int numberOfLoadpoints = result.getLoadpoints().length;
|
||||
logger.debug("Found {} loadpoints on site {}.", numberOfLoadpoints, sitename);
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
batteryConfigured = result.getBatteryConfigured();
|
||||
gridConfigured = result.getGridConfigured();
|
||||
pvConfigured = result.getPvConfigured();
|
||||
createChannelsGeneral();
|
||||
updateChannelsGeneral();
|
||||
for (int i = 0; i < numberOfLoadpoints; i++) {
|
||||
createChannelsLoadpoint(i);
|
||||
updateChannelsLoadpoint(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
ScheduledFuture<?> statePollingJob = this.statePollingJob;
|
||||
if (statePollingJob != null) {
|
||||
statePollingJob.cancel(true);
|
||||
this.statePollingJob = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Utility functions
|
||||
private void createChannelsGeneral() {
|
||||
final String channelGroup = "general";
|
||||
if (batteryConfigured) {
|
||||
createChannel(CHANNEL_BATTERY_POWER, channelGroup, CHANNEL_TYPE_UID_BATTERY_POWER, "Number:Power");
|
||||
createChannel(CHANNEL_BATTERY_SOC, channelGroup, CHANNEL_TYPE_UID_BATTERY_SOC, "Number:Dimensionless");
|
||||
createChannel(CHANNEL_BATTERY_PRIORITY_SOC, channelGroup, CHANNEL_TYPE_UID_BATTERY_PRIORITY_SOC,
|
||||
"Number:Dimensionless");
|
||||
}
|
||||
if (gridConfigured) {
|
||||
createChannel(CHANNEL_GRID_POWER, channelGroup, CHANNEL_TYPE_UID_GRID_POWER, "Number:Power");
|
||||
}
|
||||
createChannel(CHANNEL_HOME_POWER, channelGroup, CHANNEL_TYPE_UID_HOME_POWER, "Number:Power");
|
||||
if (pvConfigured) {
|
||||
createChannel(CHANNEL_PV_POWER, channelGroup, CHANNEL_TYPE_UID_PV_POWER, "Number:Power");
|
||||
}
|
||||
}
|
||||
|
||||
private void createChannelsLoadpoint(int loadpointId) {
|
||||
final String channelGroup = "loadpoint" + loadpointId;
|
||||
createChannel(CHANNEL_LOADPOINT_ACTIVE_PHASES, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_ACTIVE_PHASES,
|
||||
CoreItemFactory.NUMBER);
|
||||
createChannel(CHANNEL_LOADPOINT_CHARGE_CURRENT, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_CHARGE_CURRENT,
|
||||
"Number:ElectricCurrent");
|
||||
createChannel(CHANNEL_LOADPOINT_CHARGE_DURATION, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_CHARGE_DURATION,
|
||||
"Number:Time");
|
||||
createChannel(CHANNEL_LOADPOINT_CHARGE_POWER, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_CHARGE_POWER,
|
||||
"Number:Power");
|
||||
createChannel(CHANNEL_LOADPOINT_CHARGE_REMAINING_DURATION, channelGroup,
|
||||
CHANNEL_TYPE_UID_LOADPOINT_CHARGE_REMAINING_DURATION, "Number:Time");
|
||||
createChannel(CHANNEL_LOADPOINT_CHARGE_REMAINING_ENERGY, channelGroup,
|
||||
CHANNEL_TYPE_UID_LOADPOINT_CHARGE_REMAINING_ENERGY, "Number:Energy");
|
||||
createChannel(CHANNEL_LOADPOINT_CHARGED_ENERGY, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_CHARGED_ENERGY,
|
||||
"Number:Energy");
|
||||
createChannel(CHANNEL_LOADPOINT_CHARGING, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_CHARGING,
|
||||
CoreItemFactory.SWITCH);
|
||||
createChannel(CHANNEL_LOADPOINT_CONNECTED, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_CONNECTED,
|
||||
CoreItemFactory.SWITCH);
|
||||
createChannel(CHANNEL_LOADPOINT_CONNECTED_DURATION, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_CONNECTED_DURATION,
|
||||
"Number:Time");
|
||||
createChannel(CHANNEL_LOADPOINT_ENABLED, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_ENABLED,
|
||||
CoreItemFactory.SWITCH);
|
||||
createChannel(CHANNEL_LOADPOINT_HAS_VEHICLE, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_HAS_VEHICLE,
|
||||
CoreItemFactory.SWITCH);
|
||||
createChannel(CHANNEL_LOADPOINT_MAX_CURRENT, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_MAX_CURRENT,
|
||||
"Number:ElectricCurrent");
|
||||
createChannel(CHANNEL_LOADPOINT_MIN_CURRENT, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_MIN_CURRENT,
|
||||
"Number:ElectricCurrent");
|
||||
createChannel(CHANNEL_LOADPOINT_MIN_SOC, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_MIN_SOC,
|
||||
"Number:Dimensionless");
|
||||
createChannel(CHANNEL_LOADPOINT_MODE, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_MODE, CoreItemFactory.STRING);
|
||||
createChannel(CHANNEL_LOADPOINT_PHASES, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_PHASES,
|
||||
CoreItemFactory.NUMBER);
|
||||
createChannel(CHANNEL_LOADPOINT_TARGET_SOC, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_TARGET_SOC,
|
||||
"Number:Dimensionless");
|
||||
createChannel(CHANNEL_LOADPOINT_TARGET_TIME, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_TARGET_TIME,
|
||||
CoreItemFactory.DATETIME);
|
||||
createChannel(CHANNEL_LOADPOINT_TARGET_TIME_ENABLED, channelGroup,
|
||||
CHANNEL_TYPE_UID_LOADPOINT_TARGET_TIME_ENABLED, CoreItemFactory.SWITCH);
|
||||
createChannel(CHANNEL_LOADPOINT_TITLE, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_TITLE, CoreItemFactory.STRING);
|
||||
createChannel(CHANNEL_LOADPOINT_VEHICLE_CAPACITY, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_CAPACITY,
|
||||
"Number:Energy");
|
||||
createChannel(CHANNEL_LOADPOINT_VEHICLE_ODOMETER, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_ODOMETER,
|
||||
"Number:Length");
|
||||
createChannel(CHANNEL_LOADPOINT_VEHICLE_PRESENT, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_PRESENT,
|
||||
CoreItemFactory.SWITCH);
|
||||
createChannel(CHANNEL_LOADPOINT_VEHICLE_RANGE, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_RANGE,
|
||||
"Number:Length");
|
||||
createChannel(CHANNEL_LOADPOINT_VEHICLE_SOC, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_SOC,
|
||||
"Number:Dimensionless");
|
||||
createChannel(CHANNEL_LOADPOINT_VEHICLE_TITLE, channelGroup, CHANNEL_TYPE_UID_LOADPOINT_VEHICLE_TITLE,
|
||||
CoreItemFactory.STRING);
|
||||
}
|
||||
|
||||
// Units and description for vars: https://docs.evcc.io/docs/reference/configuration/messaging/#msg
|
||||
private void updateChannelsGeneral() {
|
||||
Result result = this.result;
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
ChannelUID channel;
|
||||
boolean batteryConfigured = this.batteryConfigured;
|
||||
if (batteryConfigured) {
|
||||
double batteryPower = result.getBatteryPower();
|
||||
channel = new ChannelUID(getThing().getUID(), "general", CHANNEL_BATTERY_POWER);
|
||||
updateState(channel, new QuantityType<>(batteryPower, Units.WATT));
|
||||
int batterySoC = result.getBatterySoC();
|
||||
channel = new ChannelUID(getThing().getUID(), "general", CHANNEL_BATTERY_SOC);
|
||||
updateState(channel, new QuantityType<>(batterySoC, Units.PERCENT));
|
||||
int batteryPrioritySoC = result.getBatterySoC();
|
||||
channel = new ChannelUID(getThing().getUID(), "general", CHANNEL_BATTERY_PRIORITY_SOC);
|
||||
updateState(channel, new QuantityType<>(batteryPrioritySoC, Units.PERCENT));
|
||||
}
|
||||
boolean gridConfigured = this.gridConfigured;
|
||||
if (gridConfigured) {
|
||||
double gridPower = result.getGridPower();
|
||||
channel = new ChannelUID(getThing().getUID(), "general", CHANNEL_GRID_POWER);
|
||||
updateState(channel, new QuantityType<>(gridPower, Units.WATT));
|
||||
}
|
||||
double homePower = result.getHomePower();
|
||||
channel = new ChannelUID(getThing().getUID(), "general", CHANNEL_HOME_POWER);
|
||||
updateState(channel, new QuantityType<>(homePower, Units.WATT));
|
||||
boolean pvConfigured = this.pvConfigured;
|
||||
if (pvConfigured) {
|
||||
double pvPower = result.getPvPower();
|
||||
channel = new ChannelUID(getThing().getUID(), "general", CHANNEL_PV_POWER);
|
||||
updateState(channel, new QuantityType<>(pvPower, Units.WATT));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateChannelsLoadpoint(int loadpointId) {
|
||||
Result result = this.result;
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
String loadpointName = "loadpoint" + loadpointId;
|
||||
ChannelUID channel;
|
||||
Loadpoint loadpoint = result.getLoadpoints()[loadpointId];
|
||||
int activePhases = loadpoint.getActivePhases();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_ACTIVE_PHASES);
|
||||
updateState(channel, new DecimalType(activePhases));
|
||||
double chargeCurrent = loadpoint.getChargeCurrent();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_CHARGE_CURRENT);
|
||||
updateState(channel, new QuantityType<>(chargeCurrent, Units.AMPERE));
|
||||
long chargeDuration = loadpoint.getChargeDuration();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_CHARGE_DURATION);
|
||||
updateState(channel, new QuantityType<>(chargeDuration, MetricPrefix.NANO(Units.SECOND)));
|
||||
double chargePower = loadpoint.getChargePower();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_CHARGE_POWER);
|
||||
updateState(channel, new QuantityType<>(chargePower, Units.WATT));
|
||||
long chargeRemainingDuration = loadpoint.getChargeRemainingDuration();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_CHARGE_REMAINING_DURATION);
|
||||
updateState(channel, new QuantityType<>(chargeRemainingDuration, MetricPrefix.NANO(Units.SECOND)));
|
||||
double chargeRemainingEnergy = loadpoint.getChargeRemainingEnergy();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_CHARGE_REMAINING_ENERGY);
|
||||
updateState(channel, new QuantityType<>(chargeRemainingEnergy, Units.WATT_HOUR));
|
||||
double chargedEnergy = loadpoint.getChargedEnergy();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_CHARGED_ENERGY);
|
||||
updateState(channel, new QuantityType<>(chargedEnergy, Units.WATT_HOUR));
|
||||
boolean charging = loadpoint.getCharging();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_CHARGING);
|
||||
updateState(channel, OnOffType.from(charging));
|
||||
boolean connected = loadpoint.getConnected();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_CONNECTED);
|
||||
updateState(channel, OnOffType.from(connected));
|
||||
long connectedDuration = loadpoint.getConnectedDuration();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_CONNECTED_DURATION);
|
||||
updateState(channel, new QuantityType<>(connectedDuration, MetricPrefix.NANO(Units.SECOND)));
|
||||
boolean enabled = loadpoint.getEnabled();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_ENABLED);
|
||||
updateState(channel, OnOffType.from(enabled));
|
||||
boolean hasVehicle = loadpoint.getHasVehicle();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_HAS_VEHICLE);
|
||||
updateState(channel, OnOffType.from(hasVehicle));
|
||||
double maxCurrent = loadpoint.getMaxCurrent();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_MAX_CURRENT);
|
||||
updateState(channel, new QuantityType<>(maxCurrent, Units.AMPERE));
|
||||
double minCurrent = loadpoint.getMinCurrent();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_MIN_CURRENT);
|
||||
updateState(channel, new QuantityType<>(minCurrent, Units.AMPERE));
|
||||
int minSoC = loadpoint.getMinSoC();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_MIN_SOC);
|
||||
updateState(channel, new QuantityType<>(minSoC, Units.PERCENT));
|
||||
String mode = loadpoint.getMode();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_MODE);
|
||||
updateState(channel, new StringType(mode));
|
||||
int phases = loadpoint.getPhases();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_PHASES);
|
||||
updateState(channel, new DecimalType(phases));
|
||||
targetSoC = loadpoint.getTargetSoC();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_TARGET_SOC);
|
||||
updateState(channel, new QuantityType<>(targetSoC, Units.PERCENT));
|
||||
String targetTime = loadpoint.getTargetTime();
|
||||
if (targetTime == null) {
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_TARGET_TIME_ENABLED);
|
||||
updateState(channel, OnOffType.OFF);
|
||||
targetTimeEnabled = false;
|
||||
} else {
|
||||
this.targetTimeZDT = ZonedDateTime.parse(targetTime);
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_TARGET_TIME);
|
||||
updateState(channel, new DateTimeType(targetTimeZDT));
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_TARGET_TIME_ENABLED);
|
||||
updateState(channel, OnOffType.ON);
|
||||
targetTimeEnabled = true;
|
||||
}
|
||||
String title = loadpoint.getTitle();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_TITLE);
|
||||
updateState(channel, new StringType(title));
|
||||
double vehicleCapacity = loadpoint.getVehicleCapacity();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_VEHICLE_CAPACITY);
|
||||
updateState(channel, new QuantityType<>(vehicleCapacity, Units.WATT_HOUR));
|
||||
double vehicleOdometer = loadpoint.getVehicleOdometer();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_VEHICLE_ODOMETER);
|
||||
updateState(channel, new QuantityType<>(vehicleOdometer, MetricPrefix.KILO(SIUnits.METRE)));
|
||||
boolean vehiclePresent = loadpoint.getVehiclePresent();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_VEHICLE_PRESENT);
|
||||
updateState(channel, OnOffType.from(vehiclePresent));
|
||||
long vehicleRange = loadpoint.getVehicleRange();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_VEHICLE_RANGE);
|
||||
updateState(channel, new QuantityType<>(vehicleRange, MetricPrefix.KILO(SIUnits.METRE)));
|
||||
int vehicleSoC = loadpoint.getVehicleSoC();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_VEHICLE_SOC);
|
||||
updateState(channel, new QuantityType<>(vehicleSoC, Units.PERCENT));
|
||||
String vehicleTitle = loadpoint.getVehicleTitle();
|
||||
channel = new ChannelUID(getThing().getUID(), loadpointName, CHANNEL_LOADPOINT_VEHICLE_TITLE);
|
||||
updateState(channel, new StringType(vehicleTitle));
|
||||
}
|
||||
|
||||
private void createChannel(String channel, String channelGroupId, ChannelTypeUID channelTypeUID, String itemType) {
|
||||
ChannelUID channelToCheck = new ChannelUID(thing.getUID(), channelGroupId, channel);
|
||||
if (thing.getChannel(channelToCheck) == null) {
|
||||
ThingBuilder thingBuilder = editThing();
|
||||
Channel testchannel = ChannelBuilder
|
||||
.create(new ChannelUID(getThing().getUID(), channelGroupId, channel), itemType)
|
||||
.withType(channelTypeUID).build();
|
||||
thingBuilder.withChannel(testchannel);
|
||||
updateThing(thingBuilder.build());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2022 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;
|
||||
|
||||
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.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.osgi.service.component.annotations.Component;
|
||||
|
||||
/**
|
||||
* The {@link EvccHandlerFactory} is responsible for creating things and thing
|
||||
* handlers.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
@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);
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
if (THING_TYPE_DEVICE.equals(thingTypeUID)) {
|
||||
return new EvccHandler(thing);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2022 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.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.evcc.internal.api.dto.Result;
|
||||
import org.openhab.binding.evcc.internal.api.dto.Status;
|
||||
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.JsonSyntaxException;
|
||||
|
||||
/**
|
||||
* The {@link EvccAPI} is responsible for API calls to evcc.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EvccAPI {
|
||||
private final Logger logger = LoggerFactory.getLogger(EvccAPI.class);
|
||||
private final Gson gson = new Gson();
|
||||
private String host = "";
|
||||
|
||||
public EvccAPI(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a HTTP request.
|
||||
*
|
||||
* @param url full request URL
|
||||
* @param method reguest method, e.g. GET, POST
|
||||
* @return the response body
|
||||
* @throws {@link 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.
|
||||
*
|
||||
* @param host hostname of IP address of the evcc instance
|
||||
* @return {@link Result} result object from API
|
||||
* @throws {@link EvccApiException} if status request failed
|
||||
*/
|
||||
public Result getResult() throws EvccApiException {
|
||||
final String response = httpRequest(this.host + EVCC_REST_API + "state", "GET");
|
||||
try {
|
||||
Status status = gson.fromJson(response, Status.class);
|
||||
if (status == null) {
|
||||
throw new EvccApiException("Status is null");
|
||||
}
|
||||
return status.getResult();
|
||||
} catch (JsonSyntaxException e) {
|
||||
throw new EvccApiException("Error parsing response: " + response, e);
|
||||
}
|
||||
}
|
||||
|
||||
// Loadpoint specific API calls.
|
||||
public String setMode(int loadpoint, String mode) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/mode/" + mode, "POST");
|
||||
}
|
||||
|
||||
public String setMinSoC(int loadpoint, int minSoC) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/minsoc/" + minSoC, "POST");
|
||||
}
|
||||
|
||||
public String setTargetSoC(int loadpoint, int targetSoC) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/targetsoc/" + targetSoC, "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");
|
||||
}
|
||||
|
||||
public String setTargetCharge(int loadpoint, int targetSoC, ZonedDateTime targetTime) throws EvccApiException {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
|
||||
return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/targetcharge/" + targetSoC + "/"
|
||||
+ targetTime.toLocalDateTime().format(formatter), "POST");
|
||||
}
|
||||
|
||||
public String unsetTargetCharge(int loadpoint) throws EvccApiException {
|
||||
return httpRequest(this.host + EVCC_REST_API + "loadpoints/" + loadpoint + "/targetcharge", "DELETE");
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2022 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);
|
||||
}
|
||||
}
|
@ -0,0 +1,316 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2022 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.91.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
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("activePhases")
|
||||
private int activePhases;
|
||||
|
||||
@SerializedName("chargeCurrent")
|
||||
private double chargeCurrent;
|
||||
|
||||
@SerializedName("chargeDuration")
|
||||
private long chargeDuration;
|
||||
|
||||
@SerializedName("chargePower")
|
||||
private double chargePower;
|
||||
|
||||
@SerializedName("chargeRemainingDuration")
|
||||
private long chargeRemainingDuration;
|
||||
|
||||
@SerializedName("chargeRemainingEnergy")
|
||||
private double chargeRemainingEnergy;
|
||||
|
||||
@SerializedName("chargedEnergy")
|
||||
private double chargedEnergy;
|
||||
|
||||
@SerializedName("charging")
|
||||
private boolean charging;
|
||||
|
||||
@SerializedName("connected")
|
||||
private boolean connected;
|
||||
|
||||
@SerializedName("connectedDuration")
|
||||
private long connectedDuration;
|
||||
|
||||
@SerializedName("enabled")
|
||||
private boolean enabled;
|
||||
|
||||
@SerializedName("hasVehicle")
|
||||
private boolean hasVehicle;
|
||||
|
||||
@SerializedName("loadpoint")
|
||||
private int loadpoint;
|
||||
|
||||
@SerializedName("maxCurrent")
|
||||
private double maxCurrent;
|
||||
|
||||
@SerializedName("minCurrent")
|
||||
private double minCurrent;
|
||||
|
||||
@SerializedName("minSoC")
|
||||
private int minSoC;
|
||||
|
||||
@SerializedName("mode")
|
||||
private String mode;
|
||||
|
||||
@SerializedName("phases")
|
||||
private int phases;
|
||||
|
||||
@SerializedName("pvAction")
|
||||
private String pvAction;
|
||||
|
||||
@SerializedName("pvRemaining")
|
||||
private long pvRemaining;
|
||||
|
||||
@SerializedName("targetSoC")
|
||||
private int targetSoC;
|
||||
|
||||
@SerializedName("targetTime")
|
||||
private String targetTime;
|
||||
|
||||
@SerializedName("title")
|
||||
private String title;
|
||||
|
||||
@SerializedName("vehicleCapacity")
|
||||
private long vehicleCapacity;
|
||||
|
||||
@SerializedName("vehicleOdometer")
|
||||
private double vehicleOdometer;
|
||||
|
||||
@SerializedName("vehiclePresent")
|
||||
private boolean vehiclePresent;
|
||||
|
||||
@SerializedName("vehicleRange")
|
||||
private long vehicleRange;
|
||||
|
||||
@SerializedName("vehicleSoC")
|
||||
private int vehicleSoC;
|
||||
|
||||
@SerializedName("vehicleTitle")
|
||||
private String vehicleTitle;
|
||||
|
||||
/**
|
||||
* @return number of active phases
|
||||
*/
|
||||
public int getActivePhases() {
|
||||
return activePhases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return charge current
|
||||
*/
|
||||
public double getChargeCurrent() {
|
||||
return chargeCurrent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return charge duration
|
||||
*/
|
||||
public long getChargeDuration() {
|
||||
return chargeDuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return charge power
|
||||
*/
|
||||
public double 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 double getChargeRemainingEnergy() {
|
||||
return chargeRemainingEnergy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return charged energy
|
||||
*/
|
||||
public double 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 whether vehicle is configured for loadpoint
|
||||
*/
|
||||
public boolean getHasVehicle() {
|
||||
return hasVehicle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return loadpoint id
|
||||
*/
|
||||
public int getLoadpoint() {
|
||||
return loadpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return maximum current
|
||||
*/
|
||||
public double getMaxCurrent() {
|
||||
return maxCurrent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return minimum current
|
||||
*/
|
||||
public double getMinCurrent() {
|
||||
return minCurrent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return minimum state of charge
|
||||
*/
|
||||
public int getMinSoC() {
|
||||
return minSoC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return charging mode: off, now, minpv, pv
|
||||
*/
|
||||
public String getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of enabled phases
|
||||
*/
|
||||
public int getPhases() {
|
||||
return phases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the pv action
|
||||
*/
|
||||
public String getPvAction() {
|
||||
return pvAction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the pv remaining
|
||||
*/
|
||||
public long getPvRemaining() {
|
||||
return pvRemaining;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return target state of charge (SoC)
|
||||
*/
|
||||
public int getTargetSoC() {
|
||||
return targetSoC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 capacity
|
||||
*/
|
||||
public double getVehicleCapacity() {
|
||||
return vehicleCapacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return vehicle's odometer
|
||||
*/
|
||||
public double getVehicleOdometer() {
|
||||
return vehicleOdometer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether evcc is able to get data from vehicle
|
||||
*/
|
||||
public boolean getVehiclePresent() {
|
||||
return vehiclePresent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return vehicle's range
|
||||
*/
|
||||
public long getVehicleRange() {
|
||||
return vehicleRange;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return vehicle's state of charge (SoC)
|
||||
*/
|
||||
public int getVehicleSoC() {
|
||||
return vehicleSoC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return vehicle's title/name
|
||||
*/
|
||||
public String getVehicleTitle() {
|
||||
return vehicleTitle;
|
||||
}
|
||||
}
|
@ -0,0 +1,140 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2022 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 result object of the status response (/api/state).
|
||||
* This DTO was written for evcc version 0.91.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
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
|
||||
|
||||
// TO DO LATER
|
||||
// @SerializedName("auth")
|
||||
// private Auth auth;
|
||||
|
||||
@SerializedName("batteryConfigured")
|
||||
private boolean batteryConfigured;
|
||||
|
||||
@SerializedName("batteryPower")
|
||||
private double batteryPower;
|
||||
|
||||
@SerializedName("batterySoC")
|
||||
private int batterySoC;
|
||||
|
||||
@SerializedName("gridConfigured")
|
||||
private boolean gridConfigured;
|
||||
|
||||
@SerializedName("gridPower")
|
||||
private double gridPower;
|
||||
|
||||
@SerializedName("homePower")
|
||||
private double homePower;
|
||||
|
||||
@SerializedName("loadpoints")
|
||||
private Loadpoint[] loadpoints;
|
||||
|
||||
@SerializedName("prioritySoC")
|
||||
private double batteryPrioritySoC;
|
||||
|
||||
@SerializedName("pvConfigured")
|
||||
private boolean pvConfigured;
|
||||
|
||||
@SerializedName("pvPower")
|
||||
private double pvPower;
|
||||
|
||||
@SerializedName("siteTitle")
|
||||
private String siteTitle;
|
||||
|
||||
/**
|
||||
* @return whether battery is configured
|
||||
*/
|
||||
public boolean getBatteryConfigured() {
|
||||
return batteryConfigured;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return battery's power
|
||||
*/
|
||||
public double getBatteryPower() {
|
||||
return batteryPower;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return battery's priority state of charge
|
||||
*/
|
||||
public double getBatteryPrioritySoC() {
|
||||
return batteryPrioritySoC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return battery's state of charge
|
||||
*/
|
||||
public int getBatterySoC() {
|
||||
return batterySoC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether grid is configured
|
||||
*/
|
||||
public boolean getGridConfigured() {
|
||||
return gridConfigured;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return grid's power
|
||||
*/
|
||||
public double getGridPower() {
|
||||
return gridPower;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return home's power
|
||||
*/
|
||||
public double getHomePower() {
|
||||
return homePower;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return all configured loadpoints
|
||||
*/
|
||||
public Loadpoint[] getLoadpoints() {
|
||||
return loadpoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether pv is configured
|
||||
*/
|
||||
public boolean getPvConfigured() {
|
||||
return pvConfigured;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pv's power
|
||||
*/
|
||||
public double getPvPower() {
|
||||
return pvPower;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return site's title/name
|
||||
*/
|
||||
public String getSiteTitle() {
|
||||
return siteTitle;
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2022 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.91.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
public class Status {
|
||||
|
||||
@SerializedName("result")
|
||||
private Result result;
|
||||
|
||||
public Result getResult() {
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding id="evcc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
|
||||
|
||||
<name>evcc Binding</name>
|
||||
<description>This is the binding for evcc (electric vehicle charging control) - soak up the sun.</description>
|
||||
|
||||
</binding:binding>
|
@ -0,0 +1,111 @@
|
||||
# binding
|
||||
|
||||
binding.evcc.name = evcc Binding
|
||||
binding.evcc.description = This is the binding for evcc (electric vehicle charging control) - soak up the sun.
|
||||
|
||||
# thing types
|
||||
|
||||
thing-type.evcc.device.label = evcc installation
|
||||
thing-type.evcc.device.description = A running evcc installation
|
||||
|
||||
# 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
|
||||
|
||||
# channel group types
|
||||
|
||||
channel-group-type.evcc.general.label = General data
|
||||
channel-group-type.evcc.loadpoint.label = Loadpoint
|
||||
|
||||
# channel types
|
||||
|
||||
channel-type.evcc.activePhases.label = Charging active phases
|
||||
channel-type.evcc.activePhases.description = Current number of active phases while charging
|
||||
channel-type.evcc.batteryPower.label = Battery Power
|
||||
channel-type.evcc.batteryPower.description = Current power from battery
|
||||
channel-type.evcc.batteryPrioritySoC.label = Battery Priority SoC
|
||||
channel-type.evcc.batteryPrioritySoC.description = State of Charge for which the battery has priority over charging the ev when charging mode is "pv".
|
||||
channel-type.evcc.batterySoC.label = Battery SoC
|
||||
channel-type.evcc.batterySoC.description = Current State of Charge of battery
|
||||
channel-type.evcc.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 target SoC is reached
|
||||
channel-type.evcc.chargeRemainingEnergy.label = Charging remaining energy
|
||||
channel-type.evcc.chargeRemainingEnergy.description = Remaining energy until target SoC is reached
|
||||
channel-type.evcc.chargedEnergy.label = Charged energy
|
||||
channel-type.evcc.chargedEnergy.description = Energy charged since plugged-in
|
||||
channel-type.evcc.charging.label = Charging state
|
||||
channel-type.evcc.charging.description = Loadpoint is currently charging
|
||||
channel-type.evcc.charging.state.option.ON = Charging
|
||||
channel-type.evcc.charging.state.option.OFF = Not charging
|
||||
channel-type.evcc.enabled.label = Charging enabled
|
||||
channel-type.evcc.enabled.description = Charging enabled (mode not "off")
|
||||
channel-type.evcc.enabled.state.option.ON = Enabled
|
||||
channel-type.evcc.enabled.state.option.OFF = Disabled
|
||||
channel-type.evcc.gridPower.label = Grid Power
|
||||
channel-type.evcc.gridPower.description = Current power from grid (negative means feed-in)
|
||||
channel-type.evcc.hasVehicle.label = Loadpoint has vehicle configuration
|
||||
channel-type.evcc.hasVehicle.description = Whether vehicle is configured for loadpoint
|
||||
channel-type.evcc.hasVehicle.state.option.ON = Configured
|
||||
channel-type.evcc.hasVehicle.state.option.OFF = Not configured
|
||||
channel-type.evcc.homePower.label = Home Power
|
||||
channel-type.evcc.homePower.description = Current power taken by home
|
||||
channel-type.evcc.maxCurrent.label = Charging max current
|
||||
channel-type.evcc.maxCurrent.description = Maximum amperage per connected phase with which the car should be charged
|
||||
channel-type.evcc.minCurrent.label = Charging min current
|
||||
channel-type.evcc.minCurrent.description = Minimum amperage per connected phase with which the car should be charged
|
||||
channel-type.evcc.minSoC.label = Charging min SoC
|
||||
channel-type.evcc.minSoC.description = Charge immediately with maximum power up to the defined SoC, if the charge mode is not set to "off"
|
||||
channel-type.evcc.mode.label = Charging mode
|
||||
channel-type.evcc.mode.description = Charging mode: "off", "now", "minpv", "pv"
|
||||
channel-type.evcc.mode.state.option.off = Off
|
||||
channel-type.evcc.mode.state.option.now = Now
|
||||
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.pvPower.label = PV Power
|
||||
channel-type.evcc.pvPower.description = Current power from photovoltaik
|
||||
channel-type.evcc.targetSoC.label = Charging target SoC
|
||||
channel-type.evcc.targetSoC.description = Until which state of charge (SoC) should the vehicle be charged
|
||||
channel-type.evcc.targetTime.label = Charging target time
|
||||
channel-type.evcc.targetTime.description = When the target SoC should be reached
|
||||
channel-type.evcc.targetTimeEnabled.label = Charging target time enabled
|
||||
channel-type.evcc.targetTimeEnabled.description = Target time for charging enabled
|
||||
channel-type.evcc.targetTimeEnabled.state.option.ON = Enabled
|
||||
channel-type.evcc.targetTimeEnabled.state.option.OFF = Disabled
|
||||
channel-type.evcc.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.vehicleOdometer.label = Vehicle odometer
|
||||
channel-type.evcc.vehicleOdometer.description = Total distance travelled by EV
|
||||
channel-type.evcc.vehiclePresent.label = Vehicle data access
|
||||
channel-type.evcc.vehiclePresent.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.vehicleTitle.label = Vehicle title
|
||||
channel-type.evcc.vehicleTitle.description = Name of EV
|
||||
|
||||
# channel types
|
||||
|
||||
offline.configuration-error.no-host = No host configured
|
||||
offline.communication-error.request-failed = Request failed
|
@ -0,0 +1,111 @@
|
||||
# binding
|
||||
|
||||
binding.evcc.name = evcc Binding
|
||||
binding.evcc.description = Dies ist das Binding für evcc (electric vehicle charging control) - Sonne tanken.
|
||||
|
||||
# thing types
|
||||
|
||||
thing-type.evcc.device.label = evcc Installation
|
||||
thing-type.evcc.device.description = Eine aktive evcc Installation.
|
||||
|
||||
# thing types config
|
||||
|
||||
thing-type.config.evcc.device.refreshInterval.label = Aktualisierungs-Interval
|
||||
thing-type.config.evcc.device.refreshInterval.description = Interval in Sekunden, in dem der Status abgerufen wird
|
||||
thing-type.config.evcc.device.url.label = URL
|
||||
thing-type.config.evcc.device.url.description = URL der evcc Web-Oberfläche, z.B. https://demo.evcc.io
|
||||
|
||||
# channel group types
|
||||
|
||||
channel-group-type.evcc.general.label = Generelle Daten
|
||||
channel-group-type.evcc.loadpoint.label = Ladepunkt
|
||||
|
||||
# channel types
|
||||
|
||||
channel-type.evcc.activePhases.label = Laden aktive Phasen
|
||||
channel-type.evcc.activePhases.description = Anzahl von Phasen, die beim Laden aktiv sind
|
||||
channel-type.evcc.batteryPower.label = Batterie Leistung
|
||||
channel-type.evcc.batteryPower.description = Aktuelle Leistung der Batterie
|
||||
channel-type.evcc.batteryPrioritySoC.label = Batterie Priorität-Ladestand
|
||||
channel-type.evcc.batteryPrioritySoC.description = Mindest-Ladestand der Batterie, unter dem die Batterie Priorität vor PV-Laden hat
|
||||
channel-type.evcc.batterySoC.label = Batterie Ladestand
|
||||
channel-type.evcc.batterySoC.description = Aktueller Ladestand der Batterie
|
||||
channel-type.evcc.chargeCurrent.label = Ladestromstärke
|
||||
channel-type.evcc.chargeCurrent.description = Aktuelle Stromstärke je Phases beim Laden
|
||||
channel-type.evcc.chargeDuration.label = Ladedauer
|
||||
channel-type.evcc.chargeDuration.description = Bisherige Ladedauer
|
||||
channel-type.evcc.chargePower.label = Ladeleistung
|
||||
channel-type.evcc.chargePower.description = Aktuelle Ladeleistung
|
||||
channel-type.evcc.chargeRemainingDuration.label = Verbleibende Ladedauer
|
||||
channel-type.evcc.chargeRemainingDuration.description = Verbleibende Dauer bis der Ziel-Füllstand erreicht ist
|
||||
channel-type.evcc.chargeRemainingEnergy.label = Verbleinbende Ladeenergie
|
||||
channel-type.evcc.chargeRemainingEnergy.description = Verbleibende Energie bis der Ziel-Füllstand erreicht ist
|
||||
channel-type.evcc.chargedEnergy.label = Geladene Energie
|
||||
channel-type.evcc.chargedEnergy.description = Geladene Energie seit das Fahrzeug angeschlossen ist
|
||||
channel-type.evcc.charging.label = Ladestatus
|
||||
channel-type.evcc.charging.description = Status Ladepunkt
|
||||
channel-type.evcc.charging.state.option.ON = Laden
|
||||
channel-type.evcc.charging.state.option.OFF = Nicht laden
|
||||
channel-type.evcc.enabled.label = Status Laden
|
||||
channel-type.evcc.enabled.description = Laden ist freigeschaltet/aktiviert (Modus ist nicht "off")
|
||||
channel-type.evcc.enabled.state.option.ON = Aktiviert
|
||||
channel-type.evcc.enabled.state.option.OFF = Deaktiviert
|
||||
channel-type.evcc.gridPower.label = Netzleistung
|
||||
channel-type.evcc.gridPower.description = Aktuelle Leistung vom Stromnetz (negativer Wert means bedeutet Einspeisung)
|
||||
channel-type.evcc.hasVehicle.label = Fahrzeug konfiguriert
|
||||
channel-type.evcc.hasVehicle.description = Fahrzeug ist für Ladepunkt konfiguriert
|
||||
channel-type.evcc.hasVehicle.state.option.ON = Konfiguriert
|
||||
channel-type.evcc.hasVehicle.state.option.OFF = Nicht konfiguriert
|
||||
channel-type.evcc.homePower.label = Leistungaufnahme Gebäude
|
||||
channel-type.evcc.homePower.description = Aktuelle Leistungsaufnahme des Gebäudes
|
||||
channel-type.evcc.maxCurrent.label = Laden maximale Stromstärke
|
||||
channel-type.evcc.maxCurrent.description = Maximale Stromstärke je Phases mit der das Auto geladen werden soll
|
||||
channel-type.evcc.minCurrent.label = Laden minimale Stromstärke
|
||||
channel-type.evcc.minCurrent.description = Minimale Stromstärke je Phases mit der das Auto geladen werden soll
|
||||
channel-type.evcc.minSoC.label = Minimaler Ladestand Fahrzeug
|
||||
channel-type.evcc.minSoC.description = Sofortiges Laden zu diesem Ladestand, wenn der Lademodus nicht "off" ist
|
||||
channel-type.evcc.mode.label = Lademodus
|
||||
channel-type.evcc.mode.description = Lademodus: "off", "now", "minpv", "pv"
|
||||
channel-type.evcc.mode.state.option.off = Aus
|
||||
channel-type.evcc.mode.state.option.now = Sofort
|
||||
channel-type.evcc.mode.state.option.minpv = Min. + PV
|
||||
channel-type.evcc.mode.state.option.pv = Nur PV
|
||||
channel-type.evcc.phases.label = Laden aktivierte Phasen
|
||||
channel-type.evcc.phases.description = Die maximale Anzahl an nutzbaren Phasen
|
||||
channel-type.evcc.pvPower.label = Solar Leistung
|
||||
channel-type.evcc.pvPower.description = Aktuelle Leistung von der Solar-Anlage
|
||||
channel-type.evcc.targetSoC.label = Ziel-Ladestand
|
||||
channel-type.evcc.targetSoC.description = Bis zu welchem Ladestand das Fahrzeug geladen werden soll
|
||||
channel-type.evcc.targetTime.label = Laden Ziel-Zeit
|
||||
channel-type.evcc.targetTime.description = Wann der Ziel-Ladestand erreicht werden soll
|
||||
channel-type.evcc.targetTimeEnabled.label = Laden Ziel-Zeit aktiviert
|
||||
channel-type.evcc.targetTimeEnabled.description = Ziel-Zeit für das Laden aktiviert
|
||||
channel-type.evcc.targetTimeEnabled.state.option.ON = aktiviert
|
||||
channel-type.evcc.targetTimeEnabled.state.option.OFF = deaktiviert
|
||||
channel-type.evcc.title.label = Ladepunkt Name
|
||||
channel-type.evcc.title.description = Name des Ladepunkts
|
||||
channel-type.evcc.vehicleCapacity.label = Fahrzeug Kapazität
|
||||
channel-type.evcc.vehicleCapacity.description = Kapazität der Fahrzeug-Batterie
|
||||
channel-type.evcc.vehicleConnected.label = Fahrzeug verbunden
|
||||
channel-type.evcc.vehicleConnected.description = Ob ein Fahrzeug mit dem Ladepunkt verbunden ist
|
||||
channel-type.evcc.vehicleConnected.state.option.ON = Verbunden
|
||||
channel-type.evcc.vehicleConnected.state.option.OFF = Nicht verbunden
|
||||
channel-type.evcc.vehicleConnectedDuration.label = Dauer Fahrzeug verbunden
|
||||
channel-type.evcc.vehicleConnectedDuration.description = Dauer seit der das Fahrzeug mit dem Ladepunkt verbunden ist
|
||||
channel-type.evcc.vehicleOdometer.label = Fahrzeug Kilometer-Zähler
|
||||
channel-type.evcc.vehicleOdometer.description = Gesamtstrecke die vom Fahrzeug zurückgelegt wurde
|
||||
channel-type.evcc.vehiclePresent.label = Fahrzeug Daten-Zugriff
|
||||
channel-type.evcc.vehiclePresent.description = Ob evcc auf die Fahrzeug-Daten zugreifen kann
|
||||
channel-type.evcc.vehiclePresent.state.option.ON = Daten-Zugriff
|
||||
channel-type.evcc.vehiclePresent.state.option.OFF = Kein Daten-Zugriff
|
||||
channel-type.evcc.vehicleRange.label = Fahrzeug Reichweite
|
||||
channel-type.evcc.vehicleRange.description = Fahrzeug-Batterie Reichweite
|
||||
channel-type.evcc.vehicleSoC.label = Fahrzeug Ladestand
|
||||
channel-type.evcc.vehicleSoC.description = Aktueller Ladestand der Fahrzeug-Batterie
|
||||
channel-type.evcc.vehicleTitle.label = Fahrzeug Name
|
||||
channel-type.evcc.vehicleTitle.description = Name des Fahrzeugs
|
||||
|
||||
# channel types
|
||||
|
||||
offline.configuration-error.no-host = Kein Host konfiguriert
|
||||
offline.communication-error.request-failed = Anfrage fehlgeschlagen
|
@ -0,0 +1,327 @@
|
||||
<?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>
|
||||
|
||||
<channel-groups>
|
||||
<channel-group id="general" typeId="general"/>
|
||||
<channel-group id="loadpoint0" typeId="loadpoint"/>
|
||||
<channel-group id="loadpoint1" typeId="loadpoint"/>
|
||||
<channel-group id="loadpoint2" typeId="loadpoint"/>
|
||||
<channel-group id="loadpoint3" typeId="loadpoint"/>
|
||||
<channel-group id="loadpoint4" typeId="loadpoint"/>
|
||||
<channel-group id="loadpoint5" typeId="loadpoint"/>
|
||||
<channel-group id="loadpoint6" typeId="loadpoint"/>
|
||||
<channel-group id="loadpoint7" typeId="loadpoint"/>
|
||||
<channel-group id="loadpoint8" typeId="loadpoint"/>
|
||||
<channel-group id="loadpoint9" typeId="loadpoint"/>
|
||||
</channel-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="loadpoint">
|
||||
<label>Loadpoint</label>
|
||||
</channel-group-type>
|
||||
|
||||
<!-- Units and description on: https://docs.evcc.io/docs/reference/configuration/messaging/#msg -->
|
||||
<channel-type id="batteryPower">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Battery Power</label>
|
||||
<description>Current power from battery</description>
|
||||
<category>Energy</category>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="batterySoC">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Battery SoC</label>
|
||||
<description>Current State of Charge of battery</description>
|
||||
<category>batterylevel</category>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="batteryPrioritySoC">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Battery Priority SoC</label>
|
||||
<description>State of Charge for which the battery has priority over charging the ev when charging mode is "pv".</description>
|
||||
<category>batterylevel</category>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</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>
|
||||
<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>
|
||||
<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>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<!-- Channels 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>
|
||||
<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>
|
||||
<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>
|
||||
<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 target SoC is reached</description>
|
||||
<category>Time</category>
|
||||
<state pattern="%.1f min" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="chargeRemainingEnergy">
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>Charging remaining energy</label>
|
||||
<description>Remaining energy until target SoC is reached</description>
|
||||
<category>Energy</category>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="chargedEnergy">
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>Charged energy</label>
|
||||
<description>Energy charged since plugged-in</description>
|
||||
<category>Energy</category>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="charging">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Charging state</label>
|
||||
<description>Loadpoint is currently charging</description>
|
||||
<category>Energy</category>
|
||||
<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>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">Enabled</option>
|
||||
<option value="OFF">Disabled</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="hasVehicle">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Loadpoint has vehicle configuration</label>
|
||||
<description>Whether vehicle is configured for loadpoint</description>
|
||||
<category>Switch</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="ON">Configured</option>
|
||||
<option value="OFF">Not configured</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="maxCurrent">
|
||||
<item-type>Number:ElectricCurrent</item-type>
|
||||
<label>Charging max current</label>
|
||||
<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="minSoC">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Charging min SoC</label>
|
||||
<description>Charge immediately with maximum power up to the defined SoC, if the charge mode is not set to "off"</description>
|
||||
<category>Batterylevel</category>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="mode">
|
||||
<item-type>String</item-type>
|
||||
<label>Charging mode</label>
|
||||
<description>Charging mode: "off", "now", "minpv", "pv"</description>
|
||||
<category>String</category>
|
||||
<state readOnly="false">
|
||||
<options>
|
||||
<option value="off">Off</option>
|
||||
<option value="now">Now</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="targetSoC">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Charging target SoC</label>
|
||||
<description>Until which state of charge (SoC) should the vehicle be charged</description>
|
||||
<category>Batterylevel</category>
|
||||
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="targetTime">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>Charging target time</label>
|
||||
<description>When the target SoC should be reached</description>
|
||||
<category>Time</category>
|
||||
<state readOnly="false"/>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="targetTimeEnabled">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Charging target time enabled</label>
|
||||
<description>Target time for charging enabled</description>
|
||||
<category>Switch</category>
|
||||
<state readOnly="false">
|
||||
<options>
|
||||
<option value="ON">Enabled</option>
|
||||
<option value="OFF">Disabled</option>
|
||||
</options>
|
||||
</state>
|
||||
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
<channel-type id="title">
|
||||
<item-type>String</item-type>
|
||||
<label>Loadpoint title</label>
|
||||
<description>Title of loadpoint</description>
|
||||
<category>Text</category>
|
||||
<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>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="vehicleCapacity">
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>Vehicle capacity</label>
|
||||
<description>Capacity of EV battery</description>
|
||||
<category>Energy</category>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="vehicleOdometer">
|
||||
<item-type>Number:Length</item-type>
|
||||
<label>Vehicle odometer</label>
|
||||
<description>Total distance travelled by EV</description>
|
||||
<category></category>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="vehiclePresent">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Vehicle data access</label>
|
||||
<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>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="vehicleSoC">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Vehicle SoC</label>
|
||||
<description>Current State of Charge of EV</description>
|
||||
<category>Batterylevel</category>
|
||||
<state pattern="%.0f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="vehicleTitle">
|
||||
<item-type>String</item-type>
|
||||
<label>Vehicle title</label>
|
||||
<description>Name of EV</description>
|
||||
<category>Text</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
@ -122,6 +122,7 @@
|
||||
<module>org.openhab.binding.enturno</module>
|
||||
<module>org.openhab.binding.epsonprojector</module>
|
||||
<module>org.openhab.binding.etherrain</module>
|
||||
<module>org.openhab.binding.evcc</module>
|
||||
<module>org.openhab.binding.evohome</module>
|
||||
<module>org.openhab.binding.exec</module>
|
||||
<module>org.openhab.binding.feed</module>
|
||||
|
Loading…
Reference in New Issue
Block a user