diff --git a/config.schema.json b/config.schema.json index 2a6764c6..6f90808e 100644 --- a/config.schema.json +++ b/config.schema.json @@ -996,6 +996,52 @@ "condition": { "functionBody": "return (model.options && model.options.irdevices && !model.options.irdevices[arrayIndices].hide_device && (model.options.irdevices[arrayIndices].configRemoteType === 'Air Conditioner' || model.options.irdevices[arrayIndices].configRemoteType === 'DIY Air Conditioner') && model.options.irdevices[arrayIndices].deviceId);" } + }, + "meterType": { + "title": "Use an existing Switchbot device for temperature/humidity", + "type": "string", + "oneOf": [ + { + "title": "Meter", + "enum": [ + "Meter" + ] + }, + { + "title": "MeterPlus", + "enum": [ + "MeterPlus" + ] + }, + { + "title": "Meter Plus (JP)", + "enum": [ + "Meter Plus (JP)" + ] + }, + { + "title": "Hub 2", + "enum": [ + "Hub 2" + ] + }, + { + "title": "WoIOSensor", + "enum": [ + "WoIOSensor" + ] + } + ], + "condition": { + "functionBody": "return (model.options && model.options.irdevices && !model.options.irdevices[arrayIndices].hide_device && (model.options.irdevices[arrayIndices].configRemoteType === 'Air Conditioner' || model.options.irdevices[arrayIndices].configRemoteType === 'DIY Air Conditioner') && model.options.irdevices[arrayIndices].deviceId);" + } + }, + "meterId": { + "title": "Device ID of the device to use for temperature/humidity", + "type": "string", + "condition": { + "functionBody": "return (model.options && model.options.irdevices && !model.options.irdevices[arrayIndices].hide_device && (model.options.irdevices[arrayIndices].configRemoteType === 'Air Conditioner' || model.options.irdevices[arrayIndices].configRemoteType === 'DIY Air Conditioner') && model.options.irdevices[arrayIndices].deviceId && model.options.irdevices[arrayIndices].irair?.meterType);" + } } } }, @@ -1259,6 +1305,8 @@ "options.irdevices[].disablePushOff", "options.irdevices[].disablePushDetail", "options.irdevices[].irair.hide_automode", + "options.irdevices[].irair.meterType", + "options.irdevices[].irair.meterId", "options.irdevices[].irfan.rotation_speed", "options.irdevices[].irfan.swing_mode", "options.irdevices[].irfan.set_minStep", diff --git a/src/irdevice/airconditioner.ts b/src/irdevice/airconditioner.ts index 0f3ebd26..f5224e9e 100644 --- a/src/irdevice/airconditioner.ts +++ b/src/irdevice/airconditioner.ts @@ -16,6 +16,7 @@ export class AirConditioner { Active!: CharacteristicValue; RotationSpeed!: CharacteristicValue; CurrentTemperature!: CharacteristicValue; + CurrentRelativeHumidity?: CharacteristicValue; TargetHeaterCoolerState!: CharacteristicValue; CurrentHeaterCoolerState!: CharacteristicValue; HeatingThresholdTemperature!: CharacteristicValue; @@ -38,6 +39,7 @@ export class AirConditioner { disablePushDetail?: boolean; deviceLogging!: string; hide_automode?: boolean; + meter?: PlatformAccessory; private readonly valid12 = [1, 2]; private readonly valid012 = [0, 1, 2]; @@ -106,6 +108,16 @@ export class AirConditioner { ` hide_automode: ${this.hide_automode}, TargetHeaterCoolerState: ${this.TargetHeaterCoolerState}`, ); } + if (this.meter) { + this.coolerService + .getCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity) + .setProps({ + minStep: 0.1, + }) + .onGet(() => { + return this.CurrentRelativeHumidityGet(); + }); + } this.coolerService .getCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState) .setProps({ @@ -283,7 +295,10 @@ export class AirConditioner { } async CurrentTemperatureGet(): Promise { - if (this.CurrentTemperature === undefined) { + if (this.meter?.context) { + this.CurrentTemperature = this.meter.context.CurrentTemperature; + this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using CurrentTemperature from ${this.meter.context?.deviceType} (${this.meter.context?.deviceID})`) + } else if (this.CurrentTemperature === undefined) { this.CurrentTemperature = 24; } else { this.CurrentTemperature = this.accessory.context.CurrentTemperature; @@ -292,6 +307,21 @@ export class AirConditioner { return this.CurrentTemperature; } + async CurrentRelativeHumidityGet(): Promise { + if (this.meter?.context) { + this.CurrentRelativeHumidity = this.meter.context.CurrentRelativeHumidity; + this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using CurrentRelativeHumidity from ${this.meter.context?.deviceType} (${this.meter.context?.deviceID})`) + } + else if (this.CurrentRelativeHumidity === undefined) { + this.CurrentRelativeHumidity = 0; + } + else { + this.CurrentRelativeHumidity = this.accessory.context.CurrentRelativeHumidity; + } + this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Get CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`); + return this.CurrentRelativeHumidity as CharacteristicValue; +} + async RotationSpeedGet(): Promise { if (!this.CurrentFanSpeed) { this.RotationSpeed = 4; @@ -471,6 +501,16 @@ export class AirConditioner { this.coolerService?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.CurrentTemperature); this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} updateCharacteristic CurrentTemperature: ${this.CurrentTemperature}`); } + if (this.meter) { + if (this.CurrentRelativeHumidity === undefined) { + this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`); + } + else { + this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidity; + this.coolerService?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, this.CurrentRelativeHumidity); + this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} updateCharacteristic CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`); + } + } if (this.TargetHeaterCoolerState === undefined) { this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} TargetHeaterCoolerState: ${this.TargetHeaterCoolerState}`); } else { @@ -661,6 +701,17 @@ export class AirConditioner { this.hide_automode = this.device.irair?.hide_automode; this.accessory.context.hide_automode = this.hide_automode; } + + if (this.device.irair?.meterUuid) { + this.meter = this.platform.accessories.find((accessory) => accessory.UUID === this.device.irair?.meterUuid) + } + if (this.meter) { + if (this.CurrentRelativeHumidity === undefined) { + this.CurrentRelativeHumidity = 0; + } else { + this.CurrentRelativeHumidity = this.accessory.context.CurrentRelativeHumidity; + } + } } async config({ device }: { device: irdevice & irDevicesConfig; }): Promise { diff --git a/src/platform.ts b/src/platform.ts index e86d0484..3ef4fbd2 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -1639,13 +1639,16 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin { } } - private async createAirConditioner(device: irdevice & devicesConfig) { + private async createAirConditioner(device: irdevice & devicesConfig & irDevicesConfig) { const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`); // see if an accessory with the same uuid has already been registered and restored from // the cached devices we stored in the `configureAccessory` method above const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid); + if (device.irair?.meterType && device.irair?.meterId) { + device.irair.meterUuid = this.api.hap.uuid.generate(`${device.irair.meterId}-${device.irair.meterType}`); + } if (existingAccessory) { // the accessory already exists if (!device.hide_device && device.hubDeviceId) { diff --git a/src/settings.ts b/src/settings.ts index e44db748..468ad93e 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -188,6 +188,9 @@ export type irfan = { export type irair = { hide_automode?: boolean; + meterType?: string; + meterId?: string; + meterUuid?: string; }; export type other = {