With latest firmware, Hue white and color ambiance lights carry a manufacturer-s…pecific cluster 0xFC03. On newer Zigbee 3 lights (typically with BLE support), this is used to set Hue-specific effects, gradient points, etc. It also reports the current light state in a single attribute, combining info from the _On/Off_, _Level Control_, and _Color Control_ cluster. The older ZLL lights (typically without BLE support) carry this cluster as well, but don't support atrribute reporting. See #6192 and #5891.
In essence, this PR provides DDFs and the supporting C++ code for Hue (white and) color ambiance lights:
- One for gradient lights, adding support for gradient mode and dynamic effects, and setting up attribute reporting for the 0xFC03 state attribute, with fallback polling;
- One for the Hue Festavia gradient string light (see #6536);
- One for Zigbee 3 white and color ambiance lights, adding support for dynamic effects, and setting up attribute reporting for the 0xFC03 state attribute, with fallback polling; and
- One for ZLL gamut-C white and color lights, with polling of the 0xFC03 state attribute.
- One for ZLL gamut-B white and color lights, with polling of the 0xFC03 state attribute.
- One for ZLL gamut-A color ambiance lights, that don't support colour temperature and don't carry the 0xFC03 cluster.
The FC03 state attribute encodes the values of _On/Off_, _Current Level_, _Current X_, _Current Y_, _Color Temperature_, the Hue effect, and the gradient. However, it does not include _Enhanced Current Hue_, _Current Saturation_, _Color Loop Active_, and _Enhanced Color Mode_. Also, these attributes are stlll not reportable.
The Hue API v2 no longer supports setting colours through `hue` and `sat`. It still supports colour loop from the ZLL extensions, but quite differently from the Hue API v1. Also, there is an undocumented dynamic effect, that looks like colour loop, but behaves a bit differently.
I wouldn't mind dropping support for `state/hue` and `state/sat` altogether, but I would hate dropping the colour loop effect from `state/effect`. Also, the colour mode cannot be deduced from the FC03 state in all cases. Consequently, we still need to poll the _Color Control_ cluster for _Enhanced Color Mode_ and _Color Loop Active_. Since we can read _Enhanced Current Hue_, _Current Saturation_ in the same command, I'll leave `state/hue` and `state/sat` in for now.
This PR adds `capabilities` and `config` maps to `lights` resources. Changes of attributes in these maps are reported in separate web socket push notifications for `capabilities` and `config`. The attributes in `capabilities` are read-only; those in `config` are read/write. The `capabilities` resource items in C++ are prefixed with `RCap`; the items in the DDFs are prefixed with `cap/`.
The ambition for `capabilities` is to eliminate the need to whitelist lights on manufacturer and model. All device-dependent behaviour would be modelled using capabilities instead. Some capabilities are for internal use by the REST API plugin only. You would add them to the DDF, but they're not exposed through the API.
The following table lists the `capabilities` attributes:
Atttribute | Default | API | DDF | Description
-- | -- | -- | -- | --
`alert/trigger_effect`| `true` | | Y | Subdevice supports _Trigger Effect_.<br>Exposed through `capabilities/alerts`.
`alerts` | | Y | | List with supported `state.alert` values.<br>Note that `state/alert` is write-only and always reports `"none"`.
`bri` | | | | Map with _Level Control_ capabilities.
`bti/min_dim_level` | | Y | Y | Percentage of lumen the light outputs at minimum value for `state/bri`.
`bri/move_with_onoff` | `true` | | Y | Subdevice supports _Move to Level (with On/Off)_.<br>Influences the subdevice on/off logic.
`color` | | Y | | Map with _Color Control_ capabilities.<br>Replaces deprecated top-level attribute `hascolor`.
`color/capabilities` | | | Y | Bitmap with supported colour modes.<br>Replaces deprecated top-level attribute `colorcapabilities`.<br>Exposed through `capabilities/color/mode` and `capabilities/color/effects`.
`color/ct` | | Y | | Map with colour temperature capabilities.
`color/ct/computes_xy` | `true` | Y | Y | Light computes and updates `state/xy`, while in `ct` colour mode.
`color/ct/max`| `500` | Y | Y | Maximum supported `state/ct` value.<br>Replaces deprecated top-level attribute `ctmax`.
`color/ct/min` | `153` | Y | Y | Minimum supported `state/ct` value.<br>Replaces deprecated top-level attribute `ctmin`.
`color/effects`| | Y | | List of supported `state/effect` values.<br>Lights supporting colour loop and/or dynamic effects.<br>Hue white and color ambiance ZB3 lights support new values, see #6192.
`color/gamut_type` | | Y | Y | Hue gamut type: `"A"`, `"B"`, or `"C"`.<br>Hue (white and) color ambiance lights.
`color/gradient` | | Y | | Map with gradient capabilities.<br>Hue white and color ambiance gradient lights, see #5891 and #6536.
`color/gradient/max_segments` | | Y | Y | Maximum supported `state/gradient/segments` value.
`color/gradient/pixel_count` | | Y | Y | Number of gradient "pixels".
`color/gradient/pixel_length` | | Y | Y | Physical length (in 0.1 mm) of a gradient "pixel".
`color/gradient/styles` | | Y | Y | List of supported `state/gradient/style` values.<br>Note that I'm using the friendly names from the Hue app, rather than the technical names from the Hue API v2.
`color/modes` | | Y | | List with supported `state/colormode` values:<br>- `ct`: Colour temperature;<br>- `effect`: Dynamic effect;<br>- `gradient`: Gradient;<br>- `hs`: Colour by hue/saturation;<br>- `xy`: Colour by CIE 1931 colour space coordinates.
`color/xy` | | Y | | Map with supported values for `state/xy`.
`color/xy/red` | `[0.9961, 0]` | Y | | Red-most value for `state/xy`.
`color/xy/red_x` | `0xFEFF` | | Y | Red-most value for _Current X_.
`color/xy/red_y` | `0` | | Y | Red-most value for _Current Y_.
`color/xy/green` | `[0, 0.9961]` | Y | | Green-most value for `state/xy`.
`color/xy/green_x` | `0` | | Y | Green-most value for _Current X_.
`color/xy/green_y` | `0xFEFF` | | Y | Green-most value for _Current Y_.
`color/xy/blue` | `[0, 0]` | Y | | Blue-most value for `state/xy`.
`color/xy/blue_x` | `0` | Y | | Blue-most value for _Current X_.
`color/xy/blue_y` | `0` | Y | | Blue-most value for _Current Y_.
`groups` | | | | Map with _Groups_ capabilities.
`groups/not_supported` | `true` | | Y | _Groups_ cluster does not work<br>Subdevice cannot be included in a group.<br>Exposed through (absence of) `config/groups`.
`on` | | Y | | Map with _On/Off_ capabilities.
`on/off_with_effect` | `true` | Y | Y | Device supports _Off with Effect_ command.<br>Influences the subdevice off logic, see #6104.
`sleeper` | `true` | Y | Y | Device turns radio off for more than 7.5s.<br>Influence the logic of interacting with the device.
`transition_block` | `true` | Y | Y | Device doesn't accept commands during active transition.<br>Bug in older IKEA firmware.
With these changes, attributes `ctmax`, `ctmin`, `colormode`, and `hascolor` have become obsolete and should be deprecated. To remove them from the light state, specify `Accept: application/vnd.ddel.v3` in the HTTP header.
The following table lists the `config` attributes:
Atttribute | Default | API | DDF | Description
-- | -- | -- | -- | --
`bri` | | | | Map with _Level Control_ settings.
`bri/execute_if_off` | `true` | | Y | Change brightness while light is off.<br>Lights supporting _Execute If Off_, see #6454.
`bri/max` | `254` | Y | Y | Maximum `state/bri` value for dimmer ballast.<br>Lights supporting _Ballast Configuration_.
`bri/min` | `1` | Y | Y | Minimum `state/bri` value for dimmer ballast.<br>Lights supporting _Ballast Configuration_.
`bri/on_level` | `true` | Y | Y | Default `state/bri` value when turning light on.<br>Lights supporting _On Level_, see #149.
`bri/onoff_transitiontime` | `4`| Y | Y | Default transition time (in 0.1 s) when turning light on or off<br>Lights supporting _OnOff Transition Time_, see #149.
`bri/startup` | `254` | Y | Y | Startup value for `state/bri`, from `0` to `254`, or `"previous"`.<br>Lights that support _Startup Current Level_;
`color` | | Y | | Map with _Color Control_ settings.
`color/ct` | | Y | | Map with colour temperature settings.
`color/ct/startup` | `366` | Y | Y | Startup value for `state/ct`: `ct` value or `"previous"`.<br>Lights that support _Startup Color Temperature_;
`color/execute_if_off` | `true` | | Y | Change colour (temperature) while light is off.<br>Lights supporting _Execute If Off_, see #6454.
`color/gradient` | | Y | | Map with gradient settings.
`color/gradient/reversed` | `false` | Y | Y | Gradient colours are reversed.
`color/xy` | | Y | | Map with colour settings.
`color/xy/startup` |`"previous"` | Y | | Startup value for `state/xy`: `xy` value or `"previous"`.<br>Hue white and color ambiance lights.
`color/xy/startup_x` |`0xFFFF` | | Y | Startup value for _Current X_.
`color/xy/startup_y` |`0xFFFF` | | Y | Startup value for _Current Y_.
`groups` | | Y | N | List with `groups` resource IDs of groups that the subdevice has joined.
`on` | | Y | | Map with _On/Off_ settings.
`on/startup` | `true`| Y | Y | Startup value for `state/on`: `true`, `false`, or `"previous"`.<br>Lights that support _Startup On/Off_.
Furthermore, this PR creates the following `state` attributes:
Attribute | Default | Description
-- | -- | --
`gradient` | | Map with gradient state.<br>Hue white and color ambiance gradient lights;
`gradient/points` | | A list with up to nine gradient "points", `xy` values defining a colour.
`gradient/segments` | # points | The number of gradient "segments".<br>If this is larger than the number of points, the colours are repeated. If it's smaller, any superfluous colours are ignored.
`gradient/color_adjustment` | `0` | Adjustment to the segment colours, from 0 to 7.
`gradient/offset` | `0` | The offset into points for the colour of the first segment.
`gradient/offset_adjustment` | `0` | Adjustment to the offset, from 0 to 7.
`gradient/style` | `linear` | The style for the gradient.<br>Note that I'm using the friendly names from the Hue app, rather than the technical names from the Hue API v2.
Finally, this PR creates the following top-level attributes:
Attribute | Default | Description
-- | -- | --
`productid` | | The `productid` as exposed by the Hue bridge.
`productname` | | The `productname` as exposed by the Hue bridge.<br>*Not yet exposed (see below).*
`swconfigid` | | The `swconfigid` as expeosed by the Hue bridge.<br>Not sure what it's used for.
Still to do:
- Better way to match lights on manufacturer, profile, device type, and firmware image type, instead of by model identifier.
- Query the light capabilities through the manifacturer-specific 0xc0/0xc1 commands on the _Basic_ cluster, o.a. others to retrieve `productname`.
Note: This is my first attempt at a PR using a different Git branch.