From d4f2b7462c2ec37eb666723892739e6e5d77ba00 Mon Sep 17 00:00:00 2001 From: Illia Antypenko Date: Sun, 12 Jun 2022 23:27:38 +0200 Subject: [PATCH 1/7] Reset current temperature to "-" in case AC returns 0 --- drivers/gree_cooper_hunter_hvac/device.js | 24 +++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/gree_cooper_hunter_hvac/device.js b/drivers/gree_cooper_hunter_hvac/device.js index 1851ee6..4bd68e1 100644 --- a/drivers/gree_cooper_hunter_hvac/device.js +++ b/drivers/gree_cooper_hunter_hvac/device.js @@ -8,10 +8,10 @@ const finder = require('./network/finder'); const RECONNECT_TIME_INTERVAL = 10000; // Interval between polling status from HVAC (ms) -const POLLING_INTERVAL = 3000; +const POLLING_INTERVAL = 3500; // Timeout for response from the HVAC during polling process (ms) -const POLLING_TIMEOUT = 2000; +const POLLING_TIMEOUT = 3000; class GreeHVACDevice extends Homey.Device { @@ -27,6 +27,7 @@ class GreeHVACDevice extends Homey.Device { this._markOffline(); this._findDevices(); + this._scheduleReconnection(); } /** @@ -225,9 +226,11 @@ class GreeHVACDevice extends Homey.Device { }).catch(this.error); } - const currentTempChanged = this._checkPropertyChanged(updatedProperties, HVAC.PROPERTY.currentTemperature, 'measure_temperature'); - if (currentTempChanged && updatedProperties[HVAC.PROPERTY.currentTemperature] !== 0) { - const value = updatedProperties[HVAC.PROPERTY.currentTemperature]; + if (this._checkPropertyChanged(updatedProperties, HVAC.PROPERTY.currentTemperature, 'measure_temperature')) { + let value = updatedProperties[HVAC.PROPERTY.currentTemperature]; + if (value === 0) { + value = null; + } this.setCapabilityValue('measure_temperature', value).then(() => { this.log('[update properties]', '[measure_temperature]', value); return Promise.resolve(); @@ -286,11 +289,13 @@ class GreeHVACDevice extends Homey.Device { _onError(message, error) { this.log('[ERROR]', 'Message:', message, 'Error', error); this._markOffline(); + this._scheduleReconnection(); } _onDisconnect() { this.log('[disconnect]', 'Disconnecting from device'); this._markOffline(); + this._scheduleReconnection(); } /** @@ -301,8 +306,9 @@ class GreeHVACDevice extends Homey.Device { * @private */ _onNoResponse(client) { - this._markOffline(); this.log('[no response]', 'Don\'t get response during polling updates'); + this._markOffline(); + this._scheduleReconnection(); } /** @@ -313,7 +319,13 @@ class GreeHVACDevice extends Homey.Device { _markOffline() { this.log('[offline] mark device offline'); this.setUnavailable(this.homey.__('error.offline')); + } + /** + * + * @private + */ + _scheduleReconnection() { if (!this._reconnectInterval) { this._reconnectInterval = this.homey.setInterval(() => { this._findDevices(); From 2368f56f746391c25e5ef086fd09cf203d946d91 Mon Sep 17 00:00:00 2001 From: Illia Antypenko Date: Sun, 12 Jun 2022 23:33:28 +0200 Subject: [PATCH 2/7] Add separate check to track changes in current temperature --- drivers/gree_cooper_hunter_hvac/device.js | 30 ++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/gree_cooper_hunter_hvac/device.js b/drivers/gree_cooper_hunter_hvac/device.js index 4bd68e1..2410ce9 100644 --- a/drivers/gree_cooper_hunter_hvac/device.js +++ b/drivers/gree_cooper_hunter_hvac/device.js @@ -226,7 +226,7 @@ class GreeHVACDevice extends Homey.Device { }).catch(this.error); } - if (this._checkPropertyChanged(updatedProperties, HVAC.PROPERTY.currentTemperature, 'measure_temperature')) { + if (this._checkCurrentTemperaturePropertyChanged(updatedProperties, HVAC.PROPERTY.currentTemperature, 'measure_temperature')) { let value = updatedProperties[HVAC.PROPERTY.currentTemperature]; if (value === 0) { value = null; @@ -354,6 +354,34 @@ class GreeHVACDevice extends Homey.Device { return hvacValue !== capabilityValue; } + + /** + * Same as _checkPropertyChanged plus check if capability value is null and from HVAC is "0" + * means no data available and should be considered as "no change" + * + * @param {Array} updatedProperties + * @param {string} propertyName + * @param {string} capabilityName + * @returns {boolean} + * @private + */ + _checkCurrentTemperaturePropertyChanged(updatedProperties, propertyName, capabilityName) { + if (!Object.prototype.hasOwnProperty.call(updatedProperties, propertyName)) { + return false; + } + + const hvacValue = updatedProperties[propertyName]; + const capabilityValue = this.getCapabilityValue(capabilityName); + + // Additional check for current temperature + if (capabilityValue === null && hvacValue === 0) { + return false; + } + + // If HVAC and Homey have different values then it was changed + return hvacValue !== capabilityValue; + } + /** * Special checks for boolean logic * From 81f1e7d11b529bf8b23c1c17b93427c6fb31f6a3 Mon Sep 17 00:00:00 2001 From: Illia Antypenko Date: Sun, 12 Jun 2022 23:39:42 +0200 Subject: [PATCH 3/7] Change logic of reconnecting --- drivers/gree_cooper_hunter_hvac/device.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gree_cooper_hunter_hvac/device.js b/drivers/gree_cooper_hunter_hvac/device.js index 2410ce9..fc238b1 100644 --- a/drivers/gree_cooper_hunter_hvac/device.js +++ b/drivers/gree_cooper_hunter_hvac/device.js @@ -26,7 +26,6 @@ class GreeHVACDevice extends Homey.Device { this._flowTriggerVerticalSwingChanged = this.homey.flow.getDeviceTriggerCard('vertical_swing_changed'); this._markOffline(); - this._findDevices(); this._scheduleReconnection(); } @@ -322,6 +321,7 @@ class GreeHVACDevice extends Homey.Device { } /** + * Start trying to find the device in and reconnect to it * * @private */ @@ -331,6 +331,7 @@ class GreeHVACDevice extends Homey.Device { this._findDevices(); }, RECONNECT_TIME_INTERVAL); } + this._findDevices(); } /** From 7cf55ce94ca0a4870cc24cb0da07ad338eb4ad9a Mon Sep 17 00:00:00 2001 From: Illia Antypenko Date: Sun, 12 Jun 2022 23:42:02 +0200 Subject: [PATCH 4/7] Fix eslint checks --- drivers/gree_cooper_hunter_hvac/device.js | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gree_cooper_hunter_hvac/device.js b/drivers/gree_cooper_hunter_hvac/device.js index fc238b1..1501114 100644 --- a/drivers/gree_cooper_hunter_hvac/device.js +++ b/drivers/gree_cooper_hunter_hvac/device.js @@ -355,7 +355,6 @@ class GreeHVACDevice extends Homey.Device { return hvacValue !== capabilityValue; } - /** * Same as _checkPropertyChanged plus check if capability value is null and from HVAC is "0" * means no data available and should be considered as "no change" From 6df0d5a79330187f521e5aee40f363f05f6a062f Mon Sep 17 00:00:00 2001 From: Illia Antypenko Date: Mon, 13 Jun 2022 00:28:51 +0200 Subject: [PATCH 5/7] Get rid of warning for duplicated registration of capabilities like "Warning: Capability "target_temperature" listener was already registered." --- drivers/gree_cooper_hunter_hvac/device.js | 51 +++++++++++++++++++---- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/drivers/gree_cooper_hunter_hvac/device.js b/drivers/gree_cooper_hunter_hvac/device.js index 1501114..7ed0737 100644 --- a/drivers/gree_cooper_hunter_hvac/device.js +++ b/drivers/gree_cooper_hunter_hvac/device.js @@ -15,6 +15,14 @@ const POLLING_TIMEOUT = 3000; class GreeHVACDevice extends Homey.Device { + /** + * Flag which indicates that capabilities are already registered + * + * @type {boolean} + * @private + */ + _capabilitiesRegistered = false; + async onInit() { this.log('Gree device has been inited'); @@ -103,17 +111,24 @@ class GreeHVACDevice extends Homey.Device { * @private */ _registerCapabilities() { + if (this._capabilitiesRegistered) { + return; + } + + // Mark capabilities as registered + this._capabilitiesRegistered = true; + this.registerCapabilityListener('onoff', value => { const rawValue = value ? HVAC.VALUE.power.on : HVAC.VALUE.power.off; this.log('[power mode change]', `Value: ${value}`, `Raw value: ${rawValue}`); - this.client.setProperty(HVAC.PROPERTY.power, rawValue); + this._setClientProperty(HVAC.PROPERTY.power, rawValue); return Promise.resolve(); }); this.registerCapabilityListener('target_temperature', value => { this.log('[temperature change]', `Value: ${value}`); - this.client.setProperty(HVAC.PROPERTY.temperature, value); + this._setClientProperty(HVAC.PROPERTY.temperature, value); return Promise.resolve(); }); @@ -122,44 +137,50 @@ class GreeHVACDevice extends Homey.Device { const rawValue = HVAC.VALUE.mode[value]; this.log('[mode change]', `Value: ${value}`, `Raw value: ${rawValue}`); this._flowTriggerHvacModeChanged.trigger(this, { hvac_mode: value }); - this.client.setProperty(HVAC.PROPERTY.mode, rawValue); + this._setClientProperty(HVAC.PROPERTY.mode, rawValue); + return Promise.resolve(); }); this.registerCapabilityListener('fan_speed', value => { const rawValue = HVAC.VALUE.fanSpeed[value]; this.log('[fan speed change]', `Value: ${value}`, `Raw value: ${rawValue}`); - this.client.setProperty(HVAC.PROPERTY.fanSpeed, rawValue); + this._setClientProperty(HVAC.PROPERTY.fanSpeed, rawValue); + return Promise.resolve(); }); this.registerCapabilityListener('turbo_mode', value => { const rawValue = value ? HVAC.VALUE.turbo.on : HVAC.VALUE.turbo.off; this.log('[turbo mode change]', `Value: ${value}`, `Raw value: ${rawValue}`); - this.client.setProperty(HVAC.PROPERTY.turbo, rawValue); + this._setClientProperty(HVAC.PROPERTY.turbo, rawValue); + return Promise.resolve(); }); this.registerCapabilityListener('lights', value => { const rawValue = value ? HVAC.VALUE.lights.on : HVAC.VALUE.lights.off; this.log('[lights change]', `Value: ${value}`, `Raw value: ${rawValue}`); - this.client.setProperty(HVAC.PROPERTY.lights, rawValue); + this._setClientProperty(HVAC.PROPERTY.lights, rawValue); this._flowTriggerHvacLightsChanged.trigger(this, { lights: value }); + return Promise.resolve(); }); this.registerCapabilityListener('xfan_mode', value => { const rawValue = value ? HVAC.VALUE.blow.on : HVAC.VALUE.blow.off; this.log('[xfan mode change]', `Value: ${value}`, `Raw value: ${rawValue}`); - this.client.setProperty(HVAC.PROPERTY.blow, rawValue); + this._setClientProperty(HVAC.PROPERTY.blow, rawValue); this._flowTriggerXFanModeChanged.trigger(this, { xfan_mode: value }); + return Promise.resolve(); }); this.registerCapabilityListener('vertical_swing', value => { const rawValue = HVAC.VALUE.swingVert[value]; this.log('[vertical swing change]', `Value: ${value}`, `Raw value: ${rawValue}`); - this.client.setProperty(HVAC.PROPERTY.swingVert, rawValue); + this._setClientProperty(HVAC.PROPERTY.swingVert, rawValue); + return Promise.resolve(); }); } @@ -461,13 +482,25 @@ class GreeHVACDevice extends Homey.Device { } } + /** + * Set value for the specific property of the HVAC client + * + * @param property + * @param value + * @private + */ + _setClientProperty(property, value) { + if (this.client) { + this.client.setProperty(property, value); + } + } + async onSettings({ oldSettings, newSettings, changedKeys }) { if (changedKeys.indexOf('enable_debug') > -1) { console.log('Changing the debug settings from', oldSettings.enable_debug, 'to', newSettings.enable_debug); this.client.setDebug(newSettings.enable_debug); } } - } /** From 891ea08e9f641b7209488be64bd5cbf72f18ac82 Mon Sep 17 00:00:00 2001 From: Illia Antypenko Date: Mon, 13 Jun 2022 00:35:34 +0200 Subject: [PATCH 6/7] Log and do clearInverval only when it's needed --- drivers/gree_cooper_hunter_hvac/device.js | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/gree_cooper_hunter_hvac/device.js b/drivers/gree_cooper_hunter_hvac/device.js index 7ed0737..a110a8c 100644 --- a/drivers/gree_cooper_hunter_hvac/device.js +++ b/drivers/gree_cooper_hunter_hvac/device.js @@ -194,8 +194,12 @@ class GreeHVACDevice extends Homey.Device { */ _onConnect(client) { this.log('[connect]', 'connected to', client.getDeviceId()); - this.homey.clearInterval(this._reconnectInterval); - delete this._reconnectInterval; + + if (this._reconnectInterval) { + this.homey.clearInterval(this._reconnectInterval); + delete this._reconnectInterval; + } + this.log('[connect]', 'mark device available'); this.setAvailable(); } @@ -224,11 +228,15 @@ class GreeHVACDevice extends Homey.Device { // turbo: 'off', // powerSave: 'off' } - this.homey.clearInterval(this._reconnectInterval); - delete this._reconnectInterval; + if (this._reconnectInterval) { + this.homey.clearInterval(this._reconnectInterval); + delete this._reconnectInterval; + } - this.log('[update]', 'mark device available'); - this.setAvailable(); + if (!this.getAvailable()) { + this.log('[update]', 'mark device available'); + this.setAvailable(); + } if (this._checkBoolPropertyChanged(updatedProperties, HVAC.PROPERTY.power, 'onoff')) { const value = updatedProperties[HVAC.PROPERTY.power] === HVAC.VALUE.power.on; @@ -501,6 +509,7 @@ class GreeHVACDevice extends Homey.Device { this.client.setDebug(newSettings.enable_debug); } } + } /** From 75fb9ab7c2a133f3222cf4e4ad2e93f96ddf0d18 Mon Sep 17 00:00:00 2001 From: Illia Antypenko Date: Mon, 13 Jun 2022 01:08:23 +0200 Subject: [PATCH 7/7] Switch gree-hvac-client to com.gree/master branch --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 75a41b0..6e09a86 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1927,8 +1927,8 @@ "dev": true }, "gree-hvac-client": { - "version": "git+https://github.com/aivus/gree-hvac-client.git#0399eb1f0bf1a89f0b979c63b346c76cfa810880", - "from": "git+https://github.com/aivus/gree-hvac-client.git#com.gree/adjustCurrentTemp", + "version": "git+https://github.com/aivus/gree-hvac-client.git#0a83781903fad1fc54f1f2fa87d4c6af21e75641", + "from": "git+https://github.com/aivus/gree-hvac-client.git#com.gree/master", "requires": { "clone": "^2.1.2", "object-diff": "^0.0.4" diff --git a/package.json b/package.json index 781bc97..1a2a58e 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ }, "homepage": "https://github.com/aivus/com.gree#readme", "dependencies": { - "gree-hvac-client": "git+https://github.com/aivus/gree-hvac-client.git#com.gree/adjustCurrentTemp", + "gree-hvac-client": "git+https://github.com/aivus/gree-hvac-client.git#com.gree/master", "homey-log": "^2.1.0" }, "devDependencies": {