From 6ce5cab558222e110567325f66678aea21ecbc4c Mon Sep 17 00:00:00 2001 From: Valentin Dusollier Date: Wed, 21 Jun 2023 14:04:02 +0200 Subject: [PATCH] Add heating capacity support for SimpleHeaterAccessory --- config.schema.json | 16 ++++++++++++++++ lib/SimpleHeaterAccessory.js | 27 +++++++++++++++++++++++---- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/config.schema.json b/config.schema.json index ee892f6..84db351 100644 --- a/config.schema.json +++ b/config.schema.json @@ -366,6 +366,22 @@ "functionBody": "return model.devices && model.devices[arrayIndices] && ['Convector'].includes(model.devices[arrayIndices].type);" } }, + "dpHeatingCapacity": { + "type": "integer", + "placeholder": "", + "description": "If your heater doesn't have a heating capacity, leave this empty.", + "condition": { + "functionBody": "return model.devices && model.devices[arrayIndices] && ['SimpleHeater'].includes(model.devices[arrayIndices].type);" + } + }, + "dpHeatingCapacityIdleValue": { + "type": "integer", + "placeholder": "0", + "description": "Value of heating capacity when the heater is idle.", + "condition": { + "functionBody": "return model.devices && model.devices[arrayIndices] && ['SimpleHeater'].includes(model.devices[arrayIndices].type);" + } + }, "dpChildLock": { "type": "integer", "placeholder": "6", diff --git a/lib/SimpleHeaterAccessory.js b/lib/SimpleHeaterAccessory.js index 4308273..c5184fb 100644 --- a/lib/SimpleHeaterAccessory.js +++ b/lib/SimpleHeaterAccessory.js @@ -25,6 +25,8 @@ class SimpleHeaterAccessory extends BaseAccessory { this.dpActive = this._getCustomDP(this.device.context.dpActive) || '1'; this.dpDesiredTemperature = this._getCustomDP(this.device.context.dpDesiredTemperature) || '2'; this.dpCurrentTemperature = this._getCustomDP(this.device.context.dpCurrentTemperature) || '3'; + this.dpHeatingCapacity = this._getCustomDP(this.device.context.dpHeatingCapacity) || null; + this.dpHeatingCapacityIdleValue = this._getCustomDP(this.device.context.dpHeatingCapacityIdleValue) || 0; this.temperatureDivisor = parseInt(this.device.context.temperatureDivisor) || 1; this.thresholdTemperatureDivisor = parseInt(this.device.context.thresholdTemperatureDivisor) || 1; this.targetTemperatureDivisor = parseInt(this.device.context.targetTemperatureDivisor) || 1; @@ -34,9 +36,10 @@ class SimpleHeaterAccessory extends BaseAccessory { .on('get', this.getActive.bind(this)) .on('set', this.setActive.bind(this)); - service.getCharacteristic(Characteristic.CurrentHeaterCoolerState) + const characteristicCurrentHeaterCoolerState = service.getCharacteristic(Characteristic.CurrentHeaterCoolerState) .updateValue(this._getCurrentHeaterCoolerState(dps)) .on('get', this.getCurrentHeaterCoolerState.bind(this)); + this.characteristicCurrentHeaterCoolerState = characteristicCurrentHeaterCoolerState; service.getCharacteristic(Characteristic.TargetHeaterCoolerState) .setProps({ @@ -80,6 +83,13 @@ class SimpleHeaterAccessory extends BaseAccessory { if (changes.hasOwnProperty(this.dpCurrentTemperature) && characteristicCurrentTemperature.value !== changes[this.dpCurrentTemperature]) characteristicCurrentTemperature.updateValue(this._getDividedState(changes[this.dpCurrentTemperature], this.temperatureDivisor)); + if (changes.hasOwnProperty(this.dpActive) || + changes.hasOwnProperty(this.dpDesiredTemperature) || + changes.hasOwnProperty(this.dpCurrentTemperature) || + (this.dpHeatingCapacity != null && changes.hasOwnProperty(this.dpHeatingCapacity))) { + this.characteristicCurrentHeaterCoolerState.updateValue(this._getCurrentHeaterCoolerState(state)); + } + console.log('[Tuya] SimpleHeater changed: ' + JSON.stringify(state)); }); } @@ -113,16 +123,25 @@ class SimpleHeaterAccessory extends BaseAccessory { } getCurrentHeaterCoolerState(callback) { - this.getState([this.dpActive], (err, dps) => { + let dps = [this.dpActive, this.dpCurrentTemperature, this.dpDesiredTemperature] + if (this.dpHeatingCapacity != null) dps.push(this.dpHeatingCapacity) + this.getState(dps, (err, dps_values) => { if (err) return callback(err); - callback(null, this._getCurrentHeaterCoolerState(dps)); + callback(null, this._getCurrentHeaterCoolerState(dps_values)); }); } _getCurrentHeaterCoolerState(dps) { const {Characteristic} = this.hap; - return dps[this.dpActive] ? Characteristic.CurrentHeaterCoolerState.HEATING : Characteristic.CurrentHeaterCoolerState.INACTIVE; + + if (!dps[this.dpActive]) return Characteristic.CurrentHeaterCoolerState.INACTIVE; + + if (this.dpHeatingCapacity == null) { // If dpHeatingCapacity isn't provided, we assume that the heater is heating when currentTemp <= desiredTemp and idle otherwise + return dps[this.dpCurrentTemperature] <= dps[this.dpDesiredTemperature] ? Characteristic.CurrentHeaterCoolerState.HEATING : Characteristic.CurrentHeaterCoolerState.IDLE; + } else { // If dpHeatingCapacity is provided, we assume that the heater is heating when heatingCapacity != idleValue and idle otherwise + return dps[this.dpHeatingCapacity] != this.dpHeatingCapacityIdleValue ? Characteristic.CurrentHeaterCoolerState.HEATING : Characteristic.CurrentHeaterCoolerState.IDLE; + } } getTargetHeaterCoolerState(callback) {