diff --git a/CODEOWNERS b/CODEOWNERS
index 58bea85272771..403c77efe527e 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -66,6 +66,7 @@
/bundles/org.openhab.binding.dwdpollenflug/ @DerOetzi
/bundles/org.openhab.binding.dwdunwetter/ @limdul79
/bundles/org.openhab.binding.ecobee/ @mhilbush
+/bundles/org.openhab.binding.ecotouch/ @sibbi77
/bundles/org.openhab.binding.elerotransmitterstick/ @vbier
/bundles/org.openhab.binding.energenie/ @hmerk
/bundles/org.openhab.binding.enigma2/ @gdolfen
diff --git a/bom/openhab-addons/pom.xml b/bom/openhab-addons/pom.xml
index ae1c023e9c0ad..0037c5b9d5325 100644
--- a/bom/openhab-addons/pom.xml
+++ b/bom/openhab-addons/pom.xml
@@ -316,6 +316,11 @@
org.openhab.binding.ecobee
${project.version}
+
+ org.openhab.addons.bundles
+ org.openhab.binding.ecotouch
+ ${project.version}
+
org.openhab.addons.bundles
org.openhab.binding.elerotransmitterstick
diff --git a/bundles/org.openhab.binding.ecotouch/NOTICE b/bundles/org.openhab.binding.ecotouch/NOTICE
new file mode 100644
index 0000000000000..38d625e349232
--- /dev/null
+++ b/bundles/org.openhab.binding.ecotouch/NOTICE
@@ -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
diff --git a/bundles/org.openhab.binding.ecotouch/README.md b/bundles/org.openhab.binding.ecotouch/README.md
new file mode 100644
index 0000000000000..2050f4ae66143
--- /dev/null
+++ b/bundles/org.openhab.binding.ecotouch/README.md
@@ -0,0 +1,200 @@
+# EcoTouch Binding
+
+The openHAB EcoTouch binding allows interaction with a [Waterkotte](https://www.waterkotte.de/) heat pump.
+
+## Supported Things
+
+| Thing type | Description |
+|-----------------|--------------------------------------------------|
+| geo | Waterkotte EcoTouch Geo + EcoVent |
+| air | Waterkotte EcoTouch Air + EcoVent |
+
+This binding was tested with a Waterkotte DS 5027 Ai DS 5010.5Ai geothermal heat pump.
+
+## Discovery
+
+Discovery is not supported. You need to provide the IP address of the display unit of the heatpump.
+
+## Thing Configuration
+
+Things can be fully configured via the UI. The following information is useful when configuring things via thing configuration files.
+
+| Property | Type | Default | Required | Description |
+|---------------------------------|---------|---------|----------|-------------|
+| ip | String | | yes | IP address or hostname of the display unit of the heat pump |
+| username | String | | yes | since software version 1.6.xx of the display unit: "waterkotte"; previously "admin". |
+| password | String | | yes | since software version 1.6.xx of the display unit: "waterkotte"; previously "wtkadmin". |
+| refresh | Integer | 60 | no | time in s after which all channels will be requested again from the heat pump |
+
+## Channels
+
+Standard channels:
+
+| Channel ID | Type | Read-Only | Description |
+|----------------------------|----------------------|-----------|-----------------------------------------------------------------|
+| adapt_heating | Number:Temperature | no | Allows to adjust the heating temperature by an offset |
+| alarm | Number:Dimensionless | yes | Alarm |
+| cop_cooling | Number:Dimensionless | yes | COP Cooling |
+| cop_heating | Number:Dimensionless | yes | COP Heating |
+| enable_cooling | Switch | no | Enable Cooling |
+| enable_heating | Switch | no | Enable Heating |
+| enable_warmwater | Switch | no | Enable Warm Water |
+| power_compressor | Number:Power | yes | Power Compressor |
+| power_cooling | Number:Power | yes | Power Cooling |
+| power_heating | Number:Power | yes | Power Heating |
+| state_alarm | Switch | yes | State Alarm |
+| temperature_cooling_return | Number:Temperature | yes | Temperature Cooling Return |
+| temperature_cooling_set2 | Number:Temperature | no | Temperature Cooling Setpoint BMS |
+| temperature_flow | Number:Temperature | yes | Temperature Flow |
+| temperature_heating_return | Number:Temperature | yes | Temperature Heating Return |
+| temperature_heating_set | Number:Temperature | yes | Temperature Heating Setpoint |
+| temperature_outside | Number:Temperature | yes | The current outside temperature |
+| temperature_outside_24h | Number:Temperature | yes | The outside temperature averaged over one day |
+| temperature_return | Number:Temperature | yes | Temperature Return |
+| temperature_return_set | Number:Temperature | yes | Temperature Return Setpoint |
+| temperature_room | Number:Temperature | yes | Temperature Room |
+| temperature_room_1h | Number:Temperature | yes | Temperature Room 1h Average |
+| temperature_source_in | Number:Temperature | yes | Temperature Source Input |
+| temperature_source_out | Number:Temperature | yes | Temperature Source Output |
+| temperature_water | Number:Temperature | yes | Temperature Water |
+| temperature_water_set2 | Number:Temperature | no | Temperature Water Setpoint BMS |
+
+Advanced channels:
+
+| Channel ID | Type | Read-Only | Description |
+|----------------------------------|----------------------|-----------|-------------------------------------------------------------------------|
+| compressor_power | Number:Dimensionless | yes | Percent Power Compressor |
+| coolEnableTemp | Number:Temperature | yes | Temperature Cooling Enable |
+| date_day | Number:Dimensionless | yes | Day |
+| date_month | Number:Dimensionless | yes | Month |
+| date_year | Number:Dimensionless | yes | Year |
+| enable_pool | Switch | no | Enable Pool |
+| enable_pv | Switch | no | Enable PV |
+| hysteresis_heating | Number:Temperature | no | Hysteresis Heating |
+| interruptions | Number:Dimensionless | yes | Interruptions |
+| manual_4wayvalve | Number:Dimensionless | no | Operating Mode 4Way Valve |
+| manual_coolvalve | Number:Dimensionless | no | Operating Mode Cooling Valve |
+| manual_heatingpump | Number:Dimensionless | no | Operating Mode Heating Pump |
+| manual_multiext | Number:Dimensionless | no | Operating Mode Multi Ouput Ext |
+| manual_poolvalve | Number:Dimensionless | no | Operating Mode Pool Valve |
+| manual_solarpump1 | Number:Dimensionless | no | Operating Mode Solar Pump |
+| manual_solarpump2 | Number:Dimensionless | no | Operating Mode Solar Pump 2 |
+| manual_sourcepump | Number:Dimensionless | no | Operating Mode Source Pump |
+| manual_tankpump | Number:Dimensionless | no | Operating Mode Tank Pump |
+| manual_valve | Number:Dimensionless | no | Operating Mode Valve |
+| maxVLTemp | Number:Temperature | yes | maxVLTemp |
+| nviHeizkreisNorm | Number:Temperature | no | nviHeizkreisNorm |
+| nviNormAussen | Number:Temperature | no | nviNormAussen |
+| nviSollKuehlen | Number:Temperature | yes | nviSollKuehlen |
+| nviTHeizgrenze | Number:Temperature | no | nviTHeizgrenze |
+| nviTHeizgrenzeSoll | Number:Temperature | no | nviTHeizgrenze Setpoint |
+| operating_hours_circulation_pump | Number:Time | yes | Operating Hours Circulation Pump |
+| operating_hours_compressor1 | Number:Time | yes | Operating Hours Compressor 1 |
+| operating_hours_compressor2 | Number:Time | yes | Operating Hours Compressor 2 |
+| operating_hours_solar | Number:Time | yes | Operating Hours Solar |
+| operating_hours_source_pump | Number:Time | yes | Operating Hours Source Pump |
+| percent_compressor | Number:Dimensionless | yes | Percent Compressor |
+| percent_heat_circ_pump | Number:Dimensionless | yes | Percent Heating Circulation Pump |
+| percent_source_pump | Number:Dimensionless | yes | Percent Source Pump |
+| position_expansion_valve | Number:Dimensionless | yes | Position Expansion Valve |
+| pressure_condensation | Number:Pressure | yes | Pressure Condensation |
+| pressure_evaporation | Number:Pressure | yes | Pressure Evaporation |
+| state | Number:Dimensionless | yes | A Bitfield which encodes the state of all valves, pumps and compressors |
+| state_compressor1 | Switch | yes | State Compressor 1 |
+| state_compressor2 | Switch | yes | State Compressor 2 |
+| state_cooling | Switch | yes | State Cooling |
+| state_cooling4way | Switch | yes | State Cooling4Way |
+| state_evd | Switch | yes | State EVD |
+| state_extheater | Switch | yes | State External Heater |
+| state_heatingpump | Switch | yes | State Heating Pump |
+| state_pool | Switch | yes | State Pool |
+| state_service | Switch | yes | State Service Mode |
+| state_solar | Switch | yes | State Solar |
+| state_sourcepump | Switch | yes | State Source Pump |
+| state_water | Switch | yes | State Water |
+| tempSet0Deg | Number:Temperature | yes | Heating Setpoint at 0°C Outside |
+| tempchange_cooling_pv | Number:Temperature | no | Temperature Change Cooling if PV |
+| tempchange_heating_pv | Number:Temperature | no | Temperature Change Heating if PV |
+| tempchange_pool_pv | Number:Temperature | no | Temperature Change Pool if PV |
+| tempchange_warmwater_pv | Number:Temperature | no | Temperature Change Water if PV |
+| temperature2_outside_1h | Number:Temperature | yes | Temperature Outside 1h Average |
+| temperature_condensation | Number:Temperature | yes | Temperature Condensation |
+| temperature_cooling_set | Number:Temperature | yes | Temperature Cooling Setpoint |
+| temperature_evaporation | Number:Temperature | yes | Temperature Evaporation |
+| temperature_heating_set2 | Number:Temperature | no | Temperature Heating Setpoint BMS |
+| temperature_outside_1h | Number:Temperature | yes | The outside temperature averaged over one hour |
+| temperature_pool | Number:Temperature | yes | Temperature Pool |
+| temperature_pool_set | Number:Temperature | yes | Temperature Pool Setpoint |
+| temperature_pool_set2 | Number:Temperature | no | Temperature Pool Setpoint BMS |
+| temperature_solar | Number:Temperature | yes | Temperature Solar |
+| temperature_solar_flow | Number:Temperature | yes | Temperature Solar Flow |
+| temperature_storage | Number:Temperature | yes | Temperature Storage |
+| temperature_suction | Number:Temperature | yes | Temperature Suction |
+| temperature_water_set | Number:Temperature | yes | Temperature Water Setpoint |
+| time_hour | Number:Dimensionless | yes | Hour |
+| time_minute | Number:Dimensionless | yes | Minute |
+| version_bios | Number:Dimensionless | yes | Version BIOS |
+| version_controller | Number:Dimensionless | yes | Version Display Controller |
+| version_controller_build | Number:Dimensionless | yes | Build Number Display Controller |
+
+If the Ecovent Unit is attached to the heat pump, the following additional channels are available:
+
+| Channel ID | Type | Read-Only | Description |
+|----------------------------|----------------------|-----------|-------------|
+| ecovent_CO2_value | Number:Dimensionless | yes | EcoVent CO2 |
+| ecovent_mode | Number:Dimensionless | no | EcoVent Mode (0..5: Day, Night, Timer, Party, Vacation, Bypass) |
+| ecovent_moisture_value | Number:Dimensionless | yes | EcoVent Air Moisture |
+| ecovent_output_y1 | Number:Dimensionless | yes | EcoVent Fan |
+| ecovent_temp_exhaust_air | Number:Temperature | yes | EcoVent Temperature Exhaust Air |
+| ecovent_temp_exit_air | Number:Temperature | yes | EcoVent Temperature Exit Air |
+| ecovent_temp_outdoor_air | Number:Temperature | yes | EcoVent Temperature Outdoor Air |
+| ecovent_temp_supply_air | Number:Temperature | yes | EcoVent Temperature Supply Air |
+
+The air heatpump has the following additional channels:
+
+| Channel ID | Type | Read-Only | Description |
+|-------------------------|--------------------|-----------|-------------------------|
+| temperature_suction_air | Number:Temperature | yes | Temperature Suction Air |
+| temperature_sump | Number:Temperature | yes | Temperature Sump |
+| temperature_surrounding | Number:Temperature | yes | Temperature Surrounding |
+
+## Example
+
+### ecotouch.things
+
+```
+Thing ecotouch:geo:heatpump "Waterkotte Heatpump" @ "basement" [ ip="192.168.1.100", username="admin", password="wtkadmin", refresh=120 ]
+```
+
+### ecotouch.items
+
+```
+Number:Temperature HeatPump_Temp_Aussen { channel="ecotouch:geo:heatpump:temperature_outside" }
+Number:Temperature HeatPump_Temp_Aussen_1d { channel="ecotouch:geo:heatpump:temperature_outside_24h" }
+Number:Temperature HeatPump_Temp_Quelle_in { channel="ecotouch:geo:heatpump:temperature_source_in" }
+Number:Temperature HeatPump_Temp_Quelle_out { channel="ecotouch:geo:heatpump:temperature_source_out" }
+Number:Temperature HeatPump_Temp_Wasser { channel="ecotouch:geo:heatpump:temperature_water" }
+Number:Temperature HeatPump_Temp_Heizen { channel="ecotouch:geo:heatpump:temperature_heating_return" }
+Number:Power HeatPump_power_el { channel="ecotouch:geo:heatpump:power_compressor" }
+Number:Power HeatPump_power_th { channel="ecotouch:geo:heatpump:power_heating" }
+Number HeatPump_COP_heating { channel="ecotouch:geo:heatpump:cop_heating" }
+Number:Temperature HeatPump_adaptHeating { channel="ecotouch:geo:heatpump:adapt_heating" }
+```
+
+### ecotouch.sitemap
+
+```
+sitemap ecotouch label="Waterkotte EcoTouch"
+{
+ Text item=HeatPump_Temp_Aussen
+ Text item=HeatPump_Temp_Aussen_1d
+ Text item=HeatPump_Temp_Quelle_in
+ Text item=HeatPump_Temp_Quelle_out
+ Text item=HeatPump_Temp_Wasser
+ Text item=HeatPump_Temp_Heizen
+ Text item=HeatPump_Temp_Heizen
+ Text item=HeatPump_power_th
+ Text item=HeatPump_COP_heating
+ Setpoint item=HeatPump_adaptHeating minValue=-2.0 maxValue=2.0 step=0.5
+}
+```
diff --git a/bundles/org.openhab.binding.ecotouch/pom.xml b/bundles/org.openhab.binding.ecotouch/pom.xml
new file mode 100644
index 0000000000000..011f0e3c75ed8
--- /dev/null
+++ b/bundles/org.openhab.binding.ecotouch/pom.xml
@@ -0,0 +1,17 @@
+
+
+
+ 4.0.0
+
+
+ org.openhab.addons.bundles
+ org.openhab.addons.reactor.bundles
+ 3.1.0-SNAPSHOT
+
+
+ org.openhab.binding.ecotouch
+
+ openHAB Add-ons :: Bundles :: EcoTouch Binding
+
+
diff --git a/bundles/org.openhab.binding.ecotouch/src/main/feature/feature.xml b/bundles/org.openhab.binding.ecotouch/src/main/feature/feature.xml
new file mode 100644
index 0000000000000..0c8a51fa4a1e0
--- /dev/null
+++ b/bundles/org.openhab.binding.ecotouch/src/main/feature/feature.xml
@@ -0,0 +1,9 @@
+
+
+ mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features
+
+
+ openhab-runtime-base
+ mvn:org.openhab.addons.bundles/org.openhab.binding.ecotouch/${project.version}
+
+
diff --git a/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchBindingConstants.java b/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchBindingConstants.java
new file mode 100644
index 0000000000000..59beab86c294c
--- /dev/null
+++ b/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchBindingConstants.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2010-2021 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.ecotouch.internal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.core.thing.ThingTypeUID;
+
+/**
+ * The {@link EcoTouchBindingConstants} class defines common constants, which are
+ * used across the whole binding.
+ *
+ * @author Sebastian Held - Initial contribution
+ */
+@NonNullByDefault
+public class EcoTouchBindingConstants {
+
+ private static final String BINDING_ID = "ecotouch";
+
+ // List of all Thing Type UIDs
+ public static final ThingTypeUID THING_TYPE_GEO = new ThingTypeUID(BINDING_ID, "geo");
+ public static final ThingTypeUID THING_TYPE_AIR = new ThingTypeUID(BINDING_ID, "air");
+}
diff --git a/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchConfiguration.java b/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchConfiguration.java
new file mode 100644
index 0000000000000..423207f54865e
--- /dev/null
+++ b/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchConfiguration.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2010-2021 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.ecotouch.internal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link EcoTouchConfiguration} class contains fields mapping thing configuration parameters.
+ *
+ * @author Sebastian Held - Initial contribution
+ */
+@NonNullByDefault
+public class EcoTouchConfiguration {
+ public String ip = "";
+ public String username = "";
+ public String password = "";
+ public Integer refresh = 60;
+}
diff --git a/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchConnector.java b/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchConnector.java
new file mode 100644
index 0000000000000..0e4ea47c091ed
--- /dev/null
+++ b/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchConnector.java
@@ -0,0 +1,332 @@
+/**
+ * Copyright (c) 2010-2021 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.ecotouch.internal;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Network communication with Waterkotte EcoTouch heat pumps.
+ *
+ * The communication protocol was reverse engineered from the Easy-Con Android
+ * app. The meaning of the EcoTouch tags was provided by Waterkotte's technical
+ * service (by an excerpt of a developer manual).
+ *
+ * @author Sebastian Held - Initial contribution
+ * @since 1.5.0
+ */
+
+@NonNullByDefault
+public class EcoTouchConnector {
+ private String ip;
+ private String username;
+ private String password;
+ @Nullable
+ List cookies;
+ static Pattern responsePattern = Pattern.compile("#(.+)\\s+S_OK[^0-9-]+([0-9-]+)\\s+([0-9-.]+)");
+
+ private final Logger logger = LoggerFactory.getLogger(EcoTouchConnector.class);
+
+ /**
+ * Create a network communication without having a current access token.
+ */
+ public EcoTouchConnector(String ip, String username, String password) {
+ this.ip = ip;
+ this.username = username;
+ this.password = password;
+ this.cookies = null;
+ }
+
+ /**
+ * Create a network communication with access token. This speeds up
+ * retrieving values, because the log in step is omitted.
+ */
+ public EcoTouchConnector(String ip, String username, String password, List cookies) {
+ this.ip = ip;
+ this.username = username;
+ this.password = password;
+ this.cookies = cookies;
+ }
+
+ private synchronized void trylogin(boolean force) throws Exception {
+ if (!force && cookies != null) {
+ // we've a login token already
+ return;
+ }
+ login();
+ }
+
+ private void login() throws IOException {
+ cookies = null;
+ String url = null;
+ String line2 = null;
+ String cause = null;
+ try {
+ url = "http://" + ip + "/cgi/login?username=" + URLEncoder.encode(username, "UTF-8") + "&password="
+ + URLEncoder.encode(password, "UTF-8");
+ URL loginurl = new URL(url);
+ URLConnection connection = loginurl.openConnection();
+ cookies = connection.getHeaderFields().get("Set-Cookie");
+ BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+ in.readLine();
+ line2 = in.readLine();
+ } catch (MalformedURLException e) {
+ cause = e.toString();
+ } catch (Exception e) {
+ cause = e.toString();
+ }
+
+ if (line2 != null && line2.trim().equals("#E_USER_DONT_EXIST")) {
+ throw new IOException("Username does not exist.");
+ }
+ if (line2 != null && line2.trim().equals("#E_PASS_DONT_MATCH")) {
+ throw new IOException("Password does not match.");
+ }
+ if (line2 != null && line2.trim().equals("#E_TOO_MANY_USERS")) {
+ throw new IOException("Too many users already logged in.");
+ }
+ if (cookies == null) {
+ if (cause == null)
+ throw new IOException("Cannot login");
+ else
+ throw new IOException("Cannot login: " + cause);
+ }
+ }
+
+ public void logout() {
+ if (cookies != null) {
+ try {
+ URL logouturl = new URL("http://" + ip + "/cgi/logout");
+ logouturl.openConnection();
+ } catch (Exception e) {
+ }
+ cookies = null;
+ }
+ }
+
+ /**
+ * Request a value from the heat pump
+ *
+ * @param tag
+ * The register to query (e.g. "A1")
+ * @return value This value is a 16-bit integer.
+ */
+ public String getValue(String tag) throws Exception {
+ Map result = getValues(Set.of(tag));
+ String value = result.get(tag);
+ if (value == null) {
+ // failed
+ logger.debug("Cannot get value for tag '{}' from Waterkotte EcoTouch.", tag);
+ throw new EcoTouchException("invalid response from EcoTouch");
+ }
+
+ return value;
+ }
+
+ /**
+ * Request multiple values from the heat pump
+ *
+ * @param tags
+ * The registers to query (e.g. "A1")
+ * @return values A map of tags and their respective string values
+ */
+ public Map getValues(Set tags) throws Exception {
+ final Integer maxNum = 100;
+
+ Map result = new HashMap();
+ Integer counter = 1;
+ StringBuilder query = new StringBuilder();
+ Iterator iter = tags.iterator();
+ while (iter.hasNext()) {
+ query.append(String.format("t%d=%s&", counter, iter.next()));
+ counter++;
+ if (counter > maxNum) {
+ query.deleteCharAt(query.length() - 1); // remove last '&'
+ String queryStr = String.format("http://%s/cgi/readTags?n=%d&", ip, maxNum) + query;
+ result.putAll(getValues(queryStr));
+ counter = 1;
+ query = new StringBuilder();
+ }
+ }
+
+ if (query.length() > 0) {
+ query.deleteCharAt(query.length() - 1); // remove last '&'
+ String queryStr = String.format("http://%s/cgi/readTags?n=%d&", ip, counter - 1) + query;
+ result.putAll(getValues(queryStr));
+ }
+
+ return result;
+ }
+
+ /**
+ * Send a request to the heat pump and evaluate the result
+ *
+ * @param url
+ * The URL to connect to
+ * @return values A map of tags and their respective string values
+ */
+ private Map getValues(String url) throws Exception {
+ trylogin(false);
+ Map result = new HashMap();
+ int loginAttempt = 0;
+ while (loginAttempt < 2) {
+ BufferedReader reader = null;
+ try {
+ URLConnection connection = new URL(url).openConnection();
+ var localCookies = cookies;
+ if (localCookies != null) {
+ for (String cookie : localCookies) {
+ connection.addRequestProperty("Cookie", cookie.split(";", 2)[0]);
+ }
+ }
+ InputStream response = connection.getInputStream();
+ reader = new BufferedReader(new InputStreamReader(response));
+ // the answer is s.th. like
+ // #A30 S_OK
+ // 192 223
+ // [...]
+ String line;
+ while ((line = reader.readLine()) != null) {
+ String line2 = reader.readLine();
+ if (line2 == null)
+ break;
+ String doubleline = line + "\n" + line2;
+ Matcher m = responsePattern.matcher(doubleline);
+ if (m.find()) {
+ String tag = m.group(1);
+ String value = m.group(3).trim();
+ result.put(tag, value);
+ }
+ }
+
+ if (result.isEmpty()) {
+ // s.th. went wrong; try to log in again
+ throw new EcoTouchException();
+ }
+
+ // succeeded
+ break;
+ } catch (Exception e) {
+ if (loginAttempt == 0) {
+ // try to login once
+ trylogin(true);
+ }
+ loginAttempt++;
+ } finally {
+ if (reader != null)
+ reader.close();
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Set a value
+ *
+ * @param tag
+ * The register to set (e.g. "A1")
+ * @param value
+ * The 16-bit integer to set the register to
+ * @return value This value is a 16-bit integer.
+ */
+ public int setValue(String tag, int value) throws Exception {
+ trylogin(false);
+
+ // set value
+ String url = "http://" + ip + "/cgi/writeTags?returnValue=true&n=1&t1=" + tag + "&v1=" + value;
+ StringBuilder body = null;
+ int loginAttempt = 0;
+ while (loginAttempt < 2) {
+ BufferedReader reader = null;
+ try {
+ URLConnection connection = new URL(url).openConnection();
+ var localCookies = cookies;
+ if (localCookies != null) {
+ for (String cookie : localCookies) {
+ connection.addRequestProperty("Cookie", cookie.split(";", 2)[0]);
+ }
+ }
+ InputStream response = connection.getInputStream();
+ reader = new BufferedReader(new InputStreamReader(response));
+ body = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ body.append(line + "\n");
+ }
+ if (body.toString().contains("#" + tag)) {
+ // succeeded
+ break;
+ }
+ // s.th. went wrong; try to log in
+ throw new EcoTouchException();
+ } catch (Exception e) {
+ if (loginAttempt == 0) {
+ // try to login once
+ trylogin(true);
+ }
+ loginAttempt++;
+ } finally {
+ if (reader != null)
+ reader.close();
+ }
+ }
+
+ if (body == null || !body.toString().contains("#" + tag)) {
+ // failed
+ logger.debug("Cannot get value for tag '{}' from Waterkotte EcoTouch.", tag);
+ throw new EcoTouchException("invalid response from EcoTouch");
+ }
+
+ // ok, the body now contains s.th. like
+ // #A30 S_OK
+ // 192 223
+
+ Matcher m = responsePattern.matcher(body.toString());
+ boolean b = m.find();
+ if (!b) {
+ // ill formatted response
+ logger.debug("ill formatted response: '{}'", body);
+ throw new EcoTouchException("invalid response from EcoTouch");
+ }
+
+ logger.debug("response: '{}'", body.toString());
+ return Integer.parseInt(m.group(3));
+ }
+
+ /**
+ * Authentication token. Store this and use it, when creating the next
+ * instance of this class.
+ *
+ * @return cookies: This includes the authentication token retrieved during
+ * log in.
+ */
+ @Nullable
+ public List getCookies() {
+ return cookies;
+ }
+}
diff --git a/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchException.java b/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchException.java
new file mode 100644
index 0000000000000..bccb4e4a7bf1f
--- /dev/null
+++ b/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchException.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2010-2021 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.ecotouch.internal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Trivial Exception Class.
+ *
+ * Used to solve compiler warning: "Avoid throwing raw exception types".
+ *
+ * @author Sebastian Held - Initial contribution
+ * @since 3.1.0
+ */
+@NonNullByDefault
+public class EcoTouchException extends Exception {
+ private static final long serialVersionUID = -346364205220073265L;
+
+ public EcoTouchException(String errorMessage, Throwable err) {
+ super(errorMessage, err);
+ }
+
+ public EcoTouchException(String errorMessage) {
+ super(errorMessage);
+ }
+
+ public EcoTouchException() {
+ super();
+ }
+}
diff --git a/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchHandler.java b/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchHandler.java
new file mode 100644
index 0000000000000..f76daa485d5b7
--- /dev/null
+++ b/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchHandler.java
@@ -0,0 +1,236 @@
+/**
+ * Copyright (c) 2010-2021 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.ecotouch.internal;
+
+import static org.openhab.core.library.unit.SIUnits.*;
+import static org.openhab.core.library.unit.Units.*;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.*;
+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.core.library.types.DecimalType;
+import org.openhab.core.library.types.QuantityType;
+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.types.Command;
+import org.openhab.core.types.RefreshType;
+import org.openhab.core.types.State;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link EcoTouchHandler} is responsible for handling commands, which are
+ * sent to one of the channels.
+ *
+ * @author Sebastian Held - Initial contribution
+ */
+@NonNullByDefault
+public class EcoTouchHandler extends BaseThingHandler {
+
+ private @Nullable EcoTouchConnector connector = null;
+
+ private final Logger logger = LoggerFactory.getLogger(EcoTouchHandler.class);
+
+ private @Nullable EcoTouchConfiguration config = null;
+
+ private @Nullable ScheduledFuture> refreshJob = null;
+
+ public EcoTouchHandler(Thing thing) {
+ super(thing);
+ }
+
+ private void updateChannel(String tag, String value_str) {
+ try {
+ List ecoTouchTags = EcoTouchTags.fromTag(tag);
+ for (EcoTouchTags ecoTouchTag : ecoTouchTags) {
+ String channel = ecoTouchTag.getCommand();
+ BigDecimal value = ecoTouchTag.decodeValue(value_str);
+ if (ecoTouchTag == EcoTouchTags.TYPE_ADAPT_HEATING) {
+ // this type needs special treatment
+ // the following reads: value = value / 2 - 2
+ value = value.divide(new BigDecimal(2), 1, RoundingMode.UNNECESSARY).subtract(new BigDecimal(2));
+ QuantityType> quantity = new QuantityType(value, CELSIUS);
+ updateState(channel, quantity);
+ } else {
+ if (ecoTouchTag.getUnit() != ONE) {
+ // this is a quantity type
+ QuantityType> quantity = new QuantityType<>(value, ecoTouchTag.getUnit());
+ updateState(channel, quantity);
+ } else {
+ DecimalType number = new DecimalType(value);
+ updateState(channel, number);
+ }
+ }
+ }
+ } catch (Exception e) {
+ }
+ }
+
+ @Override
+ public void handleCommand(ChannelUID channelUID, Command command) {
+ var localConnector = connector;
+ if (localConnector == null) {
+ // the binding was not initialized, yet
+ return;
+ }
+ if (command instanceof RefreshType) {
+ // request a refresh of a channel
+ try {
+ EcoTouchTags tag = EcoTouchTags.fromString(channelUID.getId());
+ if (tag != null) {
+ String valueStr = localConnector.getValue(tag.getTagName());
+ updateChannel(tag.getTagName(), valueStr);
+ updateStatus(ThingStatus.ONLINE);
+ }
+ } catch (Exception e) {
+ }
+ } else {
+ // send command to heat pump
+ try {
+ EcoTouchTags ecoTouchTag = EcoTouchTags.fromString(channelUID.getId());
+ if (ecoTouchTag == EcoTouchTags.TYPE_ADAPT_HEATING) {
+ // this type needs special treatment
+ QuantityType> value = (QuantityType>) command;
+ int raw = Math.round(value.floatValue() * 2 + 4);
+ localConnector.setValue(ecoTouchTag.getTagName(), raw);
+ } else {
+ if (ecoTouchTag.getUnit() != ONE) {
+ if (command instanceof QuantityType) {
+ // convert from user unit to heat pump unit
+ QuantityType> value = (QuantityType>) command;
+ QuantityType> rawUnit = value.toUnit(ecoTouchTag.getUnit());
+ if (rawUnit != null) {
+ int raw = rawUnit.intValue();
+ raw *= ecoTouchTag.getDivisor();
+ localConnector.setValue(ecoTouchTag.getTagName(), raw);
+ }
+ } else {
+ logger.debug("handleCommand: requires a QuantityType");
+ }
+ } else {
+ State state = (State) command;
+ DecimalType decimalType = state.as(DecimalType.class);
+ if (decimalType != null) {
+ BigDecimal decimal = decimalType.toBigDecimal();
+ decimal = decimal.multiply(new BigDecimal(ecoTouchTag.getDivisor()));
+ int raw = decimal.intValue();
+ localConnector.setValue(ecoTouchTag.getTagName(), raw);
+ } else {
+ logger.debug("cannot convert {} to a DecimalType", state);
+ }
+ }
+ }
+ } catch (Exception e) {
+ logger.debug("handleCommand: {}", e.toString());
+ }
+ }
+ }
+
+ @Override
+ public void initialize() {
+ config = getConfigAs(EcoTouchConfiguration.class);
+
+ var localConfig = config;
+ if (localConfig == null) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR);
+ return;
+ }
+
+ connector = new EcoTouchConnector(localConfig.ip, localConfig.username, localConfig.password);
+
+ scheduler.execute(() -> {
+ try {
+ // try to get a single value
+ var localConnector = connector;
+ if (localConnector == null) {
+ updateStatus(ThingStatus.OFFLINE);
+ return;
+ }
+ localConnector.getValue("A1");
+ } catch (IOException io) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, io.toString());
+ return;
+ } catch (Exception e) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.toString());
+ return;
+ }
+
+ updateStatus(ThingStatus.ONLINE);
+ });
+
+ // start refresh handler
+ startAutomaticRefresh();
+ }
+
+ private void startAutomaticRefresh() {
+ var localRefreshJob = refreshJob;
+ if (localRefreshJob == null || localRefreshJob.isCancelled()) {
+ Runnable runnable = () -> {
+ try {
+ Set tags = new HashSet();
+ for (EcoTouchTags ecoTouchTag : EcoTouchTags.values()) {
+ String channel = ecoTouchTag.getCommand();
+ boolean linked = isLinked(channel);
+ if (linked)
+ tags.add(ecoTouchTag.getTagName());
+ }
+ var localConnector = connector;
+ if (localConnector != null) {
+ Map result = localConnector.getValues(tags);
+
+ Iterator> it = result.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry pair = it.next();
+ updateChannel(pair.getKey(), pair.getValue());
+ }
+ }
+ } catch (IOException io) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, io.toString());
+ } catch (Exception e) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.toString());
+ } catch (Error e) {
+ // during thing creation, the following error is thrown:
+ // java.lang.NoSuchMethodError: 'org.openhab.binding.ecotouch.internal.EcoTouchTags[]
+ // org.openhab.binding.ecotouch.internal.EcoTouchTags.values()'
+ // not sure why... lets ignore it for now
+ updateStatus(ThingStatus.OFFLINE);
+ }
+ };
+
+ var localConfig = config;
+ if (localConfig != null)
+ refreshJob = scheduler.scheduleWithFixedDelay(runnable, 10, localConfig.refresh, TimeUnit.SECONDS);
+ }
+ }
+
+ @Override
+ public void dispose() {
+ var localRefreshJob = refreshJob;
+ if (localRefreshJob != null && !localRefreshJob.isCancelled()) {
+ localRefreshJob.cancel(true);
+ localRefreshJob = null;
+ }
+ var localConnector = connector;
+ if (localConnector != null)
+ localConnector.logout();
+ }
+}
diff --git a/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchHandlerFactory.java b/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchHandlerFactory.java
new file mode 100644
index 0000000000000..02e1d9f82c23d
--- /dev/null
+++ b/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchHandlerFactory.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2010-2021 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.ecotouch.internal;
+
+import static org.openhab.binding.ecotouch.internal.EcoTouchBindingConstants.THING_TYPE_AIR;
+import static org.openhab.binding.ecotouch.internal.EcoTouchBindingConstants.THING_TYPE_GEO;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+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 EcoTouchHandlerFactory} is responsible for creating things and thing
+ * handlers.
+ *
+ * @author Sebastian Held - Initial contribution
+ */
+@NonNullByDefault
+@Component(configurationPid = "binding.ecotouch", service = ThingHandlerFactory.class)
+public class EcoTouchHandlerFactory extends BaseThingHandlerFactory {
+
+ private static final Set SUPPORTED_THING_TYPES_UIDS = Collections
+ .unmodifiableSet(Stream.of(THING_TYPE_GEO, THING_TYPE_AIR).collect(Collectors.toSet()));
+
+ @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_GEO.equals(thingTypeUID) || THING_TYPE_AIR.equals(thingTypeUID)) {
+ return new EcoTouchHandler(thing);
+ }
+
+ return null;
+ }
+}
diff --git a/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchTags.java b/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchTags.java
new file mode 100644
index 0000000000000..19572aaa537ea
--- /dev/null
+++ b/bundles/org.openhab.binding.ecotouch/src/main/java/org/openhab/binding/ecotouch/internal/EcoTouchTags.java
@@ -0,0 +1,1294 @@
+/**
+ * Copyright (c) 2010-2021 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.ecotouch.internal;
+
+import static org.openhab.core.library.unit.MetricPrefix.*;
+import static org.openhab.core.library.unit.SIUnits.*;
+import static org.openhab.core.library.unit.Units.*;
+
+import java.math.BigDecimal;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.measure.Unit;
+
+/**
+ * Represents all valid commands which could be processed by this binding
+ *
+ * @author Sebastian Held - Initial contribution
+ * @since 1.5.0
+ */
+public enum EcoTouchTags {
+
+ // German: Außentemperatur
+ TYPE_TEMPERATURE_OUTSIDE {
+ {
+ command = "temperature_outside";
+ unit = CELSIUS;
+ tagName = "A1";
+ }
+ },
+
+ // German: Außentemperatur gemittelt über 1h
+ TYPE_TEMPERATURE_OUTSIDE_1H {
+ {
+ command = "temperature_outside_1h";
+ unit = CELSIUS;
+ tagName = "A2";
+ }
+ },
+
+ // German: Außentemperatur gemittelt über 24h
+ TYPE_TEMPERATURE_OUTSIDE_24H {
+ {
+ command = "temperature_outside_24h";
+ unit = CELSIUS;
+ tagName = "A3";
+ }
+ },
+
+ // German: Quelleneintrittstemperatur
+ TYPE_TEMPERATURE_SOURCE_IN {
+ {
+ command = "temperature_source_in";
+ unit = CELSIUS;
+ tagName = "A4";
+ }
+ },
+
+ // German: Quellenaustrittstemperatur
+ TYPE_TEMPERATURE_SOURCE_OUT {
+ {
+ command = "temperature_source_out";
+ unit = CELSIUS;
+ tagName = "A5";
+ }
+ },
+
+ // German: Verdampfungstemperatur
+ TYPE_TEMPERATURE_EVAPORATION {
+ {
+ command = "temperature_evaporation";
+ unit = CELSIUS;
+ tagName = "A6";
+ }
+ },
+
+ // German: Sauggastemperatur
+ TYPE_TEMPERATURE_SUCTION {
+ {
+ command = "temperature_suction";
+ unit = CELSIUS;
+ tagName = "A7";
+ }
+ },
+
+ // German: Verdampfungsdruck
+ TYPE_PRESSURE_EVAPORATION {
+ {
+ command = "pressure_evaporation";
+ unit = BAR;
+ tagName = "A8";
+ }
+ },
+
+ // German: Temperatur Rücklauf Soll
+ TYPE_TEMPERATURE_RETURN_SET {
+ {
+ command = "temperature_return_set";
+ unit = CELSIUS;
+ tagName = "A10";
+ }
+ },
+
+ // German: Temperatur Rücklauf
+ TYPE_TEMPERATURE_RETURN {
+ {
+ command = "temperature_return";
+ unit = CELSIUS;
+ tagName = "A11";
+ }
+ },
+
+ // German: Temperatur Vorlauf
+ TYPE_TEMPERATURE_FLOW {
+ {
+ command = "temperature_flow";
+ unit = CELSIUS;
+ tagName = "A12";
+ }
+ },
+
+ // German: Kondensationstemperatur
+ TYPE_TEMPERATURE_CONDENSATION {
+ {
+ command = "temperature_condensation";
+ unit = CELSIUS;
+ tagName = "A14";
+ }
+ },
+
+ // German: Kondensationsdruck
+ TYPE_PRESSURE_CONDENSATION {
+ {
+ command = "pressure_condensation";
+ unit = BAR;
+ tagName = "A15";
+ }
+ },
+
+ // German: Speichertemperatur
+ TYPE_TEMPERATURE_STORAGE {
+ {
+ command = "temperature_storage";
+ unit = CELSIUS;
+ tagName = "A16";
+ }
+ },
+
+ // German: Raumtemperatur
+ TYPE_TEMPERATURE_ROOM {
+ {
+ command = "temperature_room";
+ unit = CELSIUS;
+ tagName = "A17";
+ }
+ },
+
+ // German: Raumtemperatur gemittelt über 1h
+ TYPE_TEMPERATURE_ROOM_1H {
+ {
+ command = "temperature_room_1h";
+ unit = CELSIUS;
+ tagName = "A18";
+ }
+ },
+
+ // German: Warmwassertemperatur
+ TYPE_TEMPERATURE_WATER {
+ {
+ command = "temperature_water";
+ unit = CELSIUS;
+ tagName = "A19";
+ }
+ },
+
+ // German: Pooltemperatur
+ TYPE_TEMPERATURE_POOL {
+ {
+ command = "temperature_pool";
+ unit = CELSIUS;
+ tagName = "A20";
+ }
+ },
+
+ // German: Solarkollektortemperatur
+ TYPE_TEMPERATURE_SOLAR {
+ {
+ command = "temperature_solar";
+ unit = CELSIUS;
+ tagName = "A21";
+ }
+ },
+
+ // German: Solarkreis Vorlauf
+ TYPE_TEMPERATURE_SOLAR_FLOW {
+ {
+ command = "temperature_solar_flow";
+ unit = CELSIUS;
+ tagName = "A22";
+ }
+ },
+
+ // German: Ventilöffnung elektrisches Expansionsventil
+ TYPE_POSITION_EXPANSION_VALVE {
+ {
+ command = "position_expansion_valve";
+ unit = PERCENT;
+ tagName = "A23";
+ }
+ },
+
+ // German: elektrische Leistung Verdichter
+ TYPE_POWER_COMPRESSOR {
+ {
+ command = "power_compressor";
+ unit = KILO(WATT);
+ tagName = "A25";
+ }
+ },
+
+ // German: abgegebene thermische Heizleistung der Wärmepumpe
+ TYPE_POWER_HEATING {
+ {
+ command = "power_heating";
+ unit = KILO(WATT);
+ tagName = "A26";
+ }
+ },
+
+ // German: abgegebene thermische KälteLeistung der Wärmepumpe
+ TYPE_POWER_COOLING {
+ {
+ command = "power_cooling";
+ unit = KILO(WATT);
+ tagName = "A27";
+ }
+ },
+
+ // German: COP Heizleistung
+ TYPE_COP_HEATING {
+ {
+ command = "cop_heating";
+ tagName = "A28";
+ }
+ },
+
+ // German: COP Kälteleistungleistung
+ TYPE_COP_COOLING {
+ {
+ command = "cop_cooling";
+ tagName = "A29";
+ }
+ },
+
+ // German: Aktuelle Heizkreistemperatur
+ TYPE_TEMPERATURE_HEATING {
+ {
+ command = "temperature_heating_return";
+ unit = CELSIUS;
+ tagName = "A30";
+ }
+ },
+
+ // German: Geforderte Temperatur im Heizbetrieb
+ TYPE_TEMPERATURE_HEATING_SET {
+ {
+ command = "temperature_heating_set";
+ unit = CELSIUS;
+ tagName = "A31";
+ }
+ },
+
+ // German: Sollwertvorgabe Heizkreistemperatur
+ TYPE_TEMPERATURE_HEATING_SET2 {
+ {
+ command = "temperature_heating_set2";
+ unit = CELSIUS;
+ tagName = "A32";
+ }
+ },
+
+ // German: Aktuelle Kühlkreistemperatur
+ TYPE_TEMPERATURE_COOLING {
+ {
+ command = "temperature_cooling_return";
+ unit = CELSIUS;
+ tagName = "A33";
+ }
+ },
+
+ // German: Geforderte Temperatur im Kühlbetrieb
+ TYPE_TEMPERATURE_COOLING_SET {
+ {
+ command = "temperature_cooling_set";
+ unit = CELSIUS;
+ tagName = "A34";
+ }
+ },
+
+ // German: Sollwertvorgabe Kühlbetrieb
+ TYPE_TEMPERATURE_COOLING_SET2 {
+ {
+ command = "temperature_cooling_set2";
+ unit = CELSIUS;
+ tagName = "A35";
+ }
+ },
+
+ // German: Sollwert Warmwassertemperatur
+ TYPE_TEMPERATURE_WATER_SET {
+ {
+ command = "temperature_water_set";
+ unit = CELSIUS;
+ tagName = "A37";
+ }
+ },
+
+ // German: Sollwertvorgabe Warmwassertemperatur
+ TYPE_TEMPERATURE_WATER_SET2 {
+ {
+ command = "temperature_water_set2";
+ unit = CELSIUS;
+ tagName = "A38";
+ }
+ },
+
+ // German: Sollwert Poolwassertemperatur
+ TYPE_TEMPERATURE_POOL_SET {
+ {
+ command = "temperature_pool_set";
+ unit = CELSIUS;
+ tagName = "A40";
+ }
+ },
+
+ // German: Sollwertvorgabe Poolwassertemperatur
+ TYPE_TEMPERATURE_POOL_SET2 {
+ {
+ command = "temperature_pool_set2";
+ unit = CELSIUS;
+ tagName = "A41";
+ }
+ },
+
+ // German: geforderte Verdichterleistung
+ TYPE_COMPRESSOR_POWER {
+ {
+ command = "compressor_power";
+ unit = PERCENT;
+ tagName = "A50";
+ }
+ },
+
+ // German: % Heizungsumwälzpumpe
+ TYPE_PERCENT_HEAT_CIRC_PUMP {
+ {
+ command = "percent_heat_circ_pump";
+ unit = PERCENT;
+ tagName = "A51";
+ }
+ },
+
+ // German: % Quellenpumpe
+ TYPE_PERCENT_SOURCE_PUMP {
+ {
+ command = "percent_source_pump";
+ unit = PERCENT;
+ tagName = "A52";
+ }
+ },
+
+ // German: % Leistung Verdichter
+ TYPE_PERCENT_COMPRESSOR {
+ {
+ command = "percent_compressor";
+ unit = PERCENT;
+ tagName = "A58";
+ }
+ },
+
+ // German: Hysterese Heizung
+ TYPE_HYSTERESIS_HEATING {
+ {
+ command = "hysteresis_heating";
+ unit = CELSIUS;
+ tagName = "A61";
+ }
+ },
+
+ // German: Außentemperatur gemittelt über 1h (scheinbar identisch zu A2)
+ TYPE_TEMPERATURE2_OUTSIDE_1H {
+ {
+ command = "temperature2_outside_1h";
+ unit = CELSIUS;
+ tagName = "A90";
+ }
+ },
+
+ // German: Heizkurve - nviNormAussen
+ TYPE_NVINORMAUSSEN {
+ {
+ command = "nviNormAussen";
+ unit = CELSIUS;
+ tagName = "A91";
+ }
+ },
+
+ // German: Heizkurve - nviHeizkreisNorm
+ TYPE_NVIHEIZKREISNORM {
+ {
+ command = "nviHeizkreisNorm";
+ unit = CELSIUS;
+ tagName = "A92";
+ }
+ },
+
+ // German: Heizkurve - nviTHeizgrenze
+ TYPE_NVITHEIZGRENZE {
+ {
+ command = "nviTHeizgrenze";
+ unit = CELSIUS;
+ tagName = "A93";
+ }
+ },
+
+ // German: Heizkurve - nviTHeizgrenzeSoll
+ TYPE_NVITHEIZGRENZESOLL {
+ {
+ command = "nviTHeizgrenzeSoll";
+ unit = CELSIUS;
+ tagName = "A94";
+ }
+ },
+
+ // German: undokumentiert: Heizkurve max. VL-Temp (??)
+ TYPE_MAX_VL_TEMP {
+ {
+ command = "maxVLTemp";
+ unit = CELSIUS;
+ tagName = "A95";
+ }
+ },
+
+ // German: undokumentiert: Heizkreis Soll-Temp bei 0° Aussen
+ TYPE_TEMP_SET_0DEG {
+ {
+ command = "tempSet0Deg";
+ unit = CELSIUS;
+ tagName = "A97";
+ }
+ },
+
+ // German: Raum Soll
+ TYPE_TEMP_ROOM_SET {
+ {
+ command = "tempRoomSet";
+ unit = CELSIUS;
+ tagName = "A100";
+ }
+ },
+
+ // German: undokumentiert: Kühlen Einschalt-Temp. Aussentemp (??)
+ TYPE_COOLENABLETEMP {
+ {
+ command = "coolEnableTemp";
+ unit = CELSIUS;
+ tagName = "A108";
+ }
+ },
+
+ // German: Heizkurve - nviSollKuehlen
+ TYPE_NVITSOLLKUEHLEN {
+ {
+ command = "nviSollKuehlen";
+ unit = CELSIUS;
+ tagName = "A109";
+ }
+ },
+
+ // German: Temperaturveränderung Heizkreis bei PV-Ertrag
+ TYPE_TEMPCHANGE_HEATING_PV {
+ {
+ command = "tempchange_heating_pv";
+ unit = CELSIUS;
+ tagName = "A682";
+ }
+ },
+
+ // German: Temperaturveränderung Kühlkreis bei PV-Ertrag
+ TYPE_TEMPCHANGE_COOLING_PV {
+ {
+ command = "tempchange_cooling_pv";
+ unit = CELSIUS;
+ tagName = "A683";
+ }
+ },
+
+ // German: Temperaturveränderung Warmwasser bei PV-Ertrag
+ TYPE_TEMPCHANGE_WARMWATER_PV {
+ {
+ command = "tempchange_warmwater_pv";
+ unit = CELSIUS;
+ tagName = "A684";
+ }
+ },
+
+ // German: Temperaturveränderung Pool bei PV-Ertrag
+ TYPE_TEMPCHANGE_POOL_PV {
+ {
+ command = "tempchange_pool_pv";
+ unit = CELSIUS;
+ tagName = "A685";
+ }
+ },
+
+ // German: undokumentiert: Firmware-Version Regler
+ // value 10401 => 01.04.01
+ TYPE_VERSION_CONTROLLER {
+ {
+ command = "version_controller";
+ divisor = 1;
+ tagName = "I1";
+ type = Type.Word;
+ }
+ },
+
+ // German: undokumentiert: Firmware-Build Regler
+ TYPE_VERSION_CONTROLLER_BUILD {
+ {
+ command = "version_controller_build";
+ divisor = 1;
+ tagName = "I2";
+ type = Type.Word;
+ }
+ },
+
+ // German: undokumentiert: BIOS-Version
+ // value 620 => 06.20
+ TYPE_VERSION_BIOS {
+ {
+ command = "version_bios";
+ divisor = 1;
+ tagName = "I3";
+ type = Type.Word;
+ }
+ },
+
+ // German: undokumentiert: Datum: Tag
+ TYPE_DATE_DAY {
+ {
+ command = "date_day";
+ divisor = 1;
+ tagName = "I5";
+ type = Type.Word;
+ }
+ },
+
+ // German: undokumentiert: Datum: Monat
+ TYPE_DATE_MONTH {
+ {
+ command = "date_month";
+ divisor = 1;
+ tagName = "I6";
+ type = Type.Word;
+ }
+ },
+
+ // German: undokumentiert: Datum: Jahr
+ TYPE_DATE_YEAR {
+ {
+ command = "date_year";
+ divisor = 1;
+ tagName = "I7";
+ type = Type.Word;
+ }
+ },
+
+ // German: undokumentiert: Uhrzeit: Stunde
+ TYPE_TIME_HOUR {
+ {
+ command = "time_hour";
+ divisor = 1;
+ tagName = "I8";
+ type = Type.Word;
+ }
+ },
+
+ // German: undokumentiert: Uhrzeit: Minute
+ TYPE_TIME_MINUTE {
+ {
+ command = "time_minute";
+ divisor = 1;
+ tagName = "I9";
+ type = Type.Word;
+ }
+ },
+
+ // German: Betriebsstunden Verdichter 1
+ TYPE_OPERATING_HOURS_COMPRESSOR1 {
+ {
+ command = "operating_hours_compressor1";
+ divisor = 1;
+ unit = HOUR;
+ tagName = "I10";
+ type = Type.Word;
+ }
+ },
+
+ // German: Betriebsstunden Verdichter 2
+ TYPE_OPERATING_HOURS_COMPRESSOR2 {
+ {
+ command = "operating_hours_compressor2";
+ divisor = 1;
+ unit = HOUR;
+ tagName = "I14";
+ type = Type.Word;
+ }
+ },
+
+ // German: Betriebsstunden Heizungsumwälzpumpe
+ TYPE_OPERATING_HOURS_CIRCULATION_PUMP {
+ {
+ command = "operating_hours_circulation_pump";
+ divisor = 1;
+ unit = HOUR;
+ tagName = "I18";
+ type = Type.Word;
+ }
+ },
+
+ // German: Betriebsstunden Quellenpumpe
+ TYPE_OPERATING_HOURS_SOURCE_PUMP {
+ {
+ command = "operating_hours_source_pump";
+ divisor = 1;
+ unit = HOUR;
+ tagName = "I20";
+ type = Type.Word;
+ }
+ },
+
+ // German: Betriebsstunden Solarkreis
+ TYPE_OPERATING_HOURS_SOLAR {
+ {
+ command = "operating_hours_solar";
+ divisor = 1;
+ unit = HOUR;
+ tagName = "I22";
+ type = Type.Word;
+ }
+ },
+
+ // German: Handabschaltung Heizbetrieb
+ TYPE_ENABLE_HEATING {
+ {
+ command = "enable_heating";
+ divisor = 1;
+ tagName = "I30";
+ type = Type.Word;
+ }
+ },
+
+ // German: Handabschaltung Kühlbetrieb
+ TYPE_ENABLE_COOLING {
+ {
+ command = "enable_cooling";
+ divisor = 1;
+ tagName = "I31";
+ type = Type.Word;
+ }
+ },
+
+ // German: Handabschaltung Warmwasserbetrieb
+ TYPE_ENABLE_WARMWATER {
+ {
+ command = "enable_warmwater";
+ divisor = 1;
+ tagName = "I32";
+ type = Type.Word;
+ }
+ },
+
+ // German: Handabschaltung Pool_Heizbetrieb
+ TYPE_ENABLE_POOL {
+ {
+ command = "enable_pool";
+ divisor = 1;
+ tagName = "I33";
+ type = Type.Word;
+ }
+ },
+
+ // German: undokumentiert: vermutlich Betriebsmodus PV 0=Aus, 1=Auto, 2=Ein
+ TYPE_ENABLE_PV {
+ {
+ command = "enable_pv";
+ divisor = 1;
+ tagName = "I41";
+ type = Type.Word;
+ }
+ },
+
+ // German: Status der Wärmepumpenkomponenten
+ TYPE_STATE {
+ {
+ command = "state";
+ divisor = 1;
+ tagName = "I51";
+ type = Type.Word;
+ }
+ },
+
+ // German: Status der Wärmepumpenkomponenten: Quellenpumpe
+ TYPE_STATE_SOURCEPUMP {
+ {
+ command = "state_sourcepump";
+ tagName = "I51";
+ type = Type.Bitfield;
+ bitnum = 0;
+ }
+ },
+
+ // German: Status der Wärmepumpenkomponenten: Heizungsumwälzpumpe
+ TYPE_STATE_HEATINGPUMP {
+ {
+ command = "state_heatingpump";
+ tagName = "I51";
+ type = Type.Bitfield;
+ bitnum = 1;
+ }
+ },
+
+ // German: Status der Wärmepumpenkomponenten: Freigabe Regelung EVD /
+ // Magnetventil
+ TYPE_STATE_EVD {
+ {
+ command = "state_evd";
+ tagName = "I51";
+ type = Type.Bitfield;
+ bitnum = 2;
+ }
+ },
+
+ // German: Status der Wärmepumpenkomponenten: Verdichter 1
+ TYPE_STATE_compressor1 {
+ {
+ command = "state_compressor1";
+ tagName = "I51";
+ type = Type.Bitfield;
+ bitnum = 3;
+ }
+ },
+
+ // German: Status der Wärmepumpenkomponenten: Verdichter 2
+ TYPE_STATE_compressor2 {
+ {
+ command = "state_compressor2";
+ tagName = "I51";
+ type = Type.Bitfield;
+ bitnum = 4;
+ }
+ },
+
+ // German: Status der Wärmepumpenkomponenten: externer Wärmeerzeuger
+ TYPE_STATE_extheater {
+ {
+ command = "state_extheater";
+ tagName = "I51";
+ type = Type.Bitfield;
+ bitnum = 5;
+ }
+ },
+
+ // German: Status der Wärmepumpenkomponenten: Alarmausgang
+ TYPE_STATE_alarm {
+ {
+ command = "state_alarm";
+ tagName = "I51";
+ type = Type.Bitfield;
+ bitnum = 6;
+ }
+ },
+
+ // German: Status der Wärmepumpenkomponenten: Motorventil Kühlbetrieb
+ TYPE_STATE_cooling {
+ {
+ command = "state_cooling";
+ tagName = "I51";
+ type = Type.Bitfield;
+ bitnum = 7;
+ }
+ },
+
+ // German: Status der Wärmepumpenkomponenten: Motorventil Warmwasser
+ TYPE_STATE_water {
+ {
+ command = "state_water";
+ tagName = "I51";
+ type = Type.Bitfield;
+ bitnum = 8;
+ }
+ },
+
+ // German: Status der Wärmepumpenkomponenten: Motorventil Pool
+ TYPE_STATE_pool {
+ {
+ command = "state_pool";
+ tagName = "I51";
+ type = Type.Bitfield;
+ bitnum = 9;
+ }
+ },
+
+ // German: Status der Wärmepumpenkomponenten: Solarbetrieb
+ TYPE_STATE_solar {
+ {
+ command = "state_solar";
+ tagName = "I51";
+ type = Type.Bitfield;
+ bitnum = 10;
+ }
+ },
+
+ // German: Status der Wärmepumpenkomponenten: 4-Wegeventil im Kältekreis
+ TYPE_STATE_cooling4way {
+ {
+ command = "state_cooling4way";
+ tagName = "I51";
+ type = Type.Bitfield;
+ bitnum = 11;
+ }
+ },
+
+ // German: Meldungen von Ausfällen F0xx die zum Wärmepumpenausfall führen
+ TYPE_ALARM {
+ {
+ command = "alarm";
+ divisor = 1;
+ tagName = "I52";
+ type = Type.Word;
+ }
+ },
+
+ // German: Unterbrechungen
+ TYPE_INTERRUPTIONS {
+ {
+ command = "interruptions";
+ divisor = 1;
+ tagName = "I53";
+ type = Type.Word;
+ }
+ },
+
+ // German: Serviceebene (0: normal, 1: service)
+ TYPE_STATE_SERVICE {
+ {
+ command = "state_service";
+ divisor = 1;
+ tagName = "I135";
+ type = Type.Word;
+ }
+ },
+
+ // German: Temperaturanpassung für die Heizung
+ TYPE_ADAPT_HEATING {
+ {
+ command = "adapt_heating";
+ divisor = 1;
+ tagName = "I263";
+ type = Type.Word; // value range 0..8 => -2K .. +2K
+ }
+ },
+
+ // German: Raumeinfluss
+ TYPE_TEMP_ROOM_INFLUENCE {
+ {
+ command = "tempRoomInfluence";
+ divisor = 1;
+ tagName = "I264";
+ type = Type.Word; // value range 0..4 => 0%, 50%, 100%, 150%, 200%
+ }
+ },
+
+ // German: Handschaltung Heizungspumpe (H-0-A)
+ // H:Handschaltung Ein 0:Aus A:Automatik
+ // Kodierung: 0:? 1:? 2:Automatik
+ TYPE_MANUAL_HEATINGPUMP {
+ {
+ command = "manual_heatingpump";
+ divisor = 1;
+ tagName = "I1270";
+ type = Type.Word;
+ }
+ },
+
+ // German: Handschaltung Quellenpumpe (H-0-A)
+ TYPE_MANUAL_SOURCEPUMP {
+ {
+ command = "manual_sourcepump";
+ divisor = 1;
+ tagName = "I1281";
+ type = Type.Word;
+ }
+ },
+
+ // German: Handschaltung Solarpumpe 1 (H-0-A)
+ TYPE_MANUAL_SOLARPUMP1 {
+ {
+ command = "manual_solarpump1";
+ divisor = 1;
+ tagName = "I1287";
+ type = Type.Word;
+ }
+ },
+
+ // German: Handschaltung Solarpumpe 2 (H-0-A)
+ TYPE_MANUAL_SOLARPUMP2 {
+ {
+ command = "manual_solarpump2";
+ divisor = 1;
+ tagName = "I1289";
+ type = Type.Word;
+ }
+ },
+
+ // German: Handschaltung Speicherladepumpe (H-0-A)
+ TYPE_MANUAL_TANKPUMP {
+ {
+ command = "manual_tankpump";
+ divisor = 1;
+ tagName = "I1291";
+ type = Type.Word;
+ }
+ },
+
+ // German: Handschaltung Brauchwasserventil (H-0-A)
+ TYPE_MANUAL_VALVE {
+ {
+ command = "manual_valve";
+ divisor = 1;
+ tagName = "I1293";
+ type = Type.Word;
+ }
+ },
+
+ // German: Handschaltung Poolventil (H-0-A)
+ TYPE_MANUAL_POOLVALVE {
+ {
+ command = "manual_poolvalve";
+ divisor = 1;
+ tagName = "I1295";
+ type = Type.Word;
+ }
+ },
+
+ // German: Handschaltung Kühlventil (H-0-A)
+ TYPE_MANUAL_COOLVALVE {
+ {
+ command = "manual_coolvalve";
+ divisor = 1;
+ tagName = "I1297";
+ type = Type.Word;
+ }
+ },
+
+ // German: Handschaltung Vierwegeventil (H-0-A)
+ TYPE_MANUAL_4WAYVALVE {
+ {
+ command = "manual_4wayvalve";
+ divisor = 1;
+ tagName = "I1299";
+ type = Type.Word;
+ }
+ },
+
+ // German: Handschaltung Multiausgang Ext. (H-0-A)
+ TYPE_MANUAL_MULTIEXT {
+ {
+ command = "manual_multiext";
+ divisor = 1;
+ tagName = "I1319";
+ type = Type.Word;
+ }
+ },
+
+ // German: Umgebung
+ TYPE_TEMPERATURE_SURROUNDING {
+ {
+ command = "temperature_surrounding";
+ unit = CELSIUS;
+ tagName = "I2020";
+ type = Type.Analog;
+ divisor = 100;
+ }
+ },
+
+ // German: Sauggas
+ TYPE_TEMPERATURE_SUCTION_AIR {
+ {
+ command = "temperature_suction_air";
+ unit = CELSIUS;
+ tagName = "I2021";
+ type = Type.Analog;
+ divisor = 100;
+ }
+ },
+
+ // German: Ölsumpf
+ TYPE_TEMPERATURE_SUMP {
+ {
+ command = "temperature_sump";
+ unit = CELSIUS;
+ tagName = "I2023";
+ type = Type.Analog;
+ divisor = 100;
+ }
+ },
+
+ //
+ // The following tags are only available, if an Ecovent System is attached to the Ecotouch
+ //
+
+ // German: Abluft
+ // Waterkotte reference: airventilation-temperature-1
+ TYPE_ECOVENT_TEMP_EXHAUST_AIR {
+ {
+ command = "ecovent_temp_exhaust_air";
+ unit = CELSIUS;
+ tagName = "3:HREG400000";
+ type = Type.Float;
+ divisor = 1;
+ }
+ },
+
+ // German: Fortluft
+ // Waterkotte reference: airventilation-temperature-2
+ TYPE_ECOVENT_TEMP_EXIT_AIR {
+ {
+ command = "ecovent_temp_exit_air";
+ unit = CELSIUS;
+ tagName = "3:HREG400002";
+ type = Type.Float;
+ divisor = 1;
+ }
+ },
+
+ // German: Außenluft
+ // Waterkotte reference: airventilation-temperature-3
+ TYPE_ECOVENT_TEMP_OUTDOOR_AIR {
+ {
+ command = "ecovent_temp_outdoor_air";
+ unit = CELSIUS;
+ tagName = "3:HREG400004";
+ type = Type.Float;
+ divisor = 1;
+ }
+ },
+
+ // German: Zuluft
+ // Waterkotte reference: airventilation-temperature-4
+ TYPE_ECOVENT_TEMP_SUPPLY_AIR {
+ {
+ command = "ecovent_temp_supply_air";
+ unit = CELSIUS;
+ tagName = "3:HREG400006";
+ type = Type.Float;
+ divisor = 1;
+ }
+ },
+
+ // German: CO2
+ // Waterkotte reference: airventilation-co2-value
+ TYPE_ECOVENT_CO2_VALUE {
+ {
+ command = "ecovent_CO2_value";
+ unit = PARTS_PER_MILLION;
+ tagName = "3:HREG400008";
+ type = Type.Float;
+ divisor = 1;
+ }
+ },
+
+ // German: Luftfeuchtigkeit
+ // Waterkotte reference: airventilation-air-moisture-value
+ TYPE_ECOVENT_MOISTURE_VALUE {
+ {
+ command = "ecovent_moisture_value";
+ unit = PARTS_PER_MILLION;
+ tagName = "3:HREG400010";
+ type = Type.Float;
+ divisor = 1;
+ }
+ },
+
+ // German: Lüfterdrehzahl
+ // Waterkotte reference: airventilation-analog-output-y1
+ TYPE_ECOVENT_OUTPUT_Y1 {
+ {
+ command = "ecovent_output_y1";
+ unit = PERCENT;
+ tagName = "3:HREG400014";
+ type = Type.Float;
+ divisor = 1;
+ }
+ },
+
+ TYPE_ECOVENT_MODE {
+ {
+ command = "ecovent_mode";
+ tagName = "I4582";
+ type = Type.Word; // Type.Enum;
+ divisor = 1;
+ stringEnum = new String[] { "Day Mode", "Night Mode", "Timer Mode", "Party Mode", "Vacation Mode",
+ "Bypass Mode" };
+ }
+ },
+
+ ;
+
+ /**
+ * Represents the heatpump command as it will be used in *.items
+ * configuration
+ */
+ String command;
+ /**
+ * Represents the internal raw heatpump command as it will be used in
+ * querying the heat pump
+ */
+ String tagName;
+
+ Unit> unit = ONE;
+
+ /**
+ * The heatpump always returns 16-bit integers encoded as ASCII. They need
+ * to be interpreted according to the context.
+ * The EcoVent unit returns floating point numbers.
+ */
+ public enum Type {
+ Analog,
+ Word,
+ Bitfield,
+ Float,
+ Enum
+ };
+
+ /**
+ * The format of the response of the heat pump
+ */
+ Type type = Type.Analog;
+
+ /**
+ * If \c type is Type.Bitfield, this determines the bit number (0-based)
+ */
+ int bitnum = 0;
+
+ /**
+ * If type is anything else than {@link Type#Bitfield} this is used as divisor for the scaled integer.
+ * Defaults to 10 and should be a power of 10 (e.g. 10, 100, 1000).
+ */
+ int divisor = 10;
+
+ /**
+ * If \c type is Type.Enum, this defines the meaning of the values (0-based)
+ */
+ String[] stringEnum = null;
+
+ /**
+ * @return command name (uses in *.items files)
+ */
+ public String getCommand() {
+ return command;
+ }
+
+ /**
+ * @return tag name (raw communication with heat pump)
+ */
+ public String getTagName() {
+ return tagName;
+ }
+
+ /**
+ * @return type: how to interpret the response from the heat pump
+ */
+ public Type getType() {
+ return type;
+ }
+
+ /**
+ * @return bitnum: if the value is a bit field, this indicates the bit
+ * number (0-based)
+ */
+ public int getBitNum() {
+ return bitnum;
+ }
+
+ /**
+ * @return Divisor for scaled integer analog values.
+ */
+ public int getDivisor() {
+ return divisor;
+ }
+
+ public Unit> getUnit() {
+ return unit;
+ }
+
+ /**
+ *
+ * @param bindingConfig
+ * command e.g. TYPE_TEMPERATURE_OUTSIDE,..
+ * @param itemClass
+ * class to validate
+ * @return true if item class can bound to heatpumpCommand
+ */
+ // public static boolean validateBinding(EcoTouchTags bindingConfig, Class extends Item> itemClass) {
+ // boolean ret = false;
+ // for (EcoTouchTags c : EcoTouchTags.values()) {
+ // if (c.getCommand().equals(bindingConfig.getCommand()) && c.getItemClass().equals(itemClass)) {
+ // ret = true;
+ // break;
+ // }
+ // }
+ // return ret;
+ // }
+
+ /**
+ * Decode a raw value from the heat pump's ethernet interface into a scaled value
+ *
+ * @param rawValue
+ * @return
+ */
+ public BigDecimal decodeValue(String rawValue) {
+ BigDecimal raw = new BigDecimal(rawValue);
+ if (type == Type.Bitfield) {
+ // ignore any scaling from \ref divisor
+ int value = raw.intValue();
+ if ((value & (1 << bitnum)) != 0)
+ return BigDecimal.ONE;
+ else
+ return BigDecimal.ZERO;
+ }
+ BigDecimal result = raw.divide(new BigDecimal(divisor));
+ return result;
+ }
+
+ /**
+ * Searches the available heat pump commands and returns the matching one.
+ *
+ * @param heatpumpCommand
+ * command string e.g. "temperature_outside"
+ * @return matching EcoTouchTags instance, if available
+ */
+ public static EcoTouchTags fromString(String heatpumpCommand) {
+ if ("".equals(heatpumpCommand)) {
+ return null;
+ }
+ for (EcoTouchTags c : EcoTouchTags.values()) {
+ if (c.getCommand().equals(heatpumpCommand)) {
+ return c;
+ }
+ }
+
+ throw new IllegalArgumentException("cannot find EcoTouch tag for '" + heatpumpCommand + "'");
+ }
+
+ /**
+ * Searches the available heat pump commands and returns the first matching
+ * one.
+ *
+ * @param tag
+ * raw heatpump tag e.g. "A1"
+ * @return first matching EcoTouchTags instance, if available
+ */
+ public static List fromTag(String tag) {
+ List result = new LinkedList();
+ for (EcoTouchTags c : EcoTouchTags.values()) {
+ if (c.getTagName().equals(tag)) {
+ result.add(c);
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/bundles/org.openhab.binding.ecotouch/src/main/resources/OH-INF/binding/binding.xml b/bundles/org.openhab.binding.ecotouch/src/main/resources/OH-INF/binding/binding.xml
new file mode 100644
index 0000000000000..5fc729e7039a2
--- /dev/null
+++ b/bundles/org.openhab.binding.ecotouch/src/main/resources/OH-INF/binding/binding.xml
@@ -0,0 +1,10 @@
+
+
+
+ EcoTouch Binding
+ This is the binding for a Waterkotte EcoTouch heat pump.
+ Sebastian Held
+
+
diff --git a/bundles/org.openhab.binding.ecotouch/src/main/resources/OH-INF/i18n/ecotouch_de.properties b/bundles/org.openhab.binding.ecotouch/src/main/resources/OH-INF/i18n/ecotouch_de.properties
new file mode 100644
index 0000000000000..6455c7370031b
--- /dev/null
+++ b/bundles/org.openhab.binding.ecotouch/src/main/resources/OH-INF/i18n/ecotouch_de.properties
@@ -0,0 +1,247 @@
+# binding
+binding.ecotouch.name = EcoTouch Binding
+binding.ecotouch.description = �berwachung und Steuerung von Waterkotte EcoTouch W�rmepumpen
+
+# thing types (geo)
+thing-type.ecotouch.geo.label = Waterkotte EcoTouch Geo
+thing-type.ecotouch.geo.description = Waterkotte EcoTouch Geo Erdw�rmepumpe
+
+# thing types (air)
+thing-type.ecotouch.air.label = Waterkotte EcoTouch Air
+thing-type.ecotouch.air.description = Waterkotte EcoTouch Air Luftw�rmepumpe
+
+# thing type config description (geo)
+thing-type.config.ecotouch.geo.ip.label = IP Adresse / Hostname
+thing-type.config.ecotouch.geo.ip.description = IP Adresse oder Hostname der EcoTouch Anzeigeeinheit
+thing-type.config.ecotouch.geo.username.label = Login Benutzername
+thing-type.config.ecotouch.geo.username.description = Seit Software Version 1.6.xx der Anzeigeeinheit ist der Benutzername "waterkotte". Davor war es "admin".
+thing-type.config.ecotouch.geo.password.label = Login Passwort
+thing-type.config.ecotouch.geo.password.description = Seit Software Version 1.6.xx der Anzeigeeinheit ist das Passwort "waterkotte". Davor war es "wtkadmin".
+
+# thing type config description (air)
+thing-type.config.ecotouch.air.ip.label = IP Adresse / Hostname
+thing-type.config.ecotouch.air.ip.description = IP Adresse oder Hostname der EcoTouch Anzeigeeinheit
+thing-type.config.ecotouch.air.username.label = Login Benutzername
+thing-type.config.ecotouch.air.username.description = Seit Software Version 1.6.xx der Anzeigeeinheit ist der Benutzername "waterkotte". Davor war es "admin".
+thing-type.config.ecotouch.air.password.label = Login Passwort
+thing-type.config.ecotouch.air.password.description = Seit Software Version 1.6.xx der Anzeigeeinheit ist das Passwort "waterkotte". Davor war es "wtkadmin".
+
+# channel types
+channel-type.ecotouch.temperature_outside.label = Au�entemperatur
+channel-type.ecotouch.temperature_outside.description = Aktuelle Au�entemperatur
+channel-type.ecotouch.temperature_outside_1h.label = Au�entemperatur gemittelt 1h
+channel-type.ecotouch.temperature_outside_1h.description = Au�entemperatur gemittelt �ber 1 Stunde
+channel-type.ecotouch.temperature_outside_24h.label = Au�entemperatur gemittelt 24h
+channel-type.ecotouch.temperature_outside_24h.description = Au�entemperatur gemittelt �ber 24 Stunden
+channel-type.ecotouch.temperature_source_in.label = Quelleneintrittstemperatur
+channel-type.ecotouch.temperature_source_in.description = Quelleneintrittstemperatur
+channel-type.ecotouch.temperature_source_out.label = Quellenaustrittstemperatur
+channel-type.ecotouch.temperature_source_out.description = Quellenaustrittstemperatur
+channel-type.ecotouch.temperature_evaporation.label = Verdampfungstemperatur
+channel-type.ecotouch.temperature_evaporation.description = Verdampfungstemperatur
+channel-type.ecotouch.temperature_suction.label = Sauggastemperatur
+channel-type.ecotouch.temperature_suction.description = Sauggastemperatur
+channel-type.ecotouch.pressure_evaporation.label = Verdampfungsdruck
+channel-type.ecotouch.pressure_evaporation.description = Verdampfungsdruck
+channel-type.ecotouch.temperature_return_set.label = Temperatur R�cklauf Soll
+channel-type.ecotouch.temperature_return_set.description = Temperatur R�cklauf Soll
+channel-type.ecotouch.temperature_return.label = R�cklauftemperatur
+channel-type.ecotouch.temperature_return.description = R�cklauftemperatur
+channel-type.ecotouch.temperature_flow.label = Vorlauftemperatur
+channel-type.ecotouch.temperature_flow.description = Vorlauftemperatur
+channel-type.ecotouch.temperature_condensation.label = Kondensationstemperatur
+channel-type.ecotouch.temperature_condensation.description = Kondensationstemperatur
+channel-type.ecotouch.pressure_condensation.label = Kondensationsdruck
+channel-type.ecotouch.pressure_condensation.description = Kondensationsdruck
+channel-type.ecotouch.temperature_storage.label = Speichertemperatur
+channel-type.ecotouch.temperature_storage.description = Speichertemperatur
+channel-type.ecotouch.temperature_room.label = Raumtemperatur
+channel-type.ecotouch.temperature_room.description = Raumtemperatur
+channel-type.ecotouch.temperature_room_1h.label = Raumtemperatur gemittelt 1h
+channel-type.ecotouch.temperature_room_1h.description = Raumtemperatur gemittelt �ber 1 Stunde
+channel-type.ecotouch.temperature_water.label = Warmwassertemperatur
+channel-type.ecotouch.temperature_water.description = Aktuelle Temperatur im Warmwasserspeicher
+channel-type.ecotouch.temperature_pool.label = Pool-Temperatur
+channel-type.ecotouch.temperature_pool.description = Pool-Temperatur
+channel-type.ecotouch.temperature_solarlabel = Solarkollektortemperatur
+channel-type.ecotouch.temperature_solar.description = Solarkollektortemperatur
+channel-type.ecotouch.temperature_solar_flow.label = Solarkreis Vorlauftemperatur
+channel-type.ecotouch.temperature_solar_flow.description = Solarkreis Vorlauftemperatur
+channel-type.ecotouch.position_expansion_valve.label = Ventil�ffnung el. Expansionsventil
+channel-type.ecotouch.position_expansion_valve.description = Ventil�ffnung elektrisches Expansionsventil
+channel-type.ecotouch.power_compressor.label = Elektrische Antriebsleitung Verdichter
+channel-type.ecotouch.power_compressor.description = Aktuelle elektrische Antriebsleitung f�r den Verdichter
+channel-type.ecotouch.power_heating.label = Thermische W�rmeleistungsabgabe
+channel-type.ecotouch.power_heating.description = Aktuelle abgegebene thermische Leistung der W�rmepumpe
+channel-type.ecotouch.power_cooling.label = Thermische K�lteleistungsabgabe
+channel-type.ecotouch.power_cooling.description = Aktuelle abgegebene thermische K�lteleistung der W�rmepumpe
+channel-type.ecotouch.cop_heating.label = COP heizen
+channel-type.ecotouch.cop_heating.description = Wirkungsgrad bzw. Leitungszahl heizen
+channel-type.ecotouch.cop_cooling.label = COP k�hlen
+channel-type.ecotouch.cop_cooling.description = Wirkungsgrad bzw. Leitungszahl k�hlen
+channel-type.ecotouch.temperature_heating_return.label = Heizkreistemperatur
+channel-type.ecotouch.temperature_heating_return.description = Aktuelle Heizkreistemperatur
+channel-type.ecotouch.temperature_heating_set.label = Sollwert Heizbetrieb
+channel-type.ecotouch.temperature_heating_set.description = Geforderte Temperatur im Heizbetrieb
+channel-type.ecotouch.temperature_heating_set2.label = BMS Sollwert Heizbetrieb
+channel-type.ecotouch.temperature_heating_set2.description = Geforderte Heizkreistemperatur vom BMS
+channel-type.ecotouch.temperature_cooling_return.label = K�hlkreistemperatur
+channel-type.ecotouch.temperature_cooling_return.description = Aktuelle K�hlkreistemperatur
+channel-type.ecotouch.temperature_cooling_set.label = Sollwert K�hlkreistemperatur
+channel-type.ecotouch.temperature_cooling_set.description = Geforderte K�hlkreistemperatur
+channel-type.ecotouch.temperature_cooling_set2.label = BMS Sollwert K�hlkreistemperatur
+channel-type.ecotouch.temperature_cooling_set2.description = Geforderte K�hlkreistemperatur vom BMS
+channel-type.ecotouch.temperature_water_set.label = Sollwert Warmwasserspeicher
+channel-type.ecotouch.temperature_water_set.description = Geforderte Temperatur im Warmwasserspeicher
+channel-type.ecotouch.temperature_water_set2.label = BMS Sollwert Warmwasserspeicher
+channel-type.ecotouch.temperature_water_set2.description = Solltemperatur im Warmwasserspeicher vom BMS
+channel-type.ecotouch.temperature_pool_set.label = Sollwert Pool-Temperatur
+channel-type.ecotouch.temperature_pool_set.description = Geforderte Poolwasser-Temperatur
+channel-type.ecotouch.temperature_pool_set2.label = BMS Sollwert Pool-Temperatur
+channel-type.ecotouch.temperature_pool_set2.description = Geforderte Poolwasser-Temperatur vom BMS
+channel-type.ecotouch.compressor_power.label = Sollwert Verdichter
+channel-type.ecotouch.compressor_power.description = Geforderte Verdichterleistung
+channel-type.ecotouch.percent_heat_circ_pump.label = Aktivit�t Heizungsumw�lzpumpe
+channel-type.ecotouch.percent_heat_circ_pump.description = Aktivit�t Heizungsumw�lzpumpe
+channel-type.ecotouch.percent_source_pump.label = Aktivit�t Quellenpumpe
+channel-type.ecotouch.percent_source_pump.description = Aktivit�t Quellenpumpe
+channel-type.ecotouch.percent_compressor.label = Aktivit�t Verdichter
+channel-type.ecotouch.percent_compressor.description = Aktivit�t Verdichter
+channel-type.ecotouch.hysteresis_heating.label = Hysterese Heizung
+channel-type.ecotouch.hysteresis_heating.description = Hysterese Heizung
+channel-type.ecotouch.temperature2_outside_1h.label = Au�entemperatur gemittelt 1h (A90)
+channel-type.ecotouch.temperature2_outside_1h.description = Au�entemperatur gemittelt �ber 1 Stunde (A90)
+channel-type.ecotouch.nviNormAussen.label = Heizkurve - nviNormAussen
+channel-type.ecotouch.nviNormAussen.description = Heizkurve - nviNormAussen
+channel-type.ecotouch.nviHeizkreisNorm.label = Heizkurve - nviHeizkreisNorm
+channel-type.ecotouch.nviHeizkreisNorm.description = Heizkurve - nviHeizkreisNorm
+channel-type.ecotouch.nviTHeizgrenze.label = Heizkurve - nviTHeizgrenze
+channel-type.ecotouch.nviTHeizgrenze.description = Heizkurve - nviTHeizgrenze
+channel-type.ecotouch.nviTHeizgrenzeSoll.label = Heizkurve - nviTHeizgrenzeSoll
+channel-type.ecotouch.nviTHeizgrenzeSoll.description = Heizkurve - nviTHeizgrenzeSoll
+channel-type.ecotouch.maxVLTemp.label = Heizkurve max. VL-Temp (?)
+channel-type.ecotouch.maxVLTemp.description = Heizkurve max. VL-Temp (?)
+channel-type.ecotouch.tempSet0Deg.label = Heizkreis Soll-Temp 0�C
+channel-type.ecotouch.tempSet0Deg.description = Heizkreis Soll-Temp bei 0�C Au�entemperatur
+channel-type.ecotouch.coolEnableTemp.label = K�hlen Einschalt-Temp. Au�entemp (?)
+channel-type.ecotouch.coolEnableTemp.description = K�hlen Einschalt-Temp. Au�entemp (?)
+channel-type.ecotouch.nviSollKuehlen.label = Heizkurve - nviSollKuehlen
+channel-type.ecotouch.nviSollKuehlen.description = Heizkurve - nviSollKuehlen
+channel-type.ecotouch.tempchange_heating_pv.label = �nderung Heizkreis PV
+channel-type.ecotouch.tempchange_heating_pv.description = Temperaturver�nderung Heizkreis bei PV-Ertrag
+channel-type.ecotouch.tempchange_cooling_pv.label = �nderung K�hlkreis PV
+channel-type.ecotouch.tempchange_cooling_pv.description = Temperaturver�nderung K�hlkreis bei PV-Ertrag
+channel-type.ecotouch.tempchange_warmwater_pv.label = �nderung Warmwasser PV
+channel-type.ecotouch.tempchange_warmwater_pv.description = Temperaturver�nderung Warmwasser bei PV-Ertrag
+channel-type.ecotouch.tempchange_pool_pv.label = �nderung Pool PV
+channel-type.ecotouch.tempchange_pool_pv.description = Temperaturver�nderung Pool bei PV-Ertrag
+channel-type.ecotouch.version_controller.label = Firmware-Version Regler
+channel-type.ecotouch.version_controller.description = Firmware-Version Regler
+channel-type.ecotouch.version_controller_build.label = Firmware-Build Regler
+channel-type.ecotouch.version_controller_build.description = Firmware-Build Regler
+channel-type.ecotouch.version_bios.label = BIOS-Version
+channel-type.ecotouch.version_bios.description = BIOS-Version
+channel-type.ecotouch.date_day.label = Datum: Tag
+channel-type.ecotouch.date_day.description = Datum: Tag
+channel-type.ecotouch.date_month.label = Datum: Monat
+channel-type.ecotouch.date_month.description = Datum: Monat
+channel-type.ecotouch.date_year.label = Datum: Jahr
+channel-type.ecotouch.date_year.description = Datum: Jahr
+channel-type.ecotouch.time_hour.label = Uhrzeit: Stunde
+channel-type.ecotouch.time_hour.description = Uhrzeit: Stunde
+channel-type.ecotouch.time_minute.label = Uhrzeit: Minute
+channel-type.ecotouch.time_minute.description = Uhrzeit: Minute
+channel-type.ecotouch.operating_hours_compressor1.label = Stunden Verdichter 1
+channel-type.ecotouch.operating_hours_compressor1.description = Betriebsstunden Verdichter 1
+channel-type.ecotouch.operating_hours_compressor2.label = Stunden Verdichter 2
+channel-type.ecotouch.operating_hours_compressor2.description = Betriebsstunden Verdichter 2
+channel-type.ecotouch.operating_hours_circulation_pump.label = Stunden Heizungsumw�lzpumpe
+channel-type.ecotouch.operating_hours_circulation_pump.description = Betriebsstunden Heizungsumw�lzpumpe
+channel-type.ecotouch.operating_hours_source_pump.label = Stunden Quellenpumpe
+channel-type.ecotouch.operating_hours_source_pump.description = Betriebsstunden Quellenpumpe
+channel-type.ecotouch.operating_hours_solar.label = Stunden Solarkreis
+channel-type.ecotouch.operating_hours_solar.description = Betriebsstunden Solarkreis
+channel-type.ecotouch.enable_heating.label = Abschaltung Heizen
+channel-type.ecotouch.enable_heating.description = Handabschaltung Heizbetrieb
+channel-type.ecotouch.enable_cooling.label = Abschaltung K�hlen
+channel-type.ecotouch.enable_cooling.description = Handabschaltung K�hlbetrieb
+channel-type.ecotouch.enable_warmwater.label = Abschaltung Warmwasser
+channel-type.ecotouch.enable_warmwater.description = Handabschaltung Warmwasserbetrieb
+channel-type.ecotouch.enable_pool.label = Abschaltung Pool
+channel-type.ecotouch.enable_pool.description = Handabschaltung Pool_Heizbetrieb
+channel-type.ecotouch.enable_pv.label = Abschaltung PV
+channel-type.ecotouch.enable_pv.description = Betriebsmodus PV
+channel-type.ecotouch.state.label = Status W�rmepumpe
+channel-type.ecotouch.state.description = Status der W�rmepumpenkomponenten (Bitfeld, siehe auch die Einzelzust�nde)
+channel-type.ecotouch.state_sourcepump.label = Status Quellenpumpe
+channel-type.ecotouch.state_sourcepump.description = Status der W�rmepumpenkomponenten: Quellenpumpe
+channel-type.ecotouch.state_heatingpump.label = Status Heizungsumw�lzpumpe
+channel-type.ecotouch.state_heatingpump.description = Status der W�rmepumpenkomponenten: Heizungsumw�lzpumpe
+channel-type.ecotouch.state_evd.label = Status el. Expansionsventil
+channel-type.ecotouch.state_evd.description = Status der W�rmepumpenkomponenten: el. Expansionsventil
+channel-type.ecotouch.state_compressor1.label = Status Verdichter 1
+channel-type.ecotouch.state_compressor1.description = Status der W�rmepumpenkomponenten: Verdichter 1
+channel-type.ecotouch.state_compressor2.label = Status Verdichter 2
+channel-type.ecotouch.state_compressor2.description = Status der W�rmepumpenkomponenten: Verdichter 2
+channel-type.ecotouch.state_extheater.label = Status ext. W�rmeerzeuger
+channel-type.ecotouch.state_extheater.description = Status der W�rmepumpenkomponenten: externer W�rmeerzeuger
+channel-type.ecotouch.state_alarm.label = Status Alarmausgang
+channel-type.ecotouch.state_alarm.description = Status der W�rmepumpenkomponenten: Alarmausgang
+channel-type.ecotouch.state_cooling.label = Status Motorventil K�hlen
+channel-type.ecotouch.state_cooling.description = Status der W�rmepumpenkomponenten: Motorventil K�hlbetrieb
+channel-type.ecotouch.state_water.label = Status Motorventil Wasser
+channel-type.ecotouch.state_water.description = Status der W�rmepumpenkomponenten: Motorventil Warmwasser
+channel-type.ecotouch.state_pool.label = Status Motorventil Pool
+channel-type.ecotouch.state_pool.description = Status der W�rmepumpenkomponenten: Motorventil Pool
+channel-type.ecotouch.state_solar.label = Status Solarbetrieb
+channel-type.ecotouch.state_solar.description = Status der W�rmepumpenkomponenten: Solarbetrieb
+channel-type.ecotouch.state_cooling4way.label = Status 4-Wegeventil
+channel-type.ecotouch.state_cooling4way.description = Status der W�rmepumpenkomponenten: 4-Wegeventil im K�ltekreis
+channel-type.ecotouch.alarm.label = Alarmmeldungen
+channel-type.ecotouch.alarm.description = Meldungen von Ausf�llen F0xx die zum W�rmepumpenausfall f�hren
+channel-type.ecotouch.interruptions.label = Unterbrechungen
+channel-type.ecotouch.interruptions.description = Unterbrechungen
+channel-type.ecotouch.state_service.label = Serviceebene
+channel-type.ecotouch.state_service.description = Serviceebene
+channel-type.ecotouch.adapt_heating.label = Temperaturanpassung heizen
+channel-type.ecotouch.adapt_heating.description = Temperaturanpassung f�r die Heizung
+channel-type.ecotouch.manual_heatingpump.label = Heizungspumpe
+channel-type.ecotouch.manual_heatingpump.description = Handschaltung Heizungspumpe
+channel-type.ecotouch.manual_sourcepump.label = Quellenpumpe
+channel-type.ecotouch.manual_sourcepump.description = Handschaltung Quellenpumpe
+channel-type.ecotouch.manual_solarpump1.label = Solarpumpe 1
+channel-type.ecotouch.manual_solarpump1.description = Handschaltung Solarpumpe 1
+channel-type.ecotouch.manual_solarpump2.label = Solarpumpe 2
+channel-type.ecotouch.manual_solarpump2.description = Handschaltung Solarpumpe 2
+channel-type.ecotouch.manual_tankpump.label = Speicherpumpe
+channel-type.ecotouch.manual_tankpump.description = Handschaltung Speicherladepumpe
+channel-type.ecotouch.manual_valve.label = Brauchwasserventil
+channel-type.ecotouch.manual_valve.description = Handschaltung Brauchwasserventil
+channel-type.ecotouch.manual_poolvalve.label = Poolventil
+channel-type.ecotouch.manual_poolvalve.description = Handschaltung Poolventil
+channel-type.ecotouch.manual_coolvalve.label = K�hlventil
+channel-type.ecotouch.manual_coolvalve.description = Handschaltung K�hlventil
+channel-type.ecotouch.manual_4wayvalve.label = Vierwegeventil
+channel-type.ecotouch.manual_4wayvalve.description = Handschaltung Vierwegeventil
+channel-type.ecotouch.manual_multiext.label = Multiausgang Ext.
+channel-type.ecotouch.manual_multiext.description = Handschaltung Multiausgang Ext.
+channel-type.ecotouch.temperature_surrounding.label = Temperatur Umgebung
+channel-type.ecotouch.temperature_surrounding.description = Temperatur Umgebung
+channel-type.ecotouch.temperature_suction_air.label = Temperatur Sauggas
+channel-type.ecotouch.temperature_suction_air.description = Temperatur Sauggas
+channel-type.ecotouch.temperature_sump.label = Temperatur �lsumpf
+channel-type.ecotouch.temperature_sump.description = Temperatur �lsumpf
+channel-type.ecotouch.ecovent_temp_exhaust_air.label = EcoVent Abluft
+channel-type.ecotouch.ecovent_temp_exhaust_air.description = EcoVent Abluft
+channel-type.ecotouch.ecovent_temp_exit_air.label = EcoVent Fortluft
+channel-type.ecotouch.ecovent_temp_exit_air.description = EcoVent Fortluft
+channel-type.ecotouch.ecovent_temp_outdoor_air.label = EcoVent Au�enluft
+channel-type.ecotouch.ecovent_temp_outdoor_air.description = EcoVent Au�enluft
+channel-type.ecotouch.ecovent_temp_supply_air.label = EcoVent Zuluft
+channel-type.ecotouch.ecovent_temp_supply_air.description = EcoVent Zuluft
+channel-type.ecotouch.ecovent_CO2_value.label = EcoVent CO2
+channel-type.ecotouch.ecovent_CO2_value.description = EcoVent CO2
+channel-type.ecotouch.ecovent_moisture_value.label = EcoVent Luftfeuchtigkeit
+channel-type.ecotouch.ecovent_moisture_value.description = EcoVent Luftfeuchtigkeit
+channel-type.ecotouch.ecovent_output_y1.label = EcoVent L�fterdrehzahl
+channel-type.ecotouch.ecovent_output_y1.description = EcoVent L�fterdrehzahl
diff --git a/bundles/org.openhab.binding.ecotouch/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.ecotouch/src/main/resources/OH-INF/thing/thing-types.xml
new file mode 100644
index 0000000000000..1272f90c89c31
--- /dev/null
+++ b/bundles/org.openhab.binding.ecotouch/src/main/resources/OH-INF/thing/thing-types.xml
@@ -0,0 +1,943 @@
+
+
+
+
+
+ Waterkotte EcoTouch Geo heat pump
+ HVAC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ network-address
+
+ Enter the IP address or the hostname of the EcoTouch display unit
+
+
+
+ Since Waterkotte Display software version 1.6.xx, the username default value is waterkotte. Prior to
+ that, the username default was admin
+
+
+ password
+
+ Since Waterkotte Display software version 1.6.xx, the password default value is waterkotte. Prior to
+ that, the password default was wtkadmin
+
+
+ 60
+
+ This is the refresh interval in seconds for all channels.
+
+
+
+
+
+
+
+ Waterkotte EcoTouch Air heat pump
+ HVAC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ network-address
+
+ Enter the IP address or the hostname of the EcoTouch display unit
+
+
+
+ Since Waterkotte Display software version 1.6.xx, the username default value is waterkotte. Prior to
+ that, the username default was admin
+
+
+ password
+
+ Since Waterkotte Display software version 1.6.xx, the password default value is waterkotte. Prior to
+ that, the password default was wtkadmin
+
+
+ 60
+
+ This is the refresh interval in seconds for all channels.
+
+
+
+
+
+
+ Number:Temperature
+
+ The current outside temperature
+ Temperature
+
+
+
+ Number:Temperature
+
+ The outside temperature averaged over one hour
+ Temperature
+
+
+
+ Number:Temperature
+
+ The outside temperature averaged over one day
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Pressure
+
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Pressure
+
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Dimensionless
+
+
+
+
+ Number:Power
+
+
+
+
+ Number:Power
+
+
+
+
+ Number:Power
+
+
+
+
+ Number:Dimensionless
+
+
+
+
+ Number:Dimensionless
+
+
+
+
+ Number:Temperature
+
+ Temperature Heating Return
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature Heating Setpoint
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature Heating Setpoint BMS
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature Cooling Return
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature Cooling Setpoint
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature Cooling Setpoint BMS
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature Water Setpoint
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature Water Setpoint BMS
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature Pool Setpoint
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature Pool Setpoint BMS
+ Temperature
+
+
+
+ Number:Dimensionless
+
+
+
+
+ Number:Dimensionless
+
+ Percent Heating Circulation Pump
+
+
+
+ Number:Dimensionless
+
+
+
+
+ Number:Dimensionless
+
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature Outside 1h Average (A90)
+ Temperature
+
+
+
+ Number:Temperature
+
+
+
+
+ Number:Temperature
+
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Heating Setpoint at 0°C Outside
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature Change Heating if PV
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature Change Cooling if PV
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature Change Water if PV
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature Change Pool if PV
+ Temperature
+
+
+
+ Number:Dimensionless
+
+ Version Display Controller
+
+
+
+ Number:Dimensionless
+
+ Build Number Display Controller
+
+
+
+ Number:Dimensionless
+
+
+
+
+ Number:Dimensionless
+
+
+
+
+ Number:Dimensionless
+
+
+
+
+ Number:Dimensionless
+
+
+
+
+ Number:Dimensionless
+
+
+
+
+ Number:Dimensionless
+
+
+
+
+ Number:Time
+
+ Operating Hours Compressor 1
+
+
+
+ Number:Time
+
+ Operating Hours Compressor 2
+
+
+
+ Number:Time
+
+ Operating Hours Circulation Pump
+
+
+
+ Number:Time
+
+ Operating Hours Source Pump
+
+
+
+ Number:Time
+
+ Operating Hours Solar
+
+
+
+ Switch
+
+
+
+
+ Switch
+
+
+
+
+ Switch
+
+ Enable Warm Water
+
+
+
+ Switch
+
+
+
+
+ Switch
+
+
+
+
+ Number:Dimensionless
+
+ A Bitfield which encodes the state of all valves, pumps and compressors
+
+
+
+ Switch
+
+
+
+
+ Switch
+
+
+
+
+ Switch
+
+
+
+
+ Switch
+
+
+
+
+ Switch
+
+
+
+
+ Switch
+
+
+
+
+ Switch
+
+
+
+
+ Switch
+
+
+
+
+ Switch
+
+
+
+
+ Switch
+
+
+
+
+ Switch
+
+
+
+
+ Switch
+
+
+
+
+ Number:Dimensionless
+
+
+
+
+ Number:Dimensionless
+
+
+
+
+ Switch
+
+
+
+
+ Number:Temperature
+
+ Adjust the Heating Temperature by an Offset
+ Temperature
+
+
+
+ Number:Dimensionless
+
+ Operating Mode Heating Pump
+
+
+
+ Number:Dimensionless
+
+ Operating Mode Source Pump
+
+
+
+ Number:Dimensionless
+
+ Operating Mode Solar Pump
+
+
+
+ Number:Dimensionless
+
+ Operating Mode Solar Pump 2
+
+
+
+ Number:Dimensionless
+
+ Operating Mode Tank Pump
+
+
+
+ Number:Dimensionless
+
+ Operating Mode Valve
+
+
+
+ Number:Dimensionless
+
+ Operating Mode Pool Valve
+
+
+
+ Number:Dimensionless
+
+ Operating Mode Cooling Valve
+
+
+
+ Number:Dimensionless
+
+ Operating Mode 4Way Valve
+
+
+
+ Number:Dimensionless
+
+ Operating Mode Multi Ouput Ext
+
+
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+ Number:Temperature
+
+ Temperature
+
+
+
+
+
+ Number:Temperature
+
+ EcoVent Temperature Exhaust Air
+ Temperature
+
+
+
+ Number:Temperature
+
+ EcoVent Temperature Exit Air
+ Temperature
+
+
+
+ Number:Temperature
+
+ EcoVent Temperature Outdoor Air
+ Temperature
+
+
+
+ Number:Temperature
+
+ EcoVent Temperature Supply Air
+ Temperature
+
+
+
+ Number:Dimensionless
+
+
+
+
+ Number:Dimensionless
+
+
+
+
+ Number:Dimensionless
+
+
+
+
+ Number:Dimensionless
+
+ EcoVent Mode (0..5: Day, Night, Timer, Party, Vacation, Bypass)
+
+
+
+
diff --git a/bundles/pom.xml b/bundles/pom.xml
index 72196cd918725..0e0b3f6e77947 100644
--- a/bundles/pom.xml
+++ b/bundles/pom.xml
@@ -98,6 +98,7 @@
org.openhab.binding.dwdpollenflug
org.openhab.binding.dwdunwetter
org.openhab.binding.ecobee
+ org.openhab.binding.ecotouch
org.openhab.binding.elerotransmitterstick
org.openhab.binding.energenie
org.openhab.binding.enigma2