deconz-rest-plugin icon indicating copy to clipboard operation
deconz-rest-plugin copied to clipboard

Hue white and color ambiance ZHA lights

Open ebaauw opened this issue 3 years ago • 9 comments

Device

  • Product name: Hue white and color ambiance
  • Manufacturer: Signify Netherlands B.V.
  • Model identifier: LCG002 (but also many others)
  • Device type: Extended color light

As discussed on Discord, this likely concerns all recent Hue lights, that use the ZHA profile on endpoint 0x0B instead of ZLL.

These lights support attribute reporting for On/Off, Current Level, Current X, Current Y, Color Temperature (but not: Color Mode, Enhanced Color Mode, and Color Loop Active). This should be leveraged to reduce polling.

With the latest firmware, these lights support dynamic scenes, Candle and Fireplace, through the 0xFC03 cluster, similar to the Hue gradient light strip, see https://github.com/dresden-elektronik/deconz-rest-plugin/issues/5891. 0xFC03/0x0002 supports attribute reporting as well. This should be supported by additional values for state.effect, similar to the special scenes in the Müller lights or LIDL Xmas light strip.

I've hacked together a definition of 0xFC03 for general.xml, allowing me to set the dynamic scene, and query 0xFC03/0x0002. Unfortunately, the GUI doesn't show data type ostring in a useful way, but at least you can trigger a Read Attributes and see the response in the sniffer.

    <cluster id="0xfc03" name="Hue" mfcode="0x100b">
      <description>Hue-specific cluster.</description>
      <server>
        <command id="0x00" dir="recv" name="Set Dynamic Scene" vendor="0x100b" required="m">
          <payload>
            <attribute id="0x0000" type="u16" name="Command" showas="hex" default="0x0020" required="m"/>
            <attribute id="0x0001" type="bool" name="Enable" required="m"/>
            <attribute id="0x0002" type="enum8" name="Scene" required="m">
              <value name="None" value="0x00"/>
              <value name="Candle" value="0x01"/>
              <value name="Fireplace" value="0x02"/>
            </attribute>
          </payload>
        </command>
        <attribute id="0x0002" name="Status" type="ostring" mfcode="0x100b" access="r" required="m"/>
      </server>
    </cluster>

Screenshots

Screenshot 2022-07-12 at 21 25 Screenshot 2022-07-12 at 21 28

Basic

Screenshot 2022-07-12 at 21 39

FC03

Screenshot 2022-07-12 at 21 40

ebaauw avatar Jul 12 '22 19:07 ebaauw

Got the white and color ambiance E27 bulb today, LCA006. Same Image Type and the Hue bridge upgraded it to 1.93.11 as well. Apart from the Model Identifier, the HW Version is the only difference: 1 instead of 3.

0xFC03/0x0002 seems to report the full state, as with the gradient light strip, see https://github.com/dresden-elektronik/deconz-rest-plugin/issues/5891#issuecomment-1073038477. That means we can probably do with a single binding and report config, and a Javascript file to parse the value and set all state resource items, including colormode! It doesn't indicate whether color loop is active, though, but it does report the continuously changing xy.

ebaauw avatar Jul 13 '22 17:07 ebaauw

Here's a first go at a DDF and accompanying switch. Should create a unicast binding for 0xFC03 and attribute reporting for 0x0002, with 300s interval. Attribute is linked to on, with a backup refresh interval of 330. Read on bri, ct, x and y should be disabled - I see no more polling in the sniffer. Issues:

  • No support for hue nor sat; when setting (Enhanced) Hue and/or Saturation, colormode reports xy;
  • ~~No support for setting effect, but it does report candle or fireplace correctly; It won't report colorloop correctly, though.~~

~~Here's the DDF, white_and_color_ambiance_ble.json:~~

~~And the fc03_state.js script to parse 0x0002:~~

See PR below for latest code.

ebaauw avatar Jul 13 '22 19:07 ebaauw

As there has not been any response in 21 days, this issue has been automatically marked as stale. At OP: Please either close this issue or keep it active It will be closed in 7 days if no further activity occurs.

github-actions[bot] avatar Aug 04 '22 02:08 github-actions[bot]

Ping

ebaauw avatar Aug 04 '22 08:08 ebaauw

Just got the Hue Signe Floor lamp and looking to get the three independent color zones working. Is this still an ongoing issue?

theCheek avatar Aug 20 '22 08:08 theCheek

