Skip to content

Commit

Permalink
fix: Align options.supportsHS with meta.supportsHueAndSaturation (#5811)
Browse files Browse the repository at this point in the history
* fix: rename option supportsHS to supportsHueAndSaturation

This brings it inline with the naming for meta, are used to indicate support for Hue/Saturation for a device.
The meta is used by the converters and the option by the exposes data.

* fix: renamed enhancedHue to supportsEnhancedHue

This brings the naming more inline with the nameing of the other meta's

* fix: rename options.preferHS to options.preferHueAndSaturation

* fix: align default for meta.supportsHueAndSaturation in README.md with light.readColorAttributes

According to the readme `supportsHueAndSaturation` has a default of false, however in `light.readColorAttributes()` we used a default of true.
This change corrects it to the default mentioned in readme.md

* fix: converter should throw error when Hue/Saturation not supported

Bulbs like **TRADFRI bulb E27 CWS opal 600lm** do not support HS, we already skip reading those attributes, however the toZigbee converter does still try to call the moveHue and friends commands which do not work when specifying a `{"color": {"hue": 128, "saturation": 100}` payload. Now we throw an error making it clean this is not supported.

* fix: extend should pass options.supportsHueSaturation to meta.supportsHueSaturation

---------

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
  • Loading branch information
sjorge and Koenkk authored Jun 1, 2023
1 parent b91a81b commit e6f0399
Show file tree
Hide file tree
Showing 23 changed files with 83 additions and 72 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ If any of those commands finish with an error your PR won't pass the tests and w
- `multiEndpointEnforce`: enforce a certain endpoint for an attribute, e.g. {"power": 4} see utils.enforceEndpoint()
- `disableDefaultResponse`: used by toZigbee converters to disable the default response of some devices as they don't provide one. (default: false)
- `applyRedFix`: see toZigbee.light_color (default: false)
- `enhancedHue`: see toZigbee.light_color (default: true)
- `supportsHueAndSaturation`: see toZigbee.light_color (default: false)
- `supportsEnhancedHue`: see toZigbee.light_color (default: true)
- `supportsHueAndSaturation`: see toZigbee.light_color (default: true), usually set by light_* extends via options.
- `timeout`: timeout for commands to this device used in toZigbee. (default: 10000)
- `coverInverted`: Set to true for cover controls that report position=100 as open (default: false)
- `coverStateFromTilt`: Set cover state based on tilt
Expand Down
17 changes: 11 additions & 6 deletions src/converters/toZigbee.js
Original file line number Diff line number Diff line change
Expand Up @@ -1077,7 +1077,13 @@ const converters = {

const zclData = {transtime: utils.getTransition(entity, key, meta).time};

if (newColor.isRGB() || newColor.isXY()) {
const supportsHueAndSaturation = utils.getMetaValue(entity, meta.mapped, 'supportsHueAndSaturation', 'allEqual', true);
const supportsEnhancedHue = utils.getMetaValue(entity, meta.mapped, 'supportsEnhancedHue', 'allEqual', true);

if (newColor.isHSV() && !supportsHueAndSaturation) {
// The color we got is HSV but the bulb does not support Hue/Saturation mode
throw new Error('This light does not support Hue/Saturation, please use X/Y instead.');
} else if (newColor.isRGB() || newColor.isXY()) {
// Convert RGB to XY color mode because Zigbee doesn't support RGB (only x/y and hue/saturation)
const xy = newColor.isRGB() ? newColor.rgb.gammaCorrected().toXY().rounded(4) : newColor.xy;

Expand All @@ -1096,14 +1102,13 @@ const converters = {
zclData.colory = utils.mapNumberRange(xy.y, 0, 1, 0, 65535);
command = 'moveToColor';
} else if (newColor.isHSV()) {
const enhancedHue = utils.getMetaValue(entity, meta.mapped, 'enhancedHue', 'allEqual', true);
const hsv = newColor.hsv;
const hsvCorrected = hsv.colorCorrected(meta);
newState.color_mode = constants.colorModeLookup[0];
newState.color = hsv.toObject(false);

if (hsv.hue !== null) {
if (enhancedHue) {
if (supportsEnhancedHue) {
zclData.enhancehue = utils.mapNumberRange(hsvCorrected.hue, 0, 360, 0, 65535);
} else {
zclData.hue = utils.mapNumberRange(hsvCorrected.hue, 0, 360, 0, 254);
Expand All @@ -1121,13 +1126,13 @@ const converters = {
}

if (hsv.hue !== null && hsv.saturation !== null) {
if (enhancedHue) {
if (supportsEnhancedHue) {
command = 'enhancedMoveToHueAndSaturation';
} else {
command = 'moveToHueAndSaturation';
}
} else if (hsv.hue !== null) {
if (enhancedHue) {
if (supportsEnhancedHue) {
command = 'enhancedMoveToHue';
} else {
command = 'moveToHue';
Expand Down Expand Up @@ -4413,7 +4418,7 @@ const converters = {
state['color'] = newColor.xy.toObject();
} else if (newColor.isHSV()) {
const hsvCorrected = newColor.hsv.colorCorrected(meta);
if (utils.getMetaValue(entity, meta.mapped, 'enhancedHue', 'allEqual', true)) {
if (utils.getMetaValue(entity, meta.mapped, 'supportsEnhancedHue', 'allEqual', true)) {
const hScaled = utils.mapNumberRange(hsvCorrected.hue, 0, 360, 0, 65535);
const sScaled = utils.mapNumberRange(hsvCorrected.saturation, 0, 100, 0, 254);
extensionfieldsets.push(
Expand Down
4 changes: 2 additions & 2 deletions src/devices/adurosmart.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ module.exports = [
model: '81809FBA',
vendor: 'AduroSmart',
description: 'ERIA colors and white shades smart light bulb A19/BR30',
extend: extend.light_onoff_brightness_colortemp_color({supportsHS: true, colorTempRange: [153, 500]}),
extend: extend.light_onoff_brightness_colortemp_color({supportsHueAndSaturation: true, colorTempRange: [153, 500]}),
meta: {applyRedFix: true},
},
{
Expand Down Expand Up @@ -124,7 +124,7 @@ module.exports = [
model: '81863',
vendor: 'AduroSmart',
description: 'Eria color LED strip',
extend: extend.light_onoff_brightness_colortemp_color({supportsHS: true, colorTempRange: [153, 500]}),
extend: extend.light_onoff_brightness_colortemp_color({supportsHueAndSaturation: true, colorTempRange: [153, 500]}),
meta: {applyRedFix: true},
},
];
2 changes: 1 addition & 1 deletion src/devices/ajax_online.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ module.exports = [
vendor: 'Ajax Online',
description: 'Smart Zigbee LED strip RGB+CCT',
extend: tuya.extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
meta: {applyRedFix: true, enhancedHue: false},
meta: {applyRedFix: true, supportsEnhancedHue: false},
},
{
fingerprint: [{modelID: 'CCT Light', manufacturerName: 'ZB/Ajax Online', manufacturerID: 4137}],
Expand Down
2 changes: 1 addition & 1 deletion src/devices/awox.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ module.exports = [
model: '33943/33944/33946',
vendor: 'AwoX',
description: 'LED RGB & brightness',
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 370], supportsHS: true}),
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 370], supportsHueAndSaturation: true}),
},
{
fingerprint: [
Expand Down
2 changes: 1 addition & 1 deletion src/devices/evn.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ module.exports = [
model: 'ZB24100VS',
vendor: 'EVN',
description: 'Zigbee multicolor controller with power supply',
extend: extend.light_onoff_brightness_colortemp_color({supportsHS: true, colorTempRange: [160, 450]}),
extend: extend.light_onoff_brightness_colortemp_color({supportsHueAndSaturation: true, colorTempRange: [160, 450]}),
},
];
2 changes: 1 addition & 1 deletion src/devices/gidealed.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ module.exports = [
model: 'ZC05M',
vendor: 'GIDEALED',
description: 'Smart Zigbee RGB LED strip controller',
extend: extend.light_onoff_brightness_colortemp_color({supportsHS: true, colorTempRange: [153, 370]}),
extend: extend.light_onoff_brightness_colortemp_color({supportsHueAndSaturation: true, colorTempRange: [153, 370]}),
},
];
2 changes: 1 addition & 1 deletion src/devices/giderwel.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ module.exports = [
model: 'GD-ZCRGB012',
vendor: 'GIDERWEL',
description: 'Smart Zigbee RGB LED strip controller',
extend: extend.light_onoff_brightness_color({supportsHS: false}),
extend: extend.light_onoff_brightness_color({supportsHueAndSaturation: false}),
},
];
4 changes: 2 additions & 2 deletions src/devices/gledopto.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ const gledoptoExtend = {
),
}),
light_onoff_brightness_color: (options={}) => ({
...extend.light_onoff_brightness_color({disablePowerOnBehavior: true, supportsHS: true, ...options}),
...extend.light_onoff_brightness_color({disablePowerOnBehavior: true, supportsHueAndSaturation: true, ...options}),
toZigbee: utils.replaceInArray(
extend.light_onoff_brightness_color(options).toZigbee,
[tz.light_onoff_brightness, tz.light_color],
[tz.gledopto_light_onoff_brightness, tz.gledopto_light_color],
),
}),
light_onoff_brightness_colortemp_color: (options={}) => ({
...extend.light_onoff_brightness_colortemp_color({disablePowerOnBehavior: true, supportsHS: true, ...options}),
...extend.light_onoff_brightness_colortemp_color({disablePowerOnBehavior: true, supportsHueAndSaturation: true, ...options}),
toZigbee: utils.replaceInArray(
extend.light_onoff_brightness_colortemp_color(options).toZigbee,
[tz.light_onoff_brightness, tz.light_color_colortemp],
Expand Down
48 changes: 25 additions & 23 deletions src/devices/innr.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,23 +51,25 @@ module.exports = [
model: 'FL 140 C',
vendor: 'Innr',
description: 'Color Flex LED strip 4m 1200lm',
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHS: true}),
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHueAndSaturation: true}),
meta: {applyRedFix: true, turnsOffAtBrightness1: true},
},
{
zigbeeModel: ['FL 130 C'],
model: 'FL 130 C',
vendor: 'Innr',
description: 'Color Flex LED strip',
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHS: true}),
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHueAndSaturation: true}),
meta: {applyRedFix: true, turnsOffAtBrightness1: true},
},
{
zigbeeModel: ['FL 120 C'],
model: 'FL 120 C',
vendor: 'Innr',
description: 'Color Flex LED strip',
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHS: true, disablePowerOnBehavior: true}),
extend: extend.light_onoff_brightness_colortemp_color({
colorTempRange: [153, 555], supportsHueAndSaturation: true, disablePowerOnBehavior: true},
),
meta: {applyRedFix: true, turnsOffAtBrightness1: true},
},
{
Expand All @@ -84,7 +86,7 @@ module.exports = [
model: 'OGL 130 C',
vendor: 'Innr',
description: 'Outdoor smart globe lights',
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [100, 1000], supportsHS: true}),
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [100, 1000], supportsHueAndSaturation: true}),
meta: {applyRedFix: true, turnsOffAtBrightness1: true},
},
{
Expand All @@ -93,40 +95,40 @@ module.exports = [
vendor: 'Innr',
description: 'Outdoor smart pedestal light colour',
extend: extend.light_onoff_brightness_colortemp_color(
{colorTempRange: [153, 555], supportsHS: true, disableColorTempStartup: true}),
{colorTempRange: [153, 555], supportsHueAndSaturation: true, disableColorTempStartup: true}),
meta: {applyRedFix: true, turnsOffAtBrightness1: true},
},
{
zigbeeModel: ['RB 185 C'],
model: 'RB 185 C',
vendor: 'Innr',
description: 'E27 bulb RGBW',
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHS: true}),
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHueAndSaturation: true}),
meta: {applyRedFix: true, turnsOffAtBrightness1: true},
},
{
zigbeeModel: ['BY 185 C'],
model: 'BY 185 C',
vendor: 'Innr',
description: 'B22 bulb RGBW',
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHS: true}),
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHueAndSaturation: true}),
meta: {applyRedFix: true, turnsOffAtBrightness1: true},
},
{
zigbeeModel: ['RB 250 C'],
model: 'RB 250 C',
vendor: 'Innr',
description: 'E14 bulb RGBW',
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHS: true}),
meta: {enhancedHue: false, applyRedFix: true, turnsOffAtBrightness1: true},
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHueAndSaturation: true}),
meta: {supportsEnhancedHue: false, applyRedFix: true, turnsOffAtBrightness1: true},
},
{
zigbeeModel: ['RB 251 C'],
model: 'RB 251 C',
vendor: 'Innr',
description: 'E14 bulb RGBW',
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHS: true}),
meta: {enhancedHue: false, applyRedFix: true, turnsOffAtBrightness1: true},
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHueAndSaturation: true}),
meta: {supportsEnhancedHue: false, applyRedFix: true, turnsOffAtBrightness1: true},
ota: ota.zigbeeOTA,
},
{
Expand Down Expand Up @@ -195,15 +197,15 @@ module.exports = [
model: 'RB 285 C',
vendor: 'Innr',
description: 'E27 bulb RGBW',
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHS: true}),
meta: {enhancedHue: false, applyRedFix: true, turnsOffAtBrightness1: true},
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHueAndSaturation: true}),
meta: {supportsEnhancedHue: false, applyRedFix: true, turnsOffAtBrightness1: true},
},
{
zigbeeModel: ['RB 286 C'],
model: 'RB 286 C',
vendor: 'Innr',
description: 'E27 bulb RGBW',
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHS: true}),
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHueAndSaturation: true}),
meta: {applyRedFix: true, turnsOffAtBrightness1: true},
ota: ota.zigbeeOTA,
},
Expand All @@ -212,15 +214,15 @@ module.exports = [
model: 'BY 285 C',
vendor: 'Innr',
description: 'B22 bulb RGBW',
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHS: true}),
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHueAndSaturation: true}),
meta: {applyRedFix: true, turnsOffAtBrightness1: true},
},
{
zigbeeModel: ['BY 286 C'],
model: 'BY 286 C',
vendor: 'Innr',
description: 'B22 bulb RGBW',
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHS: true}),
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHueAndSaturation: true}),
meta: {applyRedFix: true, turnsOffAtBrightness1: true},
ota: ota.zigbeeOTA,
},
Expand Down Expand Up @@ -344,9 +346,9 @@ module.exports = [
model: 'RS 230 C',
vendor: 'Innr',
description: 'GU10 spot 350 lm, dimmable, RGBW',
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHS: true}),
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHueAndSaturation: true}),
exposes: [e.light_brightness_colortemp_color()],
meta: {enhancedHue: false, applyRedFix: true, turnsOffAtBrightness1: true},
meta: {supportsEnhancedHue: false, applyRedFix: true, turnsOffAtBrightness1: true},
ota: ota.zigbeeOTA,
},
{
Expand Down Expand Up @@ -536,7 +538,7 @@ module.exports = [
model: 'AE 280 C',
vendor: 'Innr',
description: 'E26 bulb RGBW',
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHS: true}),
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHueAndSaturation: true}),
meta: {applyRedFix: true, turnsOffAtBrightness1: true},
ota: ota.zigbeeOTA,
},
Expand Down Expand Up @@ -646,31 +648,31 @@ module.exports = [
model: 'OFL 120 C',
vendor: 'Innr',
description: 'Outdoor flex light colour LED strip 2m, 550lm, RGBW',
extend: extend.light_onoff_brightness_colortemp_color({supportsHS: true}),
extend: extend.light_onoff_brightness_colortemp_color({supportsHueAndSaturation: true}),
meta: {applyRedFix: true, turnsOffAtBrightness1: true},
},
{
zigbeeModel: ['OFL 140 C'],
model: 'OFL 140 C',
vendor: 'Innr',
description: 'Outdoor flex light colour LED strip 4m, 1000lm, RGBW',
extend: extend.light_onoff_brightness_colortemp_color({supportsHS: true}),
extend: extend.light_onoff_brightness_colortemp_color({supportsHueAndSaturation: true}),
meta: {applyRedFix: true, turnsOffAtBrightness1: true},
},
{
zigbeeModel: ['OFL 142 C'],
model: 'OFL 142 C',
vendor: 'Innr',
description: 'Outdoor flex light colour LED strip 4m, 1440lm, RGBW',
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [100, 350], supportsHS: true}),
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [100, 350], supportsHueAndSaturation: true}),
meta: {applyRedFix: true, turnsOffAtBrightness1: true},
},
{
zigbeeModel: ['OSL 130 C'],
model: 'OSL 130 C',
vendor: 'Innr',
description: 'Outdoor smart spot colour, 230lm/spot, RGBW',
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHS: true}),
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHueAndSaturation: true}),
meta: {applyRedFix: true, turnsOffAtBrightness1: true},
},
{
Expand Down
2 changes: 1 addition & 1 deletion src/devices/kurvia.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module.exports = [
description: 'GU10 GRBWC built from AliExpress',
extend: extendData,
toZigbee: [tz.on_off].concat(extendData.toZigbee),
meta: {applyRedFix: true, enhancedHue: false},
meta: {applyRedFix: true, supportsEnhancedHue: false},
},
];

4 changes: 3 additions & 1 deletion src/devices/lidl.js
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,9 @@ module.exports = [
model: 'HG08633',
vendor: 'Lidl',
description: 'Livarno gardenspot RGB',
extend: tuya.extend.light_onoff_brightness_colortemp_color({supportsHS: true, preferHS: true, colorTempRange: [153, 500]}),
extend: tuya.extend.light_onoff_brightness_colortemp_color({
supportsHueAndSaturation: true, preferHueAndSaturation: true, colorTempRange: [153, 500],
}),
},
{
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_chyvmhay'}],
Expand Down
8 changes: 4 additions & 4 deletions src/devices/müller_licht.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ module.exports = [
model: '404000/404005/404012/404019',
vendor: 'Müller Licht',
description: 'Tint LED bulb GU10/E14/E27 350/470/806 lumen, dimmable, color, opal white',
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 556], supportsHS: true}),
toZigbee: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 556], supportsHS: true}).toZigbee
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 556], supportsHueAndSaturation: true}),
toZigbee: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 556], supportsHueAndSaturation: true}).toZigbee
.concat([tz.tint_scene]),
// GU10 bulb does not support enhancedHue,
// GU10 bulb does not support supportsEnhancedHue,
// we can identify these based on the presense of haDiagnostic input cluster
meta: {enhancedHue: (entity) => !entity.getDevice().getEndpoint(1).inputClusters.includes(2821)},
meta: {supportsEnhancedHue: (entity) => !entity.getDevice().getEndpoint(1).inputClusters.includes(2821)},
},
{
zigbeeModel: ['ZBT-ColorTemperature'],
Expand Down
Loading

0 comments on commit e6f0399

Please sign in to comment.