Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reuse light characteristics. #184

Merged
merged 6 commits into from
Dec 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@
- Update support for RGB Power Switch (`dj`).
- Support showing device online status via `StatusActive`. (#172)
- Update unit and range of `RotationSpeed` with level, need clean accessory cache to take effect. (#174)
- Support Door and Window Controller motor reverse mode.
- Support Door and Window Controller motor reverse mode. (#180)
- Support Diffuser RGB light. (#184)
- Support Fan light temperature and color. (#184)
- Support Humidifier light. (#184)


## [1.6.0] - (2022.12.3)
Expand Down
49 changes: 13 additions & 36 deletions src/accessory/CameraAccessory.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { TuyaDeviceSchemaIntegerProperty, TuyaDeviceStatus } from '../device/TuyaDevice';
import { TuyaDeviceStatus } from '../device/TuyaDevice';
import { TuyaStreamingDelegate } from '../util/TuyaStreamDelegate';
import { limit, remap } from '../util/util';
import BaseAccessory from './BaseAccessory';
import { configureLight } from './characteristic/Light';
import { configureOn } from './characteristic/On';
import { configureProgrammableSwitchEvent, onProgrammableSwitchEvent } from './characteristic/ProgrammableSwitchEvent';

Expand All @@ -15,7 +15,7 @@ const SCHEMA_CODE = {
// Notifies when a doorbell ring occurs.
ALARM_MESSAGE: ['alarm_message'],
LIGHT_ON: ['floodlight_switch'],
LIGHT_BRIGHTNESS: ['floodlight_lightness'],
LIGHT_BRIGHT: ['floodlight_lightness'],
};

export default class CameraAccessory extends BaseAccessory {
Expand All @@ -29,41 +29,18 @@ export default class CameraAccessory extends BaseAccessory {
configureServices() {
this.configureDoorbell();
this.configureCamera();
this.configureFloodLight();
this.configureMotion();
}

configureFloodLight() {
const onSchema = this.getSchema(...SCHEMA_CODE.LIGHT_ON);
if (!onSchema) {
return;
}

const service = this.getLightService();

configureOn(this, service, onSchema);

const brightnessSchema = this.getSchema(...SCHEMA_CODE.LIGHT_BRIGHTNESS);
if (brightnessSchema) {
const { min, max } = brightnessSchema.property as TuyaDeviceSchemaIntegerProperty;
service.getCharacteristic(this.Characteristic.Brightness)
.onGet(() => {
const status = this.getStatus(brightnessSchema.code)!;
let value = status.value as number;
value = remap(value, 0, max, 0, 100);
value = Math.round(value);
value = limit(value, min, max);
return value;
})
.onSet(value => {
this.log.debug(`Characteristic.Brightness set to: ${value}`);
let brightValue = value as number;
brightValue = remap(brightValue, 0, 100, 0, max);
brightValue = Math.round(brightValue);
brightValue = limit(brightValue, min, max);
this.sendCommands([{ code: brightnessSchema.code, value: brightValue }], true);
});
}
// FloodLight
configureLight(
this,
this.getLightService(),
this.getSchema(...SCHEMA_CODE.LIGHT_ON),
this.getSchema(...SCHEMA_CODE.LIGHT_BRIGHT),
undefined,
undefined,
undefined,
);
}

configureMotion() {
Expand Down
112 changes: 21 additions & 91 deletions src/accessory/DiffuserAccessory.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { TuyaDeviceSchemaIntegerProperty, TuyaDeviceStatus } from '../device/TuyaDevice';
import { limit, remap } from '../util/util';
import BaseAccessory from './BaseAccessory';
import { configureActive } from './characteristic/Active';
import { configureLight } from './characteristic/Light';
import { configureOn } from './characteristic/On';
import { configureRotationSpeedLevel } from './characteristic/RotationSpeed';

Expand All @@ -11,7 +11,7 @@ const SCHEMA_CODE = {
SPRAY_LEVEL: ['level'],
LIGHT_ON: ['switch_led'],
LIGHT_MODE: ['work_mode'],
LIGHT_BRIGHTNESS: ['bright_value', 'bright_value_v2'],
LIGHT_BRIGHT: ['bright_value', 'bright_value_v2'],
LIGHT_COLOR: ['colour_data_hsv'],
SOUND_ON: ['switch_sound'],
};
Expand All @@ -23,9 +23,21 @@ export default class DiffuserAccessory extends BaseAccessory {
}

configureServices() {
configureOn(this, undefined, this.getSchema(...SCHEMA_CODE.ON)); // Main Switch
this.configureAirPurifier();
this.configureLight();
// Main Switch
configureOn(this, undefined, this.getSchema(...SCHEMA_CODE.ON));

this.configureDiffuser();

configureLight(
this,
undefined,
this.getSchema(...SCHEMA_CODE.LIGHT_ON),
this.getSchema(...SCHEMA_CODE.LIGHT_BRIGHT),
undefined,
this.getSchema(...SCHEMA_CODE.LIGHT_COLOR),
this.getSchema(...SCHEMA_CODE.LIGHT_MODE),
);

configureOn(this, undefined, this.getSchema(...SCHEMA_CODE.SOUND_ON)); // Sound Switch
}

Expand All @@ -34,41 +46,15 @@ export default class DiffuserAccessory extends BaseAccessory {
|| this.accessory.addService(this.Service.AirPurifier);
}

lightService() {
return this.accessory.getService(this.Service.Lightbulb)
|| this.accessory.addService(this.Service.Lightbulb, this.device.name + ' Light');
}

configureAirPurifier() {
const onSchema = this.getSchema(...SCHEMA_CODE.ON);
configureDiffuser() {
const sprayOnSchema = this.getSchema(...SCHEMA_CODE.SPRAY_ON)!;

// Required Characteristics
const { INACTIVE, ACTIVE } = this.Characteristic.Active;
this.mainService().getCharacteristic(this.Characteristic.Active)
.onGet(() => {
if (onSchema && !this.getStatus(onSchema.code)!.value) {
return INACTIVE;
}
configureActive(this, this.mainService(), sprayOnSchema);

const status = this.getStatus(sprayOnSchema.code)!;
return (status.value as boolean) ? ACTIVE : INACTIVE;
})
.onSet(value => {
const commands = [{ code: sprayOnSchema.code, value: (value === ACTIVE) }];
if (onSchema && value === ACTIVE) {
commands.push({ code: onSchema.code, value: true });
}
this.sendCommands(commands, true);
});

const { PURIFYING_AIR } = this.Characteristic.CurrentAirPurifierState;
const { INACTIVE, PURIFYING_AIR } = this.Characteristic.CurrentAirPurifierState;
this.mainService().getCharacteristic(this.Characteristic.CurrentAirPurifierState)
.onGet(() => {
if (onSchema && this.getStatus(onSchema.code)!.value !== true) {
return INACTIVE;
}

const status = this.getStatus(sprayOnSchema.code)!;
return (status.value as boolean) ? PURIFYING_AIR : INACTIVE;
});
Expand All @@ -82,60 +68,4 @@ export default class DiffuserAccessory extends BaseAccessory {
configureRotationSpeedLevel(this, this.mainService(), this.getSchema(...SCHEMA_CODE.SPRAY_LEVEL));
}

configureLight() {
const onSchema = this.getSchema(...SCHEMA_CODE.ON);
const lightOnSchema = this.getSchema(...SCHEMA_CODE.LIGHT_ON);
if (!lightOnSchema) {
return;
}

this.lightService().getCharacteristic(this.Characteristic.On)
.onGet(() => {
if (onSchema && this.getStatus(onSchema.code)!.value !== true) {
return false;
}

const status = this.getStatus(lightOnSchema.code)!;
return (status.value as boolean);
})
.onSet(value => {
const commands = [{ code: lightOnSchema.code, value: value as boolean }];
if (onSchema && value) {
commands.push({ code: onSchema.code, value: true });
}
this.sendCommands(commands, true);
});
this.configureLightBrightness();
}

configureLightBrightness() {
const schema = this.getSchema(...SCHEMA_CODE.LIGHT_BRIGHTNESS);
if (!schema) {
return;
}

const lightModeSchema = this.getSchema(...SCHEMA_CODE.LIGHT_MODE);

const { min, max } = schema.property as TuyaDeviceSchemaIntegerProperty;
this.lightService().getCharacteristic(this.Characteristic.Brightness)
.onGet(() => {
const status = this.getStatus(schema.code)!;
const value = Math.round(remap(status.value as number, 0, max, 0, 100));
return limit(value, 0, 100);
})
.onSet(value => {
let brightness = Math.round(remap(value as number, 0, 100, 0, max));
brightness = limit(brightness, min, max);

const commands: TuyaDeviceStatus[] = [{
code: schema.code,
value: brightness,
}];

if (lightModeSchema) {
commands.push({ code: lightModeSchema.code, value: 'white' });
}
this.sendCommands(commands, true);
});
}
}
3 changes: 2 additions & 1 deletion src/accessory/DimmerAccessory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ export default class DimmerAccessory extends BaseAccessory {
brightValue = Math.round(brightValue);
brightValue = limit(brightValue, min, max);
this.sendCommands([{ code: schema.code, value: brightValue }], true);
}).setProps(props);
})
.setProps(props);

}

Expand Down
42 changes: 15 additions & 27 deletions src/accessory/FanAccessory.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { TuyaDeviceSchemaIntegerProperty, TuyaDeviceSchemaType } from '../device/TuyaDevice';
import { limit, remap } from '../util/util';
import { TuyaDeviceSchemaType } from '../device/TuyaDevice';
import BaseAccessory from './BaseAccessory';
import { configureActive } from './characteristic/Active';
import { configureLight } from './characteristic/Light';
import { configureLockPhysicalControls } from './characteristic/LockPhysicalControls';
import { configureOn } from './characteristic/On';
import { configureRotationSpeed, configureRotationSpeedLevel, configureRotationSpeedOn } from './characteristic/RotationSpeed';
Expand All @@ -15,7 +15,10 @@ const SCHEMA_CODE = {
FAN_LOCK: ['child_lock'],
FAN_SWING: ['switch_horizontal', 'switch_vertical'],
LIGHT_ON: ['light', 'switch_led'],
LIGHT_BRIGHTNESS: ['bright_value'],
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 FanAccessory extends BaseAccessory {
Expand Down Expand Up @@ -54,8 +57,15 @@ export default class FanAccessory extends BaseAccessory {

// Light
if (this.getSchema(...SCHEMA_CODE.LIGHT_ON)) {
configureOn(this, this.lightService(), this.getSchema(...SCHEMA_CODE.LIGHT_ON));
this.configureLightBrightness();
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 {
this.log.warn('Remove Lightbulb Service...');
const unusedService = this.accessory.getService(this.Service.Lightbulb);
Expand Down Expand Up @@ -116,26 +126,4 @@ export default class FanAccessory extends BaseAccessory {
});
}

configureLightBrightness() {
const schema = this.getSchema(...SCHEMA_CODE.LIGHT_BRIGHTNESS);
if (!schema) {
return;
}

const { min, max } = schema.property as TuyaDeviceSchemaIntegerProperty;
this.lightService().getCharacteristic(this.Characteristic.Brightness)
.onGet(() => {
const status = this.getStatus(schema.code)!;
const value = Math.round(remap(status.value as number, 0, max, 0, 100));
return limit(value, 0, 100);
})
.onSet(value => {
let brightness = Math.round(remap(value as number, 0, 100, 0, max));
brightness = limit(brightness, min, max);
this.sendCommands([{
code: schema.code,
value: brightness,
}], true);
});
}
}
23 changes: 21 additions & 2 deletions src/accessory/HumidifierAccessory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@ import BaseAccessory from './BaseAccessory';
import { configureActive } from './characteristic/Active';
import { configureCurrentTemperature } from './characteristic/CurrentTemperature';
import { configureCurrentRelativeHumidity } from './characteristic/CurrentRelativeHumidity';
import { configureLight } from './characteristic/Light';

const SCHEMA_CODE = {
ACTIVE: ['switch'],
CURRENT_HUMIDITY: ['humidity_current'],
TARGET_HUMIDITY: ['humidity_set'],
CURRENT_TEMP: ['temp_current'],
LIGHT_ON: ['switch_led'],
LIGHT_MODE: ['work_mode'],
LIGHT_BRIGHT: ['bright_value', 'bright_value_v2'],
LIGHT_COLOR: ['colour_data', 'colour_data_hsv'],
};

export default class HumidifierAccessory extends BaseAccessory {
Expand All @@ -19,13 +24,27 @@ export default class HumidifierAccessory extends BaseAccessory {
}

configureServices() {
// Required Characteristics
configureActive(this, this.mainService(), this.getSchema(...SCHEMA_CODE.ACTIVE));
this.configureTargetState();
this.configureCurrentState();
this.configureTargetState();
configureCurrentRelativeHumidity(this, this.mainService(), this.getSchema(...SCHEMA_CODE.CURRENT_HUMIDITY));

// Optional Characteristics
this.configureRelativeHumidityHumidifierThreshold();
configureCurrentTemperature(this, undefined, this.getSchema(...SCHEMA_CODE.CURRENT_TEMP));
this.configureRotationSpeed();

// Other
configureCurrentTemperature(this, undefined, this.getSchema(...SCHEMA_CODE.CURRENT_TEMP));
configureLight(
this,
undefined,
this.getSchema(...SCHEMA_CODE.LIGHT_ON),
this.getSchema(...SCHEMA_CODE.LIGHT_BRIGHT),
undefined,
this.getSchema(...SCHEMA_CODE.LIGHT_COLOR),
this.getSchema(...SCHEMA_CODE.LIGHT_MODE),
);
}


Expand Down
Loading