From ea2e302d2613e4ec2384f30c5a8e9aa429d38cb1 Mon Sep 17 00:00:00 2001 From: sieren Date: Tue, 31 Aug 2021 16:23:32 +0200 Subject: [PATCH] Add initial Aqara TVOC Sensor Support Add initial Aqara TVOC Sensor support. This PR does not include Eve History support for PPM values. --- lib/HueSensor.js | 93 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 89 insertions(+), 4 deletions(-) diff --git a/lib/HueSensor.js b/lib/HueSensor.js index ab203ba..8164d62 100644 --- a/lib/HueSensor.js +++ b/lib/HueSensor.js @@ -919,11 +919,13 @@ function HueSensor (accessory, id, obj) { } else if ( this.obj.manufacturername === 'LUMI' && ( this.obj.modelid === 'lumi.weather' || - this.obj.modelid === 'lumi.sensor_ht' + this.obj.modelid === 'lumi.sensor_ht' || + this.obj.modelid === 'lumi.airmonitor.acn01' ) ) { // Xiaomi temperature/humidity sensor // Xiaomi Aqara weather sensor + // Xiaomi Aqara airquality sensor } else if ( this.obj.manufacturername === 'Heiman' && (this.obj.modelid === 'TH-H_V15' || this.obj.modelid === 'TH-T_V15') @@ -962,10 +964,41 @@ function HueSensor (accessory, id, obj) { key: 'temperature', name: 'temperature', unit: '°C', - history: 'weather', + history: this.obj.modelid === 'lumi.airmonitor.acn01' ? 'room' : 'weather', homekitValue: function (v) { return v ? Math.round(v / 10) / 10 : 0 } } break + case 'ZHAAirQuality': + if ( + this.obj.manufacturername === 'LUMI' && + this.obj.modelid === 'lumi.airmonitor.acn01' + ) { + // Xiaomi Aqara airquality sensor + } else { + this.log.warn( + '%s: %s: warning: unknown %s sensor %j', + this.bridge.name, this.resource, this.obj.type, this.obj + ) + } + // falls through + case 'CLIPAirQuality': + this.service = new Service.AirQualitySensor(this.name, this.subtype) + this.serviceList.push(this.service) + this.service + .addOptionalCharacteristic(Characteristic.AirQuality) + this.service + .addOptionalCharacteristic(eve.Characteristics.AirParticulateDensity) + this.type = { + Characteristic: Characteristic.VOCDensity, + key: 'airqualityppb', + name: 'Air Quality', + unit: 'ppb', + history: 'room', + homekitValue: function (v) { + return v ? Math.round(v) : 0 + } + } + break case 'ZLLLightLevel': // 2.7 - Hue Motion Sensor case 'ZHALightLevel': if ( @@ -1043,7 +1076,8 @@ function HueSensor (accessory, id, obj) { if ( this.obj.manufacturername === 'LUMI' && ( this.obj.modelid === 'lumi.weather' || - this.obj.modelid === 'lumi.sensor_ht' + this.obj.modelid === 'lumi.sensor_ht' || + this.obj.modelid === 'lumi.airmonitor.acn01' ) ) { // Xiaomi Aqara weather sensor @@ -1068,7 +1102,7 @@ function HueSensor (accessory, id, obj) { key: 'humidity', name: 'humidity', unit: '%', - history: 'weather', + history: this.obj.modelid === 'lumi.airmonitor.acn01' ? 'room' : 'weather', homekitValue: function (v) { return v ? Math.round(v / 100) : 0 } } break @@ -1520,6 +1554,10 @@ function HueSensor (accessory, id, obj) { this.history.entry.humidity = 0 this.history.entry.pressure = 0 break + case 'room': + this.history.entry.temp = 0 + this.history.entry.humidity = 0 + this.history.entry.ppm = 0 default: break } @@ -1752,6 +1790,8 @@ HueSensor.prototype.checkAttr = function (attr, event) { HueSensor.prototype.checkState = function (state, event) { for (const key in state) { switch (key) { + case 'airquality': + this.checkAirQuality(state.airquality) case 'angle': break case 'battery': @@ -1996,6 +2036,16 @@ HueSensor.prototype.addEntry = function (changed) { } } break + case 'room': + { + var key = this.type.key === 'airqualityppb' ? 'ppm' : this.type.key + key = this.type.key === 'temperature' ? 'temp' : key + this.history.entry[key] = this.hk[this.type.key] + if (changed || this.type.key !== this.history.resource.type.key) { + return + } + } + break default: return } @@ -2340,6 +2390,41 @@ HueSensor.prototype.checkVoltage = function (voltage) { } } +HueSensor.prototype.checkAirQuality = function (airquality) { + if (this.obj.state.airquality !== airquality) { + this.log.debug( + '%s: airquality changed from %j to %j', this.name, + this.obj.state.airquality, airquality + ) + this.obj.state.airquality = airquality + } + var hkAirQuality; + if (airquality == 'excellent') { + hkAirQuality = Characteristic.AirQuality.EXCELLENT + } else if (airquality == 'good') { + hkAirQuality = Characteristic.AirQuality.GOOD + } else if (airquality == 'moderate') { + hkAirQuality = Characteristic.AirQuality.FAIR + } else if (airquality == 'poor') { + hkAirQuality = Characteristic.AirQuality.INFERIOR + } else if (airquality == 'unhealthy') { + hkAirQuality = Characteristic.AirQuality.POOR + } else { + hkAirQuality = Characteristic.AirQuality.UNKNOWN + } + if (this.hk.airquality !== hkAirQuality) { + if (this.hk.airquality !== undefined) { + this.log.info( + '%s: set homekit airquality from %s V to %s V', this.name, + this.hk.airquality, hkAirQuality + ) + } + this.hk.airquality = hkAirQuality + this.service.getCharacteristic(Characteristic.AirQuality) + .updateValue(this.hk.airquality) + } +} + HueSensor.prototype.checkConfig = function (config) { for (const key in config) { switch (key) {