diff --git a/lib/HueSensor.js b/lib/HueSensor.js index 37f9535..6f1f458 100644 --- a/lib/HueSensor.js +++ b/lib/HueSensor.js @@ -235,6 +235,7 @@ function HueSensor (accessory, id, obj) { this.infoService = this.accessory.getInfoService(this) let durationKey = 'duration' + let temperatureHistory = 'weather' switch (this.obj.type) { case 'ZGPSwitch': case 'ZLLSwitch': @@ -956,6 +957,9 @@ function HueSensor (accessory, id, obj) { ) { // Develco smoke sensor // Develco heat sensor + } else if (this.obj.modelid === 'lumi.airmonitor.acn01') { + // Xiaomi Aquara TVOC Sensor + temperatureHistory = 'room2' } else { this.log.warn( '%s: %s: warning: unknown %s sensor %j', @@ -971,10 +975,39 @@ function HueSensor (accessory, id, obj) { key: 'temperature', name: 'temperature', unit: '°C', - history: 'weather', + history: temperatureHistory, 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.type = { + Characteristic: Characteristic.VOCDensity, + key: 'airqualityppb', + name: 'Air Quality', + unit: 'voc', + history: 'room2', + homekitValue: function (v) { + return v ? Math.round(v * 4.56) : 0 + } + } + break case 'ZLLLightLevel': // 2.7 - Hue Motion Sensor case 'ZHALightLevel': if ( @@ -1057,6 +1090,9 @@ function HueSensor (accessory, id, obj) { ) { // Xiaomi Aqara weather sensor // Xiaomi Mi temperature/humidity sensor + } else if (this.obj.modelid === 'lumi.airmonitor.acn01') { + // Xiaomi Aquara TVOC Sensor + temperatureHistory = 'room2' } else if ( this.obj.manufacturername === 'Heiman' && (this.obj.modelid === 'TH-H_V15' || this.obj.modelid === 'TH-T_V15') @@ -1077,7 +1113,7 @@ function HueSensor (accessory, id, obj) { key: 'humidity', name: 'humidity', unit: '%', - history: 'weather', + history: temperatureHistory, homekitValue: function (v) { return v ? Math.round(v / 100) : 0 } } break @@ -1529,6 +1565,11 @@ function HueSensor (accessory, id, obj) { this.history.entry.humidity = 0 this.history.entry.pressure = 0 break + case 'room2': + this.history.entry.temp = 0 + this.history.entry.humidity = 0 + this.history.entry.voc = 0 + break default: break } @@ -1761,6 +1802,9 @@ 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) + break case 'angle': break case 'battery': @@ -2005,6 +2049,17 @@ HueSensor.prototype.addEntry = function (changed) { } } break + case 'room2': + { + const key = this.type.key === 'airqualityppb' + ? 'voc' + : (this.type.key === 'temperature' ? 'temp' : this.type.key) + this.history.entry[key] = this.hk[this.type.key] + if (changed || this.type.key !== this.history.resource.type.key) { + return + } + } + break default: return } @@ -2349,6 +2404,40 @@ 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 + } + const qualities = { + excellent: Characteristic.AirQuality.EXCELLENT, + good: Characteristic.AirQuality.GOOD, + moderate: Characteristic.AirQuality.FAIR, + poor: Characteristic.AirQuality.INFERIOR, + unhealthy: Characteristic.AirQuality.POOR + } + + let hkAirQuality = qualities[airquality] + if (!hkAirQuality) { + 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) { diff --git a/package.json b/package.json index 2137754..2469da3 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "node": "^14.17.6" }, "dependencies": { - "fakegato-history": "~0.6.1", + "fakegato-history": "~0.6.2", "homebridge-lib": "~5.1.13", "semver": "^7.3.5", "ws": "^8.2.1",