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

Add a max brightness field for each dimmer in config file #149 #200

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ The `defaults` has these properties:

- `id` The name or id for the device that is registered in the Android/iOS App. When matching on ID please provide the `Tuya ID` as shown during Homebridge boot.
- `device_type` The `device_type` to be overruled. This can be useful for dimmers that are reported as `light` by the Tuya API and don't support hue and saturation or for outlets that are reported as `switch`.
- `max_brightness` The maximum value of your dimmer light brightness. To get this, turn your dimmer/light to 100% brightness via the Tuya App. Next open your HomeKit app. Lastly view your HomeBridge logs, once the accessories load you can view the output and see the current value of each light. Something along the lines of `Characteristic.Brightness - [GET] 255` should be shown - in which case you want to set the numerical value of that log entry to the `max_brightness` value.

> Note: After overriding the device type, it might appear duplicated in both HomeBridge (Accessories Tab) and the Home App. To solve this issue, go to the Homebridge settings (top right corner) and remove the device using the `Remove Single Cached Accessory` option.

Expand Down
24 changes: 24 additions & 0 deletions config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,18 @@
],
"required": true
},
"max_brightness": {
"title": "Device max brightness",
"type": "number",
"default": 255,
"description": "Dimmer lights might have different maximum value, find it and set it here"
},
"min_brightness": {
"title": "Device min brightness",
"type": "number",
"default": 1,
"description": "Dimmer lights might have different minimum value, find it and set it here"
},
"min_temper": {
"title": "Minimal Temperature",
"type": "string",
Expand Down Expand Up @@ -260,6 +272,18 @@
{
"key": "defaults[].id"
},
{
"key": "defaults[].max_brightness",
"condition": {
"functionBody": "return (model.defaults[arrayIndices].device_type == 'dimmer')"
}
},
{
"key": "defaults[].min_brightness",
"condition": {
"functionBody": "return (model.defaults[arrayIndices].device_type == 'dimmer')"
}
},
{
"key": "defaults[].device_type"
},
Expand Down
43 changes: 43 additions & 0 deletions src/accessories/DimmerAccessory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
OnCharacteristic,
} from "./characteristics";
import { TuyaDevice } from "../api/response";
import { TuyaDeviceDefaults } from "../config";

export class DimmerAccessory extends BaseAccessory {
constructor(
Expand Down Expand Up @@ -42,4 +43,46 @@ export class DimmerAccessory extends BaseAccessory {

return super.deviceSupportedCharacteristics;
}

public get maxBrightness(): number {
if (this.deviceConfig.config?.max_brightness) {
return this.deviceConfig.config.max_brightness;
}

return 255;
}

public get minBrightness(): number {
if (this.deviceConfig.config?.min_brightness) {
return this.deviceConfig.config.min_brightness;
}

return 1;
}

validateConfigOverwrites(config: TuyaDeviceDefaults): string[] {
const errors = super.validateConfigOverwrites(config);
if (config?.max_brightness) {
const maxBrightness = Number(config.max_brightness);
if (!maxBrightness) {
errors.push(
"Wrong value configured for `max_brightness`, should be a number"
);
} else {
config.max_brightness = maxBrightness;
}
}

if (config?.min_brightness) {
const minBrightness = Number(config.min_brightness);
if (!minBrightness) {
errors.push(
"Wrong value configured for `min_brightness`, should be a number"
);
} else {
config.min_brightness = minBrightness;
}
}
return errors;
}
}
15 changes: 13 additions & 2 deletions src/accessories/characteristics/brightness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { inspect } from "util";
import { TuyaWebCharacteristic } from "./base";
import { BaseAccessory } from "../BaseAccessory";
import { DeviceState } from "../../api/response";
import { DimmerAccessory } from "../DimmerAccessory";

export class BrightnessCharacteristic extends TuyaWebCharacteristic {
public static Title = "Characteristic.Brightness";
Expand Down Expand Up @@ -41,7 +42,13 @@ export class BrightnessCharacteristic extends TuyaWebCharacteristic {
callback: CharacteristicSetCallback
): void {
// Set device state in Tuya Web API
const value = ((homekitValue as number) / 10) * 9 + 10;
const dimmerPercentage = (homekitValue as number) / 100;
const correctionFactor = 10;
const value = Math.round(
(100 - correctionFactor) * dimmerPercentage +
correctionFactor +
Number.EPSILON
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you opt to add the Number.EPSILON here (and a few lines later)?

Copy link
Author

@AlexPinhasov AlexPinhasov Mar 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The decimal number is very large, I wanted to be sure as much as possible the round will be correct

);

this.accessory
.setDeviceState("brightnessSet", { value }, { brightness: homekitValue })
Expand All @@ -63,7 +70,11 @@ export class BrightnessCharacteristic extends TuyaWebCharacteristic {
) {
stateValue = Number(data.color.brightness);
} else if (data?.brightness) {
stateValue = Math.round((Number(data.brightness) / 255) * 100);
const maxBrightness = (this.accessory as DimmerAccessory).maxBrightness;
const brightness = Number(data.brightness);
stateValue = Math.round(
(brightness / maxBrightness) * 100 + Number.EPSILON
);
}

if (stateValue) {
Expand Down
2 changes: 2 additions & 0 deletions src/api/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ type TuyaProperties = Partial<{

type CustomProperties = Partial<{
target_cover_state: CoverState;
max_brightness: number;
min_brightness: number;
}>;
export type DeviceState = TuyaProperties & CustomProperties;

Expand Down
2 changes: 2 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { TuyaDeviceType } from "./api/response";
export type TuyaDeviceDefaults = {
id: string;
device_type: TuyaDeviceType;
max_brightness: number;
min_brightness: number;
min_temper: string | number;
max_temper: string | number;
current_temperature_factor: string | number;
Expand Down