Skip to content

Commit 6177954

Browse files
committed
feat: Improves handling of color temperature.
This features allows more granular control over how this plugin perceives the color temperature that it gets reported from Tuya.
1 parent 2abebd3 commit 6177954

File tree

5 files changed

+91
-7
lines changed

5 files changed

+91
-7
lines changed

config.schema.json

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,20 @@
161161
"description": "The brightness value that Tuya returns when your light is at its brightest.",
162162
"required": false
163163
},
164+
"min_kelvin": {
165+
"title": "Minimal Kelvin",
166+
"type": "string",
167+
"pattern": "^-?\\d+$",
168+
"description": "The kelvin value that Tuya returns when your light is at its warmest (most red).",
169+
"required": false
170+
},
171+
"max_kelvin": {
172+
"title": "Maximal Brightness",
173+
"type": "string",
174+
"pattern": "^-?\\d+$",
175+
"description": "The kelvin value that Tuya returns when your light is at its coolest (most blue).",
176+
"required": false
177+
},
164178
"current_temperature_factor": {
165179
"title": "Temperature Factor",
166180
"type": "string",
@@ -316,13 +330,25 @@
316330
{
317331
"key": "defaults[].min_brightness",
318332
"condition": {
319-
"functionBody": "return (model.defaults[arrayIndices].device_type == 'light')"
333+
"functionBody": "return (model.defaults[arrayIndices].light_characteristics?.includes('Brightness'))"
320334
}
321335
},
322336
{
323337
"key": "defaults[].max_brightness",
324338
"condition": {
325-
"functionBody": "return (model.defaults[arrayIndices].device_type == 'light')"
339+
"functionBody": "return (model.defaults[arrayIndices].light_characteristics?.includes('Brightness'))"
340+
}
341+
},
342+
{
343+
"key": "defaults[].min_kelvin",
344+
"condition": {
345+
"functionBody": "return (model.defaults[arrayIndices].light_characteristics?.includes('Color Temperature'))"
346+
}
347+
},
348+
{
349+
"key": "defaults[].max_kelvin",
350+
"condition": {
351+
"functionBody": "return (model.defaults[arrayIndices].light_characteristics?.includes('Color Temperature'))"
326352
}
327353
},
328354
{

src/accessories/characteristics/active.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ export class ActiveCharacteristic extends TuyaWebCharacteristic {
5555
);
5656
callback && callback(null, stateValue);
5757
} else {
58-
callback && callback(new Error("Could not get state from data"));
58+
callback &&
59+
callback(new Error("Could not find required property 'state'"));
5960
}
6061
}
6162
}

src/accessories/characteristics/colorTemperature.ts

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import {
2+
Characteristic,
23
CharacteristicGetCallback,
34
CharacteristicSetCallback,
45
CharacteristicValue,
6+
Formats,
57
} from "homebridge";
68
import { TuyaWebCharacteristic } from "./base";
79
import { MapRange } from "../../helpers/MapRange";
@@ -22,7 +24,36 @@ export class ColorTemperatureCharacteristic extends TuyaWebCharacteristic {
2224
return accessory.deviceConfig.data.color_temp !== undefined;
2325
}
2426

25-
private rangeMapper = MapRange.tuya(140, 500).homeKit(10000, 1000);
27+
public setProps(char?: Characteristic): Characteristic | undefined {
28+
return char?.setProps({
29+
format: Formats.INT,
30+
minValue: this.minHomekit,
31+
maxValue: this.maxHomekit,
32+
});
33+
}
34+
35+
public get minKelvin(): number {
36+
const data = this.accessory.deviceConfig.config;
37+
return Number(data?.min_kelvin) || 1000000 / 500;
38+
}
39+
40+
public get maxKelvin(): number {
41+
const data = this.accessory.deviceConfig.config;
42+
return Number(data?.max_kelvin) || 1000000 / 140;
43+
}
44+
45+
public get minHomekit(): number {
46+
return 1000000 / this.maxKelvin;
47+
}
48+
49+
public get maxHomekit(): number {
50+
return 1000000 / this.minKelvin;
51+
}
52+
53+
public rangeMapper = MapRange.tuya(this.maxKelvin, this.minKelvin).homeKit(
54+
this.minHomekit,
55+
this.maxHomekit
56+
);
2657

2758
public getRemoteValue(callback: CharacteristicGetCallback): void {
2859
this.accessory
@@ -46,7 +77,7 @@ export class ColorTemperatureCharacteristic extends TuyaWebCharacteristic {
4677
}
4778

4879
// Set device state in Tuya Web API
49-
const value = Math.round(this.rangeMapper.tuyaToHomekit(homekitValue));
80+
const value = Math.round(this.rangeMapper.homekitToTuya(homekitValue));
5081

5182
this.accessory
5283
.setDeviceState("colorTemperatureSet", { value }, { color_temp: value })
@@ -59,15 +90,38 @@ export class ColorTemperatureCharacteristic extends TuyaWebCharacteristic {
5990

6091
updateValue(data: DeviceState, callback?: CharacteristicGetCallback): void {
6192
if (data?.color_temp !== undefined) {
93+
const tuyaValue = data.color_temp;
6294
const homekitColorTemp = Math.round(
63-
this.rangeMapper.homekitToTuya(Number(data.color_temp))
95+
this.rangeMapper.tuyaToHomekit(Number(data.color_temp))
6496
);
97+
98+
if (homekitColorTemp > this.maxHomekit) {
99+
this.warn(
100+
"Characteristic 'ColorTemperature' will receive value higher than allowed mired (%s) since provided Tuya kelvin value (%s) " +
101+
"is lower then configured minimum Tuya kelvin value (%s). Please update your configuration!",
102+
homekitColorTemp,
103+
tuyaValue,
104+
this.rangeMapper.tuyaStart
105+
);
106+
} else if (homekitColorTemp < this.minHomekit) {
107+
this.warn(
108+
"Characteristic 'ColorTemperature' will receive value lower than allowed mired (%s) since provided Tuya kelvin value (%s) " +
109+
"exceeds configured maximum Tuya kelvin value (%s). Please update your configuration!",
110+
homekitColorTemp,
111+
tuyaValue,
112+
this.rangeMapper.tuyaEnd
113+
);
114+
}
115+
65116
this.accessory.setCharacteristic(
66117
this.homekitCharacteristic,
67118
homekitColorTemp,
68119
!callback
69120
);
70121
callback && callback(null, homekitColorTemp);
122+
} else {
123+
callback &&
124+
callback(new Error("Could not find required property 'color_temp'"));
71125
}
72126
}
73127
}

src/accessories/characteristics/on.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ export class OnCharacteristic extends TuyaWebCharacteristic {
5555
);
5656
callback && callback(null, stateValue);
5757
} else {
58-
callback && callback(new Error("Could not get state from data"));
58+
callback &&
59+
callback(new Error("Could not find required property 'state'"));
5960
}
6061
}
6162
}

src/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ export type TuyaDeviceDefaults = {
1515
cover_characteristics: "Stop"[];
1616
min_brightness: string | number;
1717
max_brightness: string | number;
18+
min_kelvin: string | number;
19+
max_kelvin: string | number;
1820
};
1921

2022
type Config = {

0 commit comments

Comments
 (0)