I don't have a Signe, but I assume it's similar to the gradiant lightstrip, see https://github.com/dresden-elektronik/deconz-rest-plugin/issues/5891.

ebaauw avatar Aug 20 '22 08:08 ebaauw

As there has not been any response in 21 days, this issue has been automatically marked as stale. At OP: Please either close this issue or keep it active It will be closed in 7 days if no further activity occurs.

github-actions[bot] avatar Sep 11 '22 02:09 github-actions[bot]

Bump

ebaauw avatar Sep 11 '22 06:09 ebaauw

See PR for latest code.

Currrent State

  • ~~For now, use regular attributes for light state using Item/val, becauseR.item('state/...').val doesn't generate websocket notifications. By using 0xFC03/0x0002, on, bri, ct, and xy could be polled using a single read (combining three requests into one), and on, bri, ct, xy, and dynamic_effect could be reported in a single report (combining four reports into one);~~
  • ZLL light state is polled with 5 second refresh;
  • ZB3 light state is reported every 5 minutes (and on changes) with fallback polling. Note ~~the colormode and~~ effect ~~aren't~~ isn't reported, so these are polled every ~~5~~ 60 seconds.

TODO

  • ~~Make startup updatable from API;~~
  • ~~Make state/dynamic_effect updatable from API.~~

ISSUES

  • How to select lights based on manufacturer, profile (ZLL vs ZB3), device type, and presence of 0xFC03 cluster? I would prefer not to have to whitelist all model identifiers.
  • How to specify selective polling of Level Control, Color Control: only when light is on? Note that you'd need to specify somehow the order of the clusters for this; currently clusters are polled in reverse order: first Color Control, then Level Control, then On/Off. Note that this would still apply when using 0xFC03/0x0002, as ~~colormode and~~ effect ~~are~~ isn't in there. Ideally, I would only poll these after an attribute report has come in.
  • ~~startup/xy incorrectly reports the regular state/xy values: DDF doesn't seem to honour mf and uses the regular attributes instead. Note Hue lights use manufacturer-specific attributes 0x0003 and 0x0004 for startup colour.~~ Seems to be fixed, at least I'm seeing different values now.
  • ~~state/dynamic_effect: How to specify command payload/parameters from DDF? Or do we still need C++ code for that?~~ Created C++ code and combined dynamic effects into state.effect;
  • ~~Combine more than four attributes in a single read for polling - more than four doesn't seem to work. Currently poll Current X, Current Y, and Color Temperature separately from Enhanced Color Mode and Color Loop Active.~~

ebaauw avatar Sep 11 '22 15:09 ebaauw

As there has not been any response in 21 days, this issue has been automatically marked as stale. At OP: Please either close this issue or keep it active It will be closed in 7 days if no further activity occurs.

github-actions[bot] avatar Oct 04 '22 02:10 github-actions[bot]

Ping

ebaauw avatar Oct 04 '22 05:10 ebaauw

Doing some more tests, now that setting multiple items from a script will trigger the corresponding event notifications.

Look like the light firmware no longer reports Color Mode nor Enhanced Color Mode correctly. It seems to be updated only when explicitly setting a colour.

When activating colour loop, they report hs alright, but when deactivating colour loop, they continue to report hs, even though the light switched back to the previous colour mode, xy or ct. Worse, the FC03 attribute reports an xy state, even when the mode before the colour loop was ct and the light is actually driving the white channels (instead of the RGB channels). Same happens on a power cycle with power-on settings to previous state. The light comes back in ct mode alright, but reports xy.

ebaauw avatar Oct 15 '22 13:10 ebaauw

After some discussion with @Thomas-Vos if we could get the archetype as exposed by the Hue bridge from Hue lights, I sniffed the Hue bridge pairing an LCA006 bulb. This revealed the following manufacturer-specific attributes carried by the bulb:

Cluster Attribute Attribute Name Type Value
Basic 0x0000 cstring Unsupported
Basic 0x0001 uint32 0
Basic 0x0002 uint8 Unsupported
Basic 0x0003 uint8 Unsupported
Basic 0x0040 Product Identifier cstring Philips-LCA006-1-A60HECLv1
Basic 0x0041 Software Config Identifier map32 0xa7ea 4812
Basic 0x0050 map32 0x0000 0001
Basic 0xf109 boolean true
Level Control 0x0003 Min Dim Level uint16 200
0xfc01 0x0000 Capabilities map8 0x0b
0xfc01 0x0002 Segments Unsupported
0xfc03 0x0001 Capabilities map32 0x0000 0007
0xfc03 0x0002 Light State ostring 0f:00:01:fe:6e:01:0f:75:f5:68
0xfc03 0x0010 map16 0x0001
0xfc03 0x0011 Effects map64 0x0000 0000 0000 000e
0xfc03 0x0012 map32 Unsupported
0xfc03 0x0013 Gradient Styles map16 Unsupported
0xfc03 0x0030 Gradient Pixel Count uint8 Unsupported
Scenes 0x0001 map32 0x0000 0003

There's also a dialogue between the bridge and the bulb using manufacturer-specific commands on the Basic cluster. The bridge sends 0xc0 and the bulb responds with 0xc1. The payload for 0xc0 seems to be the starting point and max length; the payload for 0xc1 seems (at least in part) TLV encoded.

0xc0 0xc1
000000000040 0000000000004c000000350a4a0801158d667a8b1a410a064c434130303612185369676e696679204e65746865726c616e647320422e562e420e48756520636f
003500000040 0000350000004c000000176c6f72206c616d704802520b080b1207089f0810031801

Trying to decode the 0xc1 payload:

 0                    1                      2                      3                    4                   5                     6
 0 1 2 3 4 5 6 7 8 9  0  1  2 3  4 5 6 7 8 9 0 1  2 3  4 5 6 7 8 9  0 1  2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5  6 7  8 9 0 1 2 3
0000000000004c000000 35 0a 4a08 01158d667a8b1a41 0a06 4c4341303036 1218 5369676e696679204e65746865726c616e647320422e562e 420e 48756520636f
                                                       L C A 0 0 6       S i g n i f y   N e t h e r l a n d s   B . V .       H u e   c o


 0                    1                        2                     3        
 0 1 2 3 4 5 6 7 8 9  0  1  2 3  4 5 6 7  8 9  0 1  2 3  4 5 6 7 8 9 0 1 2
0000350000004c000000 17 6c6f72206c616d70 4802 520b 080b 1207089f0810031801
                         l o r   l a m p

ebaauw avatar Nov 18 '22 10:11 ebaauw

Added these newly discovered attributes to general.xml and queried all Hue lights I've currently online (LST001, LWB006, LCT007, LCT015, LCA006, LCE002, LCG002, LCL003, LCX004, LCX012, Hue Ensis, latest Hue Bloom).

As for the Basic cluster attributes:

  • 0x0000, 0x0002, and 0x0003 are only supported on older bulbs, but even then their values are empty string or 0.
  • 0x0001 seems supported by all but the gamut-A lights, but only shows value 0.
  • 0x0040 is indeed the productid from the Hue API v1;
  • 0x0041 is the swconfigid from the Hue API v1;
  • 0x0050 is 0x0000 0001 for all lights.
  • 0xf109 is not supported on older lights, but is true for the others.

0x0003 on the Level Control cluster matches the min_dim_level as exposed by the Hue API v2 times 1000. So a value of 1000 is exposed as 1.0 %.

As for the 0xfc01 cluster attributes:

  • 0x0000 is not supported on the LWB006 (dimmable light), 0x0a (0b1010) for the LST001 (gamut-A color light), 0x0b (0b1011) for the extended color lights, and 0x0f (0b1111) for the gradients. I would theorise the bitmap specified whether the light supports Hue entertainment (0b1000), multiple segments (0b0100), proxy (or renderer?) (0b0010) and renderer (or proxy?) (0b0001). Need to pair a gamut-A light with the Hue bridge to check which is renderer vs proxy.
  • 0x0002 indicates the maximum number of (entertainment) segments when other than 1. This is exposed as segments/max_segments under the entertainment endpoint of the Hue API v2. For both the Gradient light strip and the Festavia, this is 10. The lengths of the segments sum up to the pixel count.

As for the 0xfc03 cluster attributes:

  • 0x0001 is 0x0000 0003 for the ZLL bulbs, 0x0000 0007 for the ZB3 bulbs, and 0x0000 000f for the gradients. I would theorise the types of modes that 0x0002 could carry: xy, ct, effect, gradient.
  • 0x0010 is 0x0001 for all lights. I can only hypothesise that this corresponds to the API v1 colorloop effect or the API v2 dynamic_palette (although I haven't been able to set that).
  • 0x0011 is 0x00e for the ZB3 bulbs, 0x020e for the gradient strip, and 0x060e for the Festavia. The bit number seems to match the supported value for the effect:
    effect value in 0x0002 bit in 0x0011 value in 0x0011
    candle 0x01 0000 0000 0010 0x02
    fireplace 0x02 0000 0000 0100 0x04
    loop 0x03 0000 0000 1000 0x08
    sunrise 0x09 0010 0000 0000 0x20
    sparkle 0x0a 0100 0000 0000 0x40
  • 0x0012 is only supported on the gradients. It is 0x0001 for the gradient light strip and 0x0003 for the festavia. 0x0013 is only supported on the festavia, with value 0x0007. I suppose these encode the mode (or style in the app) for the gradients: interpolated_palette (Linear), interpolated_palette_mirrored, random_pixelated (Scattered)

ebaauw avatar Nov 18 '22 13:11 ebaauw

Here's a ZB3 light:

{
  "capabilities": {
    "alerts": [
      "none",
      "select",
      "lselect",
      "blink",
      "breathe",
      "okay",
      "channelchange",
      "finish",
      "stop"
    ],
    "bri": {
      "min_dim_level": 0.2
    },
    "color": {
      "ct": {
        "computes_xy": true,
        "max": 500,
        "min": 153
      },
      "effects": [
        "none",
        "colorloop",
        "candle",
        "fireplace",
        "loop"
      ],
      "gamut_type": "C",
      "modes": [
        "ct",
        "effect",
        "hs",
        "xy"
      ],
      "xy": {
        "blue": [
          0.1532,
          0.0475
        ],
        "green": [
          0.17,
          0.7
        ],
        "red": [
          0.6915,
          0.3083
        ]
      }
    }
  },
  "colorcapabilities": 31,
  "config": {
    "bri": {
      "execute_if_off": true,
      "startup": "previous"
    },
    "color": {
      "ct": {
        "startup": "previous"
      },
      "execute_if_off": true,
      "xy": {
        "startup": "previous"
      }
    },
    "groups": [
      "0",
      "256"
    ],
    "on": {
      "startup": false
    }
  },
  "ctmax": 500,
  "ctmin": 153,
  "etag": "86a0cae2ac651d3b4c3ae6019abd7136",
  "hascolor": true,
  "lastannounced": null,
  "lastseen": "2022-11-20T15:22Z",
  "manufacturername": "Signify Netherlands B.V.",
  "modelid": "LCA006",
  "name": "Hue Gamut-C",
  "productid": "Philips-LCA006-1-A60HECLv1",
  "state": {
    "alert": "none",
    "bri": 57,
    "colormode": "xy",
    "ct": 366,
    "effect": "candle",
    "hue": 7846,
    "on": false,
    "reachable": true,
    "sat": 188,
    "xy": [
      0.4923,
      0.4149
    ]
  },
  "swconfigid": "A7EA4812",
  "swversion": "1.93.11",
  "type": "Extended color light",
  "uniqueid": "00:17:88:01:0b:1c:ff:75-0b"
}

ebaauw avatar Nov 19 '22 21:11 ebaauw

Here's a gamut-C ZLL light:

{
  "capabilities": {
    "alerts": [
      "none",
      "select",
      "lselect",
      "blink",
      "breathe",
      "okay",
      "channelchange",
      "finish",
      "stop"
    ],
    "bri": {
      "min_dim_level": 1
    },
    "color": {
      "ct": {
        "computes_xy": true,
        "max": 500,
        "min": 153
      },
      "effects": [
        "none",
        "colorloop"
      ],
      "gamut_type": "C",
      "modes": [
        "ct",
        "effect",
        "hs",
        "xy"
      ],
      "xy": {
        "blue": [
          0.1532,
          0.0475
        ],
        "green": [
          0.17,
          0.7
        ],
        "red": [
          0.6915,
          0.3083
        ]
      }
    }
  },
  "colorcapabilities": 31,
  "config": {
    "bri": {
      "startup": "previous"
    },
    "color": {
      "ct": {
        "startup": "previous"
      },
      "xy": {
        "startup": "previous"
      }
    },
    "groups": [
      "0",
      "256"
    ],
    "on": {
      "startup": false
    }
  },
  "ctmax": 500,
  "ctmin": 153,
  "etag": "2be42cb76ac17a309d362f2a6a309bf1",
  "hascolor": true,
  "lastannounced": null,
  "lastseen": "2022-11-20T15:23Z",
  "manufacturername": "Signify Netherlands B.V.",
  "modelid": "LCT015",
  "name": "Hue Gamut-C ZLL",
  "productid": "Philips-LCT015-2-A19ECLv5",
  "state": {
    "alert": "none",
    "bri": 254,
    "colormode": "ct",
    "ct": 366,
    "effect": "none",
    "hue": 8417,
    "on": false,
    "reachable": true,
    "sat": 140,
    "xy": [
      0.4573,
      0.41
    ]
  },
  "swconfigid": "F17C3A73",
  "swversion": "1.88.1",
  "type": "Extended color light",
  "uniqueid": "00:17:88:01:04:34:2c:ff-0b"
}

ebaauw avatar Nov 19 '22 21:11 ebaauw

Here's a gamut-B ZLL light:

{
  "capabilities": {
    "alerts": [
      "none",
      "select",
      "lselect",
      "blink",
      "breathe",
      "okay",
      "channelchange",
      "finish",
      "stop"
    ],
    "bri": {
      "min_dim_level": 2
    },
    "color": {
      "ct": {
        "computes_xy": true,
        "max": 500,
        "min": 153
      },
      "effects": [
        "none",
        "colorloop"
      ],
      "gamut_type": "B",
      "modes": [
        "ct",
        "effect",
        "hs",
        "xy"
      ],
      "xy": {
        "blue": [
          0.167,
          0.04
        ],
        "green": [
          0.409,
          0.518
        ],
        "red": [
          0.675,
          0.322
        ]
      }
    }
  },
  "colorcapabilities": 31,
  "config": {
    "bri": {
      "startup": "previous"
    },
    "color": {
      "ct": {
        "startup": "previous"
      },
      "xy": {
        "startup": "previous"
      }
    },
    "groups": [
      "0",
      "256"
    ],
    "on": {
      "startup": false
    }
  },
  "ctmax": 500,
  "ctmin": 153,
  "etag": "438febf7ab2cd835fc0be299aec9751a",
  "hascolor": true,
  "lastannounced": null,
  "lastseen": "2022-11-19T21:12Z",
  "manufacturername": "Signify Netherlands B.V.",
  "modelid": "LCT007",
  "name": "Hue Gamut-B ZLL",
  "state": {
    "alert": "none",
    "bri": 10,
    "colormode": "xy",
    "ct": 500,
    "effect": "none",
    "hue": 0,
    "on": false,
    "reachable": true,
    "sat": 254,
    "xy": [
      0.675,
      0.322
    ]
  },
  "swversion": "67.88.1",
  "type": "Extended color light",
  "uniqueid": "00:17:88:01:10:41:c0:e6-0b"
}

ebaauw avatar Nov 19 '22 21:11 ebaauw

I added the 0xC0 / 0xC1 commands to the Basic cluster, for querying the Hue light capabilities. If the payload length is larger than 0x35, you need to issue multiple 0xC0 commands to get the full payload. Note that the requested length of 0x40 (64) is including the 10 bytes before the payload and the length byte, so the first 0xC1 returns 0x35 (53) bytes. Hence the next 0xC0 uses an offset of 0x35.

Untitled

ebaauw avatar Nov 19 '22 21:11 ebaauw

Also did the Hue smart plug:

{
  "capabilities": {
    "alerts": [
      "none",
      "select",
      "lselect",
      "blink",
      "breathe",
      "okay",
      "channelchange",
      "finish",
      "stop"
    ]
  },
  "config": {
    "groups": [
      "0"
    ],
    "on": {
      "startup": false
    }
  },
  "etag": "edbf69445ba97934cc35ddd94e8f7a79",
  "hascolor": false,
  "lastannounced": null,
  "lastseen": "2022-11-20T15:24Z",
  "manufacturername": "Signify Netherlands B.V.",
  "modelid": "LOM007",
  "name": "Hue smart plug",
  "productid": "Philips-LOM007-1-SPPIUv2",
  "state": {
    "alert": "none",
    "on": false,
    "reachable": true
  },
  "swconfigid": "493EC159",
  "swversion": "1.93.6",
  "type": "On/Off plug-in unit",
  "uniqueid": "00:17:88:01:0b:df:e7:98-0b"
}

Not sure if all the alerts make sense, but the plug does seem to support them. It also accepts Off with Effect, which is what the Hue bridge sends to turn it off.

ebaauw avatar Nov 20 '22 15:11 ebaauw

As there has not been any response in 21 days, this issue has been automatically marked as stale. At OP: Please either close this issue or keep it active It will be closed in 7 days if no further activity occurs.

github-actions[bot] avatar Dec 14 '22 02:12 github-actions[bot]

Bump

ebaauw avatar Dec 14 '22 08:12 ebaauw