diff --git a/.homeycompose/capabilities/summer_winter.json b/.homeycompose/capabilities/summer_winter.json
new file mode 100644
index 0000000..4de903a
--- /dev/null
+++ b/.homeycompose/capabilities/summer_winter.json
@@ -0,0 +1,9 @@
+{
+ "title": {
+ "en": "Season"
+ },
+ "type": "string",
+ "getable": true,
+ "setable": false,
+ "uiComponent": "sensor"
+}
diff --git a/.homeycompose/capabilities/valve_cooling.json b/.homeycompose/capabilities/valve_cooling.json
new file mode 100644
index 0000000..5664a57
--- /dev/null
+++ b/.homeycompose/capabilities/valve_cooling.json
@@ -0,0 +1,10 @@
+{
+ "title": {
+ "en": "Cooling"
+ },
+ "type": "boolean",
+ "getable": true,
+ "setable": false,
+ "uiComponent": "sensor",
+ "uiQuickAction": false
+}
diff --git a/.homeycompose/capabilities/valve_heating.json b/.homeycompose/capabilities/valve_heating.json
new file mode 100644
index 0000000..9dec3e9
--- /dev/null
+++ b/.homeycompose/capabilities/valve_heating.json
@@ -0,0 +1,10 @@
+{
+ "title": {
+ "en": "Heating"
+ },
+ "type": "boolean",
+ "getable": true,
+ "setable": false,
+ "uiComponent": "sensor",
+ "uiQuickAction": false
+}
diff --git a/.homeycompose/capabilities/vimar_thermostat_mode.json b/.homeycompose/capabilities/vimar_thermostat_mode.json
new file mode 100644
index 0000000..47718e8
--- /dev/null
+++ b/.homeycompose/capabilities/vimar_thermostat_mode.json
@@ -0,0 +1,36 @@
+
+{
+ "type": "enum",
+ "title": {
+ "en": "Mode"
+ },
+ "values": [
+ {
+ "id": "1",
+ "title": {
+ "en": "Comfort"
+ }
+ },
+ {
+ "id": "2",
+ "title": {
+ "en": "Standby"
+ }
+ },
+ {
+ "id": "3",
+ "title": {
+ "en": "Economy"
+ }
+ },
+ {
+ "id": "4",
+ "title": {
+ "en": "Protect"
+ }
+ }
+ ],
+ "getable": true,
+ "setable": true,
+ "uiComponent": "picker"
+ }
\ No newline at end of file
diff --git a/.homeycompose/drivers/pair/select_groupaddresses/index.html b/.homeycompose/drivers/pair/select_groupaddresses/index.html
index 7ca418e..f42152d 100644
--- a/.homeycompose/drivers/pair/select_groupaddresses/index.html
+++ b/.homeycompose/drivers/pair/select_groupaddresses/index.html
@@ -1,571 +1,657 @@
diff --git a/app.json b/app.json
index fc1450f..5e71027 100644
--- a/app.json
+++ b/app.json
@@ -283,6 +283,39 @@
}
],
"id": "trigger_to_scene"
+ },
+ {
+ "id": "set-window-switch",
+ "title": {
+ "en": "Set Window Switch"
+ },
+ "args": [
+ {
+ "type": "device",
+ "name": "device",
+ "filter": "driver_id=vimar_thermostat_02952.b"
+ },
+ {
+ "type": "checkbox",
+ "name": "open",
+ "title": {
+ "en": "Window open"
+ }
+ }
+ ]
+ },
+ {
+ "id": "reset_to_basesetpoint",
+ "title": {
+ "en": "Reset to Base Setpoint"
+ },
+ "args": [
+ {
+ "type": "device",
+ "name": "device",
+ "filter": "driver_id=vimar_thermostat_02952.b"
+ }
+ ]
}
]
},
@@ -1843,6 +1876,201 @@
]
}
]
+ },
+ {
+ "images": {
+ "large": "/drivers/vimar_thermostat_02952.b/assets/images/large.png",
+ "small": "/drivers/vimar_thermostat_02952.b/assets/images/small.png"
+ },
+ "platforms": [
+ "local"
+ ],
+ "connectivity": [
+ "lan"
+ ],
+ "pair": [
+ {
+ "id": "select_interface",
+ "navigation": {
+ "next": "select_groupaddresses"
+ }
+ },
+ {
+ "id": "parse_knxproj",
+ "navigation": {
+ "next": "select_groupaddresses",
+ "prev": "select_groupaddresses"
+ }
+ },
+ {
+ "id": "select_groupaddresses",
+ "options": {
+ "devicetype": "vimar_thermostat_02952.b"
+ },
+ "navigation": {
+ "prev": "select_interface"
+ }
+ }
+ ],
+ "id": "vimar_thermostat_02952.b",
+ "name": {
+ "en": "Vimar Thermostat",
+ "nl": "Vimar Thermostaat"
+ },
+ "class": "thermostat",
+ "capabilities": [
+ "target_temperature",
+ "measure_temperature",
+ "vimar_thermostat_mode",
+ "valve_heating",
+ "valve_cooling",
+ "summer_winter"
+ ],
+ "settings": [
+ {
+ "type": "group",
+ "label": {
+ "en": "KNX groupaddress",
+ "nl": "KNX groepadressen"
+ },
+ "children": [
+ {
+ "id": "ga_temperature_target",
+ "type": "text",
+ "label": {
+ "en": "Setpoint Shift address"
+ },
+ "value": "",
+ "hint": {
+ "en": "Enter groupaddress"
+ }
+ },
+ {
+ "id": "ga_temperature_measure",
+ "type": "text",
+ "label": {
+ "en": "Actual Temperature address"
+ },
+ "value": "",
+ "hint": {
+ "en": "Enter groupaddress"
+ }
+ },
+ {
+ "id": "ga_temperature_target_actual",
+ "type": "text",
+ "label": {
+ "en": "Actual setpoint address"
+ },
+ "value": "",
+ "hint": {
+ "en": "Enter groupaddress"
+ }
+ },
+ {
+ "id": "ga_thermostat_mode",
+ "type": "text",
+ "label": {
+ "en": "Thermostat mode address"
+ },
+ "value": "",
+ "hint": {
+ "en": "Enter groupaddress"
+ }
+ },
+ {
+ "id": "ga_thermostat_mode_state",
+ "type": "text",
+ "label": {
+ "en": "Thermostat mode state address"
+ },
+ "value": "",
+ "hint": {
+ "en": "Enter groupaddress"
+ }
+ },
+ {
+ "id": "ga_summerwinter_state",
+ "type": "text",
+ "label": {
+ "en": "Summer/Winter state address"
+ },
+ "value": "",
+ "hint": {
+ "en": "Enter groupaddress"
+ }
+ },
+ {
+ "id": "ga_window_switch",
+ "type": "text",
+ "label": {
+ "en": "Window Switch address"
+ },
+ "value": "",
+ "hint": {
+ "en": "Enter groupaddress"
+ }
+ },
+ {
+ "id": "ga_valve_heating_state",
+ "type": "text",
+ "label": {
+ "en": "Heating Valve state address"
+ },
+ "value": "",
+ "hint": {
+ "en": "Enter groupaddress"
+ }
+ },
+ {
+ "id": "ga_valve_cooling_state",
+ "type": "text",
+ "label": {
+ "en": "Cooling Valve state address"
+ },
+ "value": "",
+ "hint": {
+ "en": "Enter groupaddress"
+ }
+ }
+ ]
+ },
+ {
+ "type": "group",
+ "label": {
+ "en": "Network settings",
+ "nl": "Netwerk instellingen"
+ },
+ "children": [
+ {
+ "id": "macAddress",
+ "type": "text",
+ "label": {
+ "en": "Interface MAC address",
+ "nl": "Interface MAC adres"
+ },
+ "value": "",
+ "hint": {
+ "en": "MAC address of the required KNX IP interface",
+ "nl": "MAC adres van de KNX IP interface"
+ }
+ },
+ {
+ "id": "ipAddress",
+ "type": "text",
+ "label": {
+ "en": "Interface IP address",
+ "nl": "Interface IP adres"
+ },
+ "value": "",
+ "hint": {
+ "en": "IP address of the required KNX IP interface",
+ "nl": "IP adres van de KNX IP interface"
+ }
+ }
+ ]
+ }
+ ]
}
],
"capabilities": {
@@ -1874,6 +2102,70 @@
"setable": true,
"uiComponent": "button",
"uiQuickAction": true
+ },
+ "summer_winter": {
+ "title": {
+ "en": "Season"
+ },
+ "type": "string",
+ "getable": true,
+ "setable": false,
+ "uiComponent": "sensor"
+ },
+ "valve_cooling": {
+ "title": {
+ "en": "Cooling"
+ },
+ "type": "boolean",
+ "getable": true,
+ "setable": false,
+ "uiComponent": "sensor",
+ "uiQuickAction": false
+ },
+ "valve_heating": {
+ "title": {
+ "en": "Heating"
+ },
+ "type": "boolean",
+ "getable": true,
+ "setable": false,
+ "uiComponent": "sensor",
+ "uiQuickAction": false
+ },
+ "vimar_thermostat_mode": {
+ "type": "enum",
+ "title": {
+ "en": "Mode"
+ },
+ "values": [
+ {
+ "id": "1",
+ "title": {
+ "en": "Comfort"
+ }
+ },
+ {
+ "id": "2",
+ "title": {
+ "en": "Standby"
+ }
+ },
+ {
+ "id": "3",
+ "title": {
+ "en": "Economy"
+ }
+ },
+ {
+ "id": "4",
+ "title": {
+ "en": "Protect"
+ }
+ }
+ ],
+ "getable": true,
+ "setable": true,
+ "uiComponent": "picker"
}
}
}
\ No newline at end of file
diff --git a/drivers/vimar_thermostat_02952.b/assets/images/large.png b/drivers/vimar_thermostat_02952.b/assets/images/large.png
new file mode 100644
index 0000000..7442800
Binary files /dev/null and b/drivers/vimar_thermostat_02952.b/assets/images/large.png differ
diff --git a/drivers/vimar_thermostat_02952.b/assets/images/small.png b/drivers/vimar_thermostat_02952.b/assets/images/small.png
new file mode 100644
index 0000000..8867fc6
Binary files /dev/null and b/drivers/vimar_thermostat_02952.b/assets/images/small.png differ
diff --git a/drivers/vimar_thermostat_02952.b/device.js b/drivers/vimar_thermostat_02952.b/device.js
new file mode 100644
index 0000000..cb978cc
--- /dev/null
+++ b/drivers/vimar_thermostat_02952.b/device.js
@@ -0,0 +1,226 @@
+'use strict';
+
+const KNXGenericDevice = require('../../lib/GenericKNXDevice');
+const DatapointTypeParser = require('../../lib/DatapointTypeParser');
+
+//
+// I am hating the way to do the shift calculation
+// either we have to get all 8 combinations, and then keep track of summer/winter and mode, or
+// keep track of actual setpoint and shift, and calculate the new shift based on the calculated base setpoint
+//
+class VimarThermostat02952BDevice extends KNXGenericDevice {
+
+ onInit() {
+ super.onInit();
+
+ // Initialize variables
+ this.currentSetpoint = undefined;
+ this.currentSetpointShift = undefined;
+ this.currentSetpointBase = undefined;
+
+ this.registerCapabilityListener('target_temperature', this.onCapabilityTargetTemperature.bind(this));
+ this.registerCapabilityListener('vimar_thermostat_mode', this.onCapabilityMode.bind(this));
+
+ // Maybe this can be placed better during pairing?
+ if (!this.settings.ga_summerwinter_state && this.hasCapability('summer_winter')) {
+ this.removeCapability('summer_winter');
+ this.knxInterface.removeKNXConnectionListener(this.settings.ga_summerwinter_state, this.KNXEventHandler);
+ }
+ if (!this.settings.ga_valve_heating_state && this.hasCapability('valve_heating')) {
+ this.removeCapability('valve_heating');
+ this.knxInterface.removeKNXConnectionListener(this.settings.ga_valve_heating_state, this.KNXEventHandler);
+ }
+ if (!this.settings.ga_valve_cooling_state && this.hasCapability('valve_cooling')) {
+ this.removeCapability('valve_cooling');
+ this.knxInterface.removeKNXConnectionListener(this.settings.ga_valve_cooling_state, this.KNXEventHandler);
+ }
+ }
+
+ async onKNXEvent(groupaddress, data) {
+ super.onKNXEvent(groupaddress, data);
+
+ try {
+ if (groupaddress === this.settings.ga_temperature_target) {
+ this.currentSetpointShift = DatapointTypeParser.dpt9(data);
+ setTimeout(() => {
+ this.currentSetpointShift = undefined;
+ }, 500);
+ }
+ if (groupaddress === this.settings.ga_temperature_target_actual) {
+ this.currentSetpoint = DatapointTypeParser.dpt9(data);
+ await this.setCapabilityValue('target_temperature', this.currentSetpoint);
+ setTimeout(() => {
+ this.currentSetpoint = undefined;
+ }, 500);
+ }
+
+ if (this.currentSetpoint !== undefined && this.currentSetpointShift !== undefined) {
+ this.currentSetpointBase = this.currentSetpoint - this.currentSetpointShift;
+ }
+
+ if (groupaddress === this.settings.ga_temperature_measure) {
+ await this.setCapabilityValue('measure_temperature', DatapointTypeParser.dpt9(data));
+ }
+ if (groupaddress === this.settings.ga_valve_heating_state) {
+ await this.setCapabilityValue('valve_heating', DatapointTypeParser.onoff(data));
+ }
+ if (groupaddress === this.settings.ga_valve_cooling_state) {
+ await this.setCapabilityValue('valve_cooling', DatapointTypeParser.onoff(data));
+ }
+ if (groupaddress === this.settings.ga_summerwinter_state) {
+ await this.setCapabilityValue('summer_winter', DatapointTypeParser.onoff(data) ? 'Winter' : 'Summer');
+ }
+ if (groupaddress === this.settings.ga_thermostat_mode_state) {
+ if (this.settings.ga_temperature_measure) {
+ await this.knxInterface.readKNXGroupAddress(this.settings.ga_temperature_measure);
+ }
+ if (this.settings.ga_temperature_target_actual) {
+ await this.knxInterface.readKNXGroupAddress(this.settings.ga_temperature_target_actual);
+ }
+
+ await this.setCapabilityValue('vimar_thermostat_mode', `${DatapointTypeParser.dpt17(data)}`);
+ }
+ } catch (error) {
+ this.log('Error in onKNXEvent', error);
+ }
+ }
+
+ addKNXEventListeners(settings) {
+ super.addKNXEventListeners(settings);
+
+ // The ga_temperature_target and ga_temperature_measure are added by super
+ this.knxInterface.addKNXEventListener(settings.ga_temperature_target_actual, this.KNXEventHandler);
+ this.knxInterface.addKNXEventListener(settings.ga_thermostat_mode_state, this.KNXEventHandler);
+ this.knxInterface.addKNXEventListener(settings.ga_summerwinter_state, this.KNXEventHandler);
+ this.knxInterface.addKNXEventListener(settings.ga_valve_heating_state, this.KNXEventHandler);
+ this.knxInterface.addKNXEventListener(settings.ga_valve_cooling_state, this.KNXEventHandler);
+ }
+
+ async onKNXConnection(connectionStatus) {
+ super.onKNXConnection(connectionStatus);
+
+ try {
+ if (connectionStatus === 'connected') {
+ // Reading the groupaddress will trigger a event on the bus.
+ // This will be catched by onKNXEvent, hence the return value is not used.
+ if (this.settings.ga_temperature_target) {
+ await this.knxInterface.readKNXGroupAddress(this.settings.ga_temperature_target);
+ }
+ if (this.settings.ga_temperature_measure) {
+ await this.knxInterface.readKNXGroupAddress(this.settings.ga_temperature_measure);
+ }
+ if (this.settings.ga_temperature_target_actual) {
+ await this.knxInterface.readKNXGroupAddress(this.settings.ga_temperature_target_actual);
+ }
+ if (this.settings.ga_thermostat_mode_state) {
+ await this.knxInterface.readKNXGroupAddress(this.settings.ga_thermostat_mode_state);
+ }
+ if (this.settings.ga_summerwinter_state) {
+ await this.knxInterface.readKNXGroupAddress(this.settings.ga_summerwinter_state);
+ }
+ if (this.settings.ga_valve_heating_state) {
+ await this.knxInterface.readKNXGroupAddress(this.settings.ga_valve_heating_state);
+ }
+ if (this.settings.ga_valve_cooling_state) {
+ await this.knxInterface.readKNXGroupAddress(this.settings.ga_valve_cooling_state);
+ }
+ }
+ } catch (knxerror) {
+ this.log('Failed to read', knxerror);
+ }
+ }
+
+ async onCapabilityMode(value, opts) {
+ if (this.knxInterface && this.settings.ga_thermostat_mode) {
+ try {
+ await this.knxInterface.writeKNXGroupAddress(this.settings.ga_thermostat_mode, value, 'DPT17');
+ } catch (knxerror) {
+ this.log(knxerror);
+ throw new Error(this.homey.__('errors.mode_set_failed'));
+ }
+
+ // Wait a bit before reading the temperature,
+ // as the mode change will trigger a new setpoint
+ // the knx lib has an issue when sending read requests too fast after a write,
+ // it will actually send them before
+ await (new Promise((resolve) => setTimeout(resolve, 400)));
+
+ if (this.settings.ga_temperature_measure) {
+ await this.knxInterface.readKNXGroupAddress(this.settings.ga_temperature_measure);
+ }
+ if (this.settings.ga_temperature_target_actual) {
+ await this.knxInterface.readKNXGroupAddress(this.settings.ga_temperature_target_actual);
+ }
+ }
+ }
+
+ onCapabilityTargetTemperature(value, opts) {
+ this.getMeasuredTemperature();
+ if (this.knxInterface && this.settings.ga_temperature_target) {
+ if (this.currentSetpointBase === undefined) {
+ throw new Error('Actual setpoint and shift are unknown');
+ }
+
+ const newShift = value - this.currentSetpointBase;
+ return this.knxInterface.writeKNXGroupAddress(this.settings.ga_temperature_target, newShift, 'DPT9.1')
+ .catch((knxerror) => {
+ this.log(knxerror);
+ throw new Error(this.homey.__('errors.temperature_set_failed'));
+ });
+ }
+ return null;
+ }
+
+ getMeasuredTemperature() {
+ if (this.settings.ga_temperature_measure) {
+ this.knxInterface.readKNXGroupAddress(this.settings.ga_temperature_measure)
+ .catch((knxerror) => {
+ this.log(knxerror);
+ throw new Error(this.homey.__('errors.temperature_get_failed'));
+ });
+ }
+ }
+
+ /**
+ * onSettings is called when the user updates the device's settings.
+ * @param {object} event the onSettings event data
+ * @param {object} event.oldSettings The old settings object
+ * @param {object} event.newSettings The new settings object
+ * @param {string[]} event.changedKeys An array of keys changed since the previous version
+ * @returns {Promise} return a custom message that will be displayed
+ */
+ async onSettings({ oldSettings, newSettings, changedKeys }) {
+ await super.onSettings({ oldSettings, newSettings, changedKeys });
+
+ if (!newSettings.ga_summerwinter_state && this.hasCapability('summer_winter')) {
+ this.removeCapability('summer_winter');
+ if (oldSettings.ga_summerwinter_state) {
+ this.knxInterface.removeKNXConnectionListener(oldSettings.ga_summerwinter_state, this.KNXEventHandler);
+ }
+ } else if (newSettings.ga_summerwinter_state && !this.hasCapability('summer_winter')) {
+ this.addCapability('summer_winter');
+ this.knxInterface.addKNXEventListener(newSettings.ga_summerwinter_state, this.KNXEventHandler);
+ }
+ if (!newSettings.ga_valve_heating_state && this.hasCapability('valve_heating')) {
+ this.removeCapability('valve_heating');
+ if (oldSettings.ga_valve_heating_state) {
+ this.knxInterface.removeKNXConnectionListener(oldSettings.ga_valve_heating_state, this.KNXEventHandler);
+ }
+ } else if (newSettings.ga_valve_heating_state && !this.hasCapability('valve_heating')) {
+ this.addCapability('valve_heating');
+ this.knxInterface.addKNXEventListener(newSettings.ga_valve_heating_state, this.KNXEventHandler);
+ }
+ if (!newSettings.ga_valve_cooling_state && this.hasCapability('valve_cooling')) {
+ this.removeCapability('valve_cooling');
+ if (oldSettings.ga_valve_cooling_state) {
+ this.knxInterface.removeKNXConnectionListener(oldSettings.ga_valve_cooling_state, this.KNXEventHandler);
+ }
+ } else if (newSettings.ga_valve_cooling_state && !this.hasCapability('valve_cooling')) {
+ this.addCapability('valve_cooling');
+ this.knxInterface.addKNXEventListener(newSettings.ga_valve_cooling_state, this.KNXEventHandler);
+ }
+ }
+
+}
+
+module.exports = VimarThermostat02952BDevice;
diff --git a/drivers/vimar_thermostat_02952.b/driver.compose.json b/drivers/vimar_thermostat_02952.b/driver.compose.json
new file mode 100644
index 0000000..517b1e3
--- /dev/null
+++ b/drivers/vimar_thermostat_02952.b/driver.compose.json
@@ -0,0 +1,189 @@
+{
+ "$extends" :["knx_driver"],
+ "id": "vimar_thermostat_02952.b",
+ "name": {
+ "en": "Vimar Thermostat",
+ "nl": "Vimar Thermostaat"
+ },
+ "class": "thermostat",
+ "capabilities": [
+ "target_temperature",
+ "measure_temperature",
+ "vimar_thermostat_mode",
+ "valve_heating",
+ "valve_cooling",
+ "summer_winter"
+ ],
+ "pair" : [
+ {
+ "id": "select_interface",
+ "$template": "select_interface",
+ "navigation": {
+ "next": "select_groupaddresses"
+ }
+ },
+ {
+ "id": "parse_knxproj",
+ "$template": "parse_knxproj",
+ "navigation": {
+ "next": "select_groupaddresses",
+ "prev": "select_groupaddresses"
+ }
+ },
+ {
+ "id": "select_groupaddresses",
+ "$template": "select_groupaddresses",
+ "options": {
+ "devicetype": "vimar_thermostat_02952.b"
+ },
+ "navigation": {
+ "prev": "select_interface"
+ }
+ }
+ ],
+ "settings": [
+ {
+ "type": "group",
+ "label": {
+ "en": "KNX groupaddress",
+ "nl": "KNX groepadressen"
+ },
+ "children": [
+ {
+ "id": "ga_temperature_target",
+ "type": "text",
+ "label": {
+ "en": "Setpoint Shift address"
+ },
+ "value": "",
+ "hint": {
+ "en": "Enter groupaddress"
+ }
+ },
+ {
+ "id": "ga_temperature_measure",
+ "type": "text",
+ "label": {
+ "en": "Actual Temperature address"
+ },
+ "value": "",
+ "hint": {
+ "en": "Enter groupaddress"
+ }
+ },
+ {
+ "id": "ga_temperature_target_actual",
+ "type": "text",
+ "label": {
+ "en": "Actual setpoint address"
+ },
+ "value": "",
+ "hint": {
+ "en": "Enter groupaddress"
+ }
+ },
+ {
+ "id": "ga_thermostat_mode",
+ "type": "text",
+ "label": {
+ "en": "Thermostat mode address"
+ },
+ "value": "",
+ "hint": {
+ "en": "Enter groupaddress"
+ }
+ },
+ {
+ "id": "ga_thermostat_mode_state",
+ "type": "text",
+ "label": {
+ "en": "Thermostat mode state address"
+ },
+ "value": "",
+ "hint": {
+ "en": "Enter groupaddress"
+ }
+ },
+ {
+ "id": "ga_summerwinter_state",
+ "type": "text",
+ "label": {
+ "en": "Summer/Winter state address"
+ },
+ "value": "",
+ "hint": {
+ "en": "Enter groupaddress"
+ }
+ },
+ {
+ "id": "ga_window_switch",
+ "type": "text",
+ "label": {
+ "en": "Window Switch address"
+ },
+ "value": "",
+ "hint": {
+ "en": "Enter groupaddress"
+ }
+ },
+ {
+ "id": "ga_valve_heating_state",
+ "type": "text",
+ "label": {
+ "en": "Heating Valve state address"
+ },
+ "value": "",
+ "hint": {
+ "en": "Enter groupaddress"
+ }
+ },
+ {
+ "id": "ga_valve_cooling_state",
+ "type": "text",
+ "label": {
+ "en": "Cooling Valve state address"
+ },
+ "value": "",
+ "hint": {
+ "en": "Enter groupaddress"
+ }
+ }
+ ]
+ },
+ {
+ "type": "group",
+ "label": {
+ "en": "Network settings",
+ "nl": "Netwerk instellingen"
+ },
+ "children": [
+ {
+ "id": "macAddress",
+ "type": "text",
+ "label": {
+ "en": "Interface MAC address",
+ "nl": "Interface MAC adres"
+ },
+ "value" : "",
+ "hint": {
+ "en": "MAC address of the required KNX IP interface",
+ "nl": "MAC adres van de KNX IP interface"
+ }
+ },
+ {
+ "id": "ipAddress",
+ "type": "text",
+ "label": {
+ "en": "Interface IP address",
+ "nl": "Interface IP adres"
+ },
+ "value" : "",
+ "hint": {
+ "en": "IP address of the required KNX IP interface",
+ "nl": "IP adres van de KNX IP interface"
+ }
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/drivers/vimar_thermostat_02952.b/driver.flow.compose.json b/drivers/vimar_thermostat_02952.b/driver.flow.compose.json
new file mode 100644
index 0000000..3061070
--- /dev/null
+++ b/drivers/vimar_thermostat_02952.b/driver.flow.compose.json
@@ -0,0 +1,25 @@
+{
+ "actions": [
+ {
+ "id": "set-window-switch",
+ "title": {
+ "en": "Set Window Switch"
+ },
+ "args": [
+ {
+ "type": "checkbox",
+ "name": "open",
+ "title": {
+ "en": "Window open"
+ }
+ }
+ ]
+ },
+ {
+ "id": "reset_to_basesetpoint",
+ "title": {
+ "en": "Reset to Base Setpoint"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/drivers/vimar_thermostat_02952.b/driver.js b/drivers/vimar_thermostat_02952.b/driver.js
new file mode 100644
index 0000000..bc8e8ff
--- /dev/null
+++ b/drivers/vimar_thermostat_02952.b/driver.js
@@ -0,0 +1,29 @@
+'use strict';
+
+const KNXGenericDriver = require('../../lib/GenericKNXDriver');
+
+class VimarThermostat02952BDriver extends KNXGenericDriver {
+
+ onInit() {
+ super.onInit();
+
+ this.homey.flow.getActionCard('set-window-switch').registerRunListener(async (args, state) => {
+ return args.device.knxInterface.writeKNXGroupAddress(args.device.settings.ga_window_switch, args.open, 'DPT1')
+ .catch((knxerror) => {
+ this.log(knxerror);
+ throw new Error(this.homey.__('errors.window_switch_failed'));
+ });
+ });
+
+ this.homey.flow.getActionCard('reset_to_basesetpoint').registerRunListener(async (args, state) => {
+ return args.device.knxInterface.writeKNXGroupAddress(args.device.settings.ga_temperature_target, 0, 'DPT9.1')
+ .catch((knxerror) => {
+ this.log(knxerror);
+ throw new Error(this.homey.__('errors.reset_to_basesetpoint_failed'));
+ });
+ });
+ }
+
+}
+
+module.exports = VimarThermostat02952BDriver;
diff --git a/locales/en.json b/locales/en.json
index 7e1a881..d49f5a3 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -45,7 +45,14 @@
},
"thermostat": {
"target": "Target temperature address",
- "measure": "Temperature measurement address"
+ "actualtarget": "Target temperature status address",
+ "measure": "Temperature measurement address",
+ "mode": "Thermostat mode address",
+ "mode_state": "Thermostat mode status address",
+ "summer_winter": "Summer/Winter address",
+ "window_switch": "Window switch address",
+ "valve_heating": "Heating valve status address",
+ "valve_cooling": "Cooling valve status address"
},
"rgb": {
"red_toggle_action": "Toggle address red channel",
diff --git a/locales/nl.json b/locales/nl.json
index 7da72c1..0335671 100644
--- a/locales/nl.json
+++ b/locales/nl.json
@@ -45,7 +45,14 @@
},
"thermostat": {
"target": "Doel temperatuur adres",
- "measure": "Ruimtetemperatuur adres"
+ "actualtarget": "Doel temperatuur status adres",
+ "measure": "Ruimtetemperatuur adres",
+ "mode": "Thermostaat modus adres",
+ "mode_state": "Thermostaat modus status adres",
+ "summer_winter": "Zomer/Winter adres",
+ "window_switch": "Raamschakelaar adres",
+ "valve_heating": "Verwarmingsklep status adres",
+ "valve_cooling": "Koelklep status adres"
},
"rgb": {
"red_toggle_action": "Schakel adres rood kanaal",