From 84c406242d44ca9c82be6c8191498263387c1e4e Mon Sep 17 00:00:00 2001 From: Job Doesburg Date: Thu, 1 Aug 2024 11:20:07 +0200 Subject: [PATCH 1/3] Add support for yyj ExtractionHoodAccessory.ts --- src/accessory/AccessoryFactory.ts | 4 + src/accessory/ExtractionHoodAccessory.ts | 135 +++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 src/accessory/ExtractionHoodAccessory.ts diff --git a/src/accessory/AccessoryFactory.ts b/src/accessory/AccessoryFactory.ts index be4330d..8add6be 100644 --- a/src/accessory/AccessoryFactory.ts +++ b/src/accessory/AccessoryFactory.ts @@ -31,6 +31,7 @@ import HumidifierAccessory from './HumidifierAccessory'; import DehumidifierAccessory from './DehumidifierAccessory'; import DiffuserAccessory from './DiffuserAccessory'; import AirPurifierAccessory from './AirPurifierAccessory'; +import ExtractionHoodAccessory from './ExtractionHoodAccessory'; import CameraAccessory from './CameraAccessory'; import SceneAccessory from './SceneAccessory'; import AirConditionerAccessory from './AirConditionerAccessory'; @@ -138,6 +139,9 @@ export default class AccessoryFactory { case 'fskg': handler = new FanAccessory(platform, accessory); break; + case 'yyj': + handler = new ExtractionHoodAccessory(platform, accessory) + break; // Security & Video Surveillance case 'sp': diff --git a/src/accessory/ExtractionHoodAccessory.ts b/src/accessory/ExtractionHoodAccessory.ts new file mode 100644 index 0000000..d74f84f --- /dev/null +++ b/src/accessory/ExtractionHoodAccessory.ts @@ -0,0 +1,135 @@ +import { TuyaDeviceSchemaType } from '../device/TuyaDevice'; +import BaseAccessory from './BaseAccessory'; +import { configureActive } from './characteristic/Active'; +import { configureAirQuality } from './characteristic/AirQuality'; +import { configureLockPhysicalControls } from './characteristic/LockPhysicalControls'; +import { configureRotationSpeed, configureRotationSpeedLevel } from './characteristic/RotationSpeed'; +import {configureLight} from "./characteristic/Light"; +import {configureOn} from "./characteristic/On"; + +const SCHEMA_CODE = { + ACTIVE: ['switch'], + MODE: ['mode'], + LOCK: ['lock'], + SPEED: ['speed'], + SPEED_LEVEL: ['fan_speed_enum', 'speed'], + AIR_QUALITY: ['air_quality', 'pm25'], + PM2_5: ['pm25'], + VOC: ['tvoc'], + LIGHT_ON: ['light', 'switch_led'], + LIGHT_MODE: ['work_mode'], + LIGHT_BRIGHT: ['bright_value', 'bright_value_v2'], + LIGHT_TEMP: ['temp_value', 'temp_value_v2'], + LIGHT_COLOR: ['colour_data'], +}; + +export default class ExtractionHoodAccessory extends BaseAccessory { + + requiredSchema() { + return [SCHEMA_CODE.ACTIVE]; + } + + configureServices() { + configureActive(this, this.mainService(), this.getSchema(...SCHEMA_CODE.ACTIVE)); + this.configureCurrentState(); + this.configureTargetState(); + configureLockPhysicalControls(this, this.mainService(), this.getSchema(...SCHEMA_CODE.LOCK)); + if (this.getFanSpeedSchema()) { + configureRotationSpeed(this, this.mainService(), this.getFanSpeedSchema()); + } else if (this.getFanSpeedLevelSchema()) { + configureRotationSpeedLevel(this, this.mainService(), this.getFanSpeedLevelSchema()); + } + + // Light + if (this.getSchema(...SCHEMA_CODE.LIGHT_ON)) { + if (this.lightServiceType() === this.Service.Lightbulb) { + configureLight( + this, + this.lightService(), + this.getSchema(...SCHEMA_CODE.LIGHT_ON), + this.getSchema(...SCHEMA_CODE.LIGHT_BRIGHT), + this.getSchema(...SCHEMA_CODE.LIGHT_TEMP), + this.getSchema(...SCHEMA_CODE.LIGHT_COLOR), + this.getSchema(...SCHEMA_CODE.LIGHT_MODE), + ); + } else if (this.lightServiceType() === this.Service.Switch) { + configureOn(this, undefined, this.getSchema(...SCHEMA_CODE.LIGHT_ON)); + const unusedService = this.accessory.getService(this.Service.Lightbulb); + unusedService && this.accessory.removeService(unusedService); + } + } + } + + + mainService() { + return this.accessory.getService(this.Service.AirPurifier) + || this.accessory.addService(this.Service.AirPurifier); + } + + getFanSpeedSchema() { + const schema = this.getSchema(...SCHEMA_CODE.SPEED); + if (schema && schema.type === TuyaDeviceSchemaType.Integer) { + return schema; + } + return undefined; + } + + getFanSpeedLevelSchema() { + const schema = this.getSchema(...SCHEMA_CODE.SPEED_LEVEL); + if (schema && schema.type === TuyaDeviceSchemaType.Enum) { + return schema; + } + return undefined; + } + + + configureCurrentState() { + const schema = this.getSchema(...SCHEMA_CODE.ACTIVE); + if (!schema) { + return; + } + + const { INACTIVE, PURIFYING_AIR } = this.Characteristic.CurrentAirPurifierState; + this.mainService().getCharacteristic(this.Characteristic.CurrentAirPurifierState) + .onGet(() => { + const status = this.getStatus(schema.code)!; + return status.value as boolean ? PURIFYING_AIR : INACTIVE; + }); + } + + configureTargetState() { + const schema = this.getSchema(...SCHEMA_CODE.MODE); + if (!schema) { + return; + } + + const { MANUAL, AUTO } = this.Characteristic.TargetAirPurifierState; + this.mainService().getCharacteristic(this.Characteristic.TargetAirPurifierState) + .onGet(() => { + const status = this.getStatus(schema.code)!; + return (status.value === 'auto') ? AUTO : MANUAL; + }) + .onSet(async value => { + await this.sendCommands([{ + code: schema.code, + value: (value === AUTO) ? 'auto' : 'manual', + }], true); + }); + } + + lightServiceType() { + if (this.getSchema(...SCHEMA_CODE.LIGHT_BRIGHT) + || this.getSchema(...SCHEMA_CODE.LIGHT_TEMP) + || this.getSchema(...SCHEMA_CODE.LIGHT_COLOR) + || this.getSchema(...SCHEMA_CODE.LIGHT_MODE)) { + return this.Service.Lightbulb; + } + return this.Service.Switch; + } + + lightService() { + return this.accessory.getService(this.Service.Lightbulb) + || this.accessory.addService(this.Service.Lightbulb); + } + +} From d98c26cbb81c6f8f8d02b82ef2f2d275861e536e Mon Sep 17 00:00:00 2001 From: Job Doesburg Date: Thu, 1 Aug 2024 11:58:23 +0200 Subject: [PATCH 2/3] Cleanup --- src/accessory/AccessoryFactory.ts | 2 +- src/accessory/ExtractionHoodAccessory.ts | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/accessory/AccessoryFactory.ts b/src/accessory/AccessoryFactory.ts index 8add6be..284a02f 100644 --- a/src/accessory/AccessoryFactory.ts +++ b/src/accessory/AccessoryFactory.ts @@ -140,7 +140,7 @@ export default class AccessoryFactory { handler = new FanAccessory(platform, accessory); break; case 'yyj': - handler = new ExtractionHoodAccessory(platform, accessory) + handler = new ExtractionHoodAccessory(platform, accessory); break; // Security & Video Surveillance diff --git a/src/accessory/ExtractionHoodAccessory.ts b/src/accessory/ExtractionHoodAccessory.ts index d74f84f..1f03450 100644 --- a/src/accessory/ExtractionHoodAccessory.ts +++ b/src/accessory/ExtractionHoodAccessory.ts @@ -1,11 +1,10 @@ import { TuyaDeviceSchemaType } from '../device/TuyaDevice'; import BaseAccessory from './BaseAccessory'; import { configureActive } from './characteristic/Active'; -import { configureAirQuality } from './characteristic/AirQuality'; import { configureLockPhysicalControls } from './characteristic/LockPhysicalControls'; import { configureRotationSpeed, configureRotationSpeedLevel } from './characteristic/RotationSpeed'; -import {configureLight} from "./characteristic/Light"; -import {configureOn} from "./characteristic/On"; +import {configureLight} from './characteristic/Light'; +import {configureOn} from './characteristic/On'; const SCHEMA_CODE = { ACTIVE: ['switch'], @@ -44,13 +43,13 @@ export default class ExtractionHoodAccessory extends BaseAccessory { if (this.getSchema(...SCHEMA_CODE.LIGHT_ON)) { if (this.lightServiceType() === this.Service.Lightbulb) { configureLight( - this, - this.lightService(), - this.getSchema(...SCHEMA_CODE.LIGHT_ON), - this.getSchema(...SCHEMA_CODE.LIGHT_BRIGHT), - this.getSchema(...SCHEMA_CODE.LIGHT_TEMP), - this.getSchema(...SCHEMA_CODE.LIGHT_COLOR), - this.getSchema(...SCHEMA_CODE.LIGHT_MODE), + this, + this.lightService(), + this.getSchema(...SCHEMA_CODE.LIGHT_ON), + this.getSchema(...SCHEMA_CODE.LIGHT_BRIGHT), + this.getSchema(...SCHEMA_CODE.LIGHT_TEMP), + this.getSchema(...SCHEMA_CODE.LIGHT_COLOR), + this.getSchema(...SCHEMA_CODE.LIGHT_MODE), ); } else if (this.lightServiceType() === this.Service.Switch) { configureOn(this, undefined, this.getSchema(...SCHEMA_CODE.LIGHT_ON)); From 0beb65eff217bfa91343722fada33f01817e0a91 Mon Sep 17 00:00:00 2001 From: Job Doesburg Date: Thu, 1 Aug 2024 12:03:47 +0200 Subject: [PATCH 3/3] Update SUPPORTED_DEVICES.md --- SUPPORTED_DEVICES.md | 59 ++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/SUPPORTED_DEVICES.md b/SUPPORTED_DEVICES.md index 0a0fb24..430db98 100644 --- a/SUPPORTED_DEVICES.md +++ b/SUPPORTED_DEVICES.md @@ -56,35 +56,36 @@ Most category code is pinyin abbreviation of Chinese name. ## Small Home Appliances -| Name | Name (zh) | Code | Homebridge Service | Supported | Links | -| ---- | ---- | ---- | ---- | ---- | ---- | -| Robot Vacuum | 扫地机 | sd | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorysd?id=Kaiuz16b2s6yd) | -| Heater | 取暖器 | qn | Heater Cooler | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categoryqn?id=Kaiuz18kih0sm) | -| Air Purifier | 空气净化器 | kj | Air Purifier | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categorykj?id=Kaiuz1atqo5l7) | -| Drying Rack | 晾衣架 | lyj | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorylyj?id=Kaiuz1cy926vh) | -| Diffuser | 香薰机 | xxj | Air Purifier
Lightbulb | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categoryxxj?id=Kaiuz1f9mo6bl) | -| Curtain | 窗帘 | cl | Window Covering | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categorycl?id=Kaiuz1hnpo7df) | -| Door and Window Controller | 门窗控制器 | mc | Window | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categorymc?id=Kaiuz1jyoassg) | -| Thermostat | 温控器 | wk | Thermostat | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categorywk?id=Kaiuz1m1xqnt6) | -| Thermostat Valve | 温控阀 | wkf | Thermostat | ✅ | Documentation | -| Bathroom Heater | 浴霸 | yb | | | [Documentation](https://developer.tuya.com/en/docs/iot/categoryyb?id=Kaiuz1oajgpib) | -| Irrigator | 灌溉器 | ggq
sfkzq | Valve | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categoryggq?id=Kaiuz1qib7z0k) | -| Humidifier | 加湿器 | jsq | Humidifier Dehumidifier | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categoryjsq?id=Kaiuz1smr440b) | -| Dehumidifier | 除湿机 | cs | Humidifier Dehumidifier | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categorycs?id=Kaiuz1vcz4dha) | -| Fan | 风扇 | fs | Fanv2 | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categoryfs?id=Kaiuz1xweel1c) | -| Water Purifier | 净水器 | js | | | [Documentation](https://developer.tuya.com/en/docs/iot/categoryjs?id=Kaiuz204l58n9) | -| Electric Blanket | 电热毯 | dr | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorydr?id=Kaiuz22dyc66p) | -| Pet Treat Feeder | 宠物弹射喂食器 | cwtswsq | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorycwtswsq?id=Kaiuz24lq3fq5) | -| Pet Ball Thrower | 宠物网球发射器 | cwwqfsq | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorycwwqfsq?id=Kaiuz26r7g1up) | -| HVAC | 暖通器 | ntq | | | [Documentation](https://developer.tuya.com/en/docs/iot/categoryntq?id=Kaiuz292sjqcz) | -| Pet Feeder | 宠物喂食器 | cwwsq | Switch | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categorycwwsq?id=Kaiuz2b6vydld) | -| Pet Fountain | 宠物饮水机 | cwysj | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorycwysj?id=Kaiuz2dfro0nd) | -| Sofa | 沙发 | sf | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorysf?id=Kaiuz2fp9uqtt) | -| Electric Fireplace | 电壁炉 | dbl | | | [Documentation](https://developer.tuya.com/en/docs/iot/electric-fireplace?id=Kaiuz2hz4iyp6) | -| Smart Milk Kettle | 智能调奶器 | tnq | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorytnq?id=Kakf01agbfkfa) | -| Cat Toilet | 猫砂盆 | msp | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorymsp?id=Kakg2t7714ky7) | -| Towel Rack | 毛巾架 | mjj | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorymjj?id=Kakkmlm9k4cir) | -| Smart Indoor Garden | 植物生长机 | sz | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorysz?id=Kaiuz4e6h7up0) | +| Name | Name (zh) | Code | Homebridge Service | Supported | Links | +|----------------------------| ---- |---------------| ---- | ---- |------------------------------------------------------------------------------------------| +| Robot Vacuum | 扫地机 | sd | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorysd?id=Kaiuz16b2s6yd) | +| Heater | 取暖器 | qn | Heater Cooler | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categoryqn?id=Kaiuz18kih0sm) | +| Air Purifier | 空气净化器 | kj | Air Purifier | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categorykj?id=Kaiuz1atqo5l7) | +| Drying Rack | 晾衣架 | lyj | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorylyj?id=Kaiuz1cy926vh) | +| Diffuser | 香薰机 | xxj | Air Purifier
Lightbulb | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categoryxxj?id=Kaiuz1f9mo6bl) | +| Extraction hood | 香薰机 | yyj | Air Purifier
Lightbulb | ✅ | Documentation | +| Curtain | 窗帘 | cl | Window Covering | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categorycl?id=Kaiuz1hnpo7df) | +| Door and Window Controller | 门窗控制器 | mc | Window | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categorymc?id=Kaiuz1jyoassg) | +| Thermostat | 温控器 | wk | Thermostat | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categorywk?id=Kaiuz1m1xqnt6) | +| Thermostat Valve | 温控阀 | wkf | Thermostat | ✅ | Documentation | +| Bathroom Heater | 浴霸 | yb | | | [Documentation](https://developer.tuya.com/en/docs/iot/categoryyb?id=Kaiuz1oajgpib) | +| Irrigator | 灌溉器 | ggq
sfkzq | Valve | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categoryggq?id=Kaiuz1qib7z0k) | +| Humidifier | 加湿器 | jsq | Humidifier Dehumidifier | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categoryjsq?id=Kaiuz1smr440b) | +| Dehumidifier | 除湿机 | cs | Humidifier Dehumidifier | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categorycs?id=Kaiuz1vcz4dha) | +| Fan | 风扇 | fs | Fanv2 | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categoryfs?id=Kaiuz1xweel1c) | +| Water Purifier | 净水器 | js | | | [Documentation](https://developer.tuya.com/en/docs/iot/categoryjs?id=Kaiuz204l58n9) | +| Electric Blanket | 电热毯 | dr | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorydr?id=Kaiuz22dyc66p) | +| Pet Treat Feeder | 宠物弹射喂食器 | cwtswsq | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorycwtswsq?id=Kaiuz24lq3fq5) | +| Pet Ball Thrower | 宠物网球发射器 | cwwqfsq | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorycwwqfsq?id=Kaiuz26r7g1up) | +| HVAC | 暖通器 | ntq | | | [Documentation](https://developer.tuya.com/en/docs/iot/categoryntq?id=Kaiuz292sjqcz) | +| Pet Feeder | 宠物喂食器 | cwwsq | Switch | ✅ | [Documentation](https://developer.tuya.com/en/docs/iot/categorycwwsq?id=Kaiuz2b6vydld) | +| Pet Fountain | 宠物饮水机 | cwysj | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorycwysj?id=Kaiuz2dfro0nd) | +| Sofa | 沙发 | sf | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorysf?id=Kaiuz2fp9uqtt) | +| Electric Fireplace | 电壁炉 | dbl | | | [Documentation](https://developer.tuya.com/en/docs/iot/electric-fireplace?id=Kaiuz2hz4iyp6) | +| Smart Milk Kettle | 智能调奶器 | tnq | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorytnq?id=Kakf01agbfkfa) | +| Cat Toilet | 猫砂盆 | msp | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorymsp?id=Kakg2t7714ky7) | +| Towel Rack | 毛巾架 | mjj | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorymjj?id=Kakkmlm9k4cir) | +| Smart Indoor Garden | 植物生长机 | sz | | | [Documentation](https://developer.tuya.com/en/docs/iot/categorysz?id=Kaiuz4e6h7up0) | ## Kitchen Appliances