mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-25 14:55:55 +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.enturno/ @klocsson
|
||||||
/bundles/org.openhab.binding.epsonprojector/ @mlobstein
|
/bundles/org.openhab.binding.epsonprojector/ @mlobstein
|
||||||
/bundles/org.openhab.binding.etherrain/ @dfad1469
|
/bundles/org.openhab.binding.etherrain/ @dfad1469
|
||||||
|
/bundles/org.openhab.binding.evcc/ @florian-h05
|
||||||
/bundles/org.openhab.binding.evohome/ @Nebula83
|
/bundles/org.openhab.binding.evohome/ @Nebula83
|
||||||
/bundles/org.openhab.binding.exec/ @kgoderis
|
/bundles/org.openhab.binding.exec/ @kgoderis
|
||||||
/bundles/org.openhab.binding.feed/ @svilenvul
|
/bundles/org.openhab.binding.feed/ @svilenvul
|
||||||
|
@ -441,6 +441,11 @@
|
|||||||
<artifactId>org.openhab.binding.etherrain</artifactId>
|
<artifactId>org.openhab.binding.etherrain</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openhab.addons.bundles</groupId>
|
||||||
|
<artifactId>org.openhab.binding.evcc</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.openhab.addons.bundles</groupId>
|
<groupId>org.openhab.addons.bundles</groupId>
|
||||||
<artifactId>org.openhab.binding.evohome</artifactId>
|
<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.enturno</module>
|
||||||
<module>org.openhab.binding.epsonprojector</module>
|
<module>org.openhab.binding.epsonprojector</module>
|
||||||
<module>org.openhab.binding.etherrain</module>
|
<module>org.openhab.binding.etherrain</module>
|
||||||
|
<module>org.openhab.binding.evcc</module>
|
||||||
<module>org.openhab.binding.evohome</module>
|
<module>org.openhab.binding.evohome</module>
|
||||||
<module>org.openhab.binding.exec</module>
|
<module>org.openhab.binding.exec</module>
|
||||||
<module>org.openhab.binding.feed</module>
|
<module>org.openhab.binding.feed</module>
|
||||||
|
Loading…
Reference in New Issue
Block a user