diff --git a/.copier-answers.yml b/.copier-answers.yml index c83d763..d588135 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -3,7 +3,7 @@ _commit: v0.9.16 _src_path: git@github.com:finitelabs/control4-driver-template.git distributions: drivercentral oss github_org: finitelabs -primary_color: '#5D3FD3' +primary_color: '#C8102E' project_description: Integrate generic Zigbee 3.0 devices into Control4 (device definitions generated from zigbee2mqtt) project_name: control4-zigbee3 diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..aad7f32 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,48 @@ +version: 2 + +# tools/generator is the only npm manifest in this repo. It builds the device +# database from the zigbee2mqtt definitions and never ships inside a .c4z, so +# these are build-time dependencies only. The root package.json was retired in +# the v0.9.11 template update (docs now render with Python and WeasyPrint), so +# there is nothing left to watch at "/". +# +# Bumping zigbee-herdsman-converters does not update the shipped device tables +# on its own. After merging one of these PRs run `make generate && make build` +# and commit the regenerated drivers/zigbee3_device/generated/* and +# SUPPORTED_DEVICES.md, otherwise the pinned converter version and the +# generated data drift apart. +# +# Both halves are required. `make generate` writes unformatted output, while the +# committed files are post-`make fmt`: stylua wraps devices.lua and mdformat pads +# the SUPPORTED_DEVICES.md tables. Committing raw generator output makes CI fail +# its dirty-tree check, because `make build` runs fmt and rewrites everything. +# It also makes the diff unreadable: raw output reads as roughly 10k insertions +# against 78k deletions, where the real change after formatting is a few +# thousand lines. +# +# CI cannot catch this drift. build.yml runs `make init` and `make build`, never +# `make generate`, so its dirty-tree check only proves the committed files are +# already formatted, not that they match the pinned converters version. A green +# build says nothing about whether this step was run. The local run is the +# verification. +# +# Read the formatted diff before merging, and check more than the channel list. +# A converters release can: +# * re-key a model. DEVICES lookup in src/zigbee3/device.lua is an exact, +# case-sensitive index and Device:restoreModel() re-resolves the persisted +# string on every reload, so a re-key silently drops an already-installed +# device to generic handling on the next driver update. +# * drop a model outright, same effect. +# * drop channels, settings or Tuya datapoint maps from a retained model. +# * drop button wire keys from a retained model, which silently kills any +# Composer programming bound to those actions. +# * narrow a binding key in binding_keys.xml from a ManufacturerName wildcard +# to specific strings, which changes whether Director claims the device at +# all on a fresh pair. +updates: + - package-ecosystem: npm + directory: /tools/generator + schedule: + interval: monthly + commit-message: + prefix: chore diff --git a/.gitignore b/.gitignore index c4bbcc4..32ff4e9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,12 @@ /.venv /.lua **/http-client.private.env.json + +# Python bytecode (tools/ scripts and their tests import each other as modules) +__pycache__/ +*.pyc + +# Local screenshot-generation scripts. They drive the maintainer's review-driver +# skill (shoot_ui.py), which lives outside this repo, so they are kept on disk but +# not tracked here. +/shots/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 20d14ed..10f4ddd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# Changelog +# Changelog ## Unreleased + +Initial release. One generic driver that speaks ZCL directly to any joined +Zigbee 3.0 device: adding a device is a data refresh from the zigbee2mqtt +database rather than new code, so thousands of devices are supported. The driver +resolves the joined model and builds its proxies, readings, and settings +automatically. + +### Added + +- Sensors: motion, contact, and similar security sensors enroll automatically, + and every reading is published as a Control4 variable for programming. A + device that reports the same reading on more than one endpoint (a multi-probe + sensor, a multi-zone presence sensor) surfaces each one as its own reading, + variable, and reporting control rather than collapsing them into one. +- Energy monitoring: metering plugs and switches publish power, voltage, + current, energy, and power factor, each scaled by the device's own multiplier + and divisor attributes. +- Real-time bindings: reporting and button clusters are bound to the coordinator + so the device pushes changes at once instead of waiting for a poll. Binds + persist across reloads, confirm on a sleepy device's next wake, and are + reconciled against the device's own table. A Bindings tab shows their state, + and a Re-establish Bindings action re-runs them. +- Tunable update rate: a cog on each Device-tab reading sets how often it + reports (minimum and maximum interval, and the change threshold). +- Settings: per-device configuration from a Settings tab, covering standard ZCL + and manufacturer-specific settings (including vendor custom clusters), + delivered reliably to sleepy devices and enforced across reloads. +- Alerts and actions: battery, trouble, and offline/online alerts, plus Identify + and other device actions from the Actions tab. +- Buttons and remotes: wireless remotes and scene controllers fire Control4 + programming events, one per button action (e.g. "1 Single", "2 Hold"), decoded + from standard ZCL Scenes, On/Off, and Level commands. +- Companion drivers: a **Zigbee 3 Lock** and a **Zigbee 3 Light** bind to a + joined Zigbee 3 Device to present a deadbolt or lever, or a bulb or fixture, + as a standard Control4 lock or light. Lock, unlock, dimming, color + temperature, and color are enabled from what the device reports. +- Switches and relays: any switch is presented as a Control4 relay, one per gang + over ZCL On/Off, with multi-gang endpoints (l1/l2, left/right) resolved from + the zigbee2mqtt database. diff --git a/Makefile b/Makefile index c03d3cd..a1be3a3 100644 --- a/Makefile +++ b/Makefile @@ -233,6 +233,22 @@ zip: $(VENV_STAMP) ## Zip the c4z/, docs/, and source/ subfolders per distributi "$$repo.zip" c4z docs source); \ done +# ─── Generate ───────────────────────────────────────────────────────────────── +# Project-specific: regenerate driver device data from the zigbee2mqtt database. +# Runs before `preprocess`; the generated fragments are #embed-ed into the +# hand-authored driver sources. Kept out of `build` so drivers/ stays reviewable +# source, regenerated deliberately when refreshing device support. + +GEN := tools/generator + +$(GEN)/node_modules: $(GEN)/package.json + cd $(GEN) && npm install + @touch $@ + +.PHONY: generate +generate: $(GEN)/node_modules ## Regenerate drivers/ device data from the zigbee2mqtt database + cd $(GEN) && node extract-z2m.mjs && node map-c4.mjs && node gen-drivers.mjs && node gen-devices.mjs && node gen-compat.mjs + # ─── Test ───────────────────────────────────────────────────────────────────── .PHONY: test @@ -240,7 +256,7 @@ zip: $(VENV_STAMP) ## Zip the c4z/, docs/, and source/ subfolders per distributi # test/run_test.sh sets up. Existing suites are written against that shim and # fail on a bare `luajit ` with "attempt to index global 'C4'". A test that # defines its own C4 still wins, since it assigns after the preload has run. -test: ## Run the Lua test suite (test/test_*.lua) +test: $(VENV_STAMP) ## Run the Lua test suite (test/test_*.lua) + the Python tool tests @found=0; \ for f in test/test_*.lua; do \ [ -e "$$f" ] || continue; \ @@ -250,6 +266,11 @@ test: ## Run the Lua test suite (test/test_*.lua) luajit -e "require('c4_shim')" "$$f" || exit 1; \ done; \ if [ "$$found" = "0" ]; then echo "No test/test_*.lua files found; nothing to run."; fi + @for f in tools/test_*.py; do \ + [ -e "$$f" ] || continue; \ + echo "==> $$f"; \ + $(VENV_PY) "$$f" || exit 1; \ + done # ─── Build ──────────────────────────────────────────────────────────────────── diff --git a/README.md b/README.md new file mode 100644 index 0000000..8e69d6c --- /dev/null +++ b/README.md @@ -0,0 +1,398 @@ + + +
+⚠ Experimental driver, under active development. Behavior and settings may change between releases, and some devices may not yet work reliably. Use at your own risk and report any issues. +
+ +Zigbee 3 Device + +______________________________________________________________________ + +# Overview + +> DISCLAIMER: This software is neither affiliated with nor endorsed by Control4 +> or the Zigbee Alliance. + +The Zigbee 3 Device driver brings generic **Zigbee 3.0** devices into Control4, +with device support generated from the +[zigbee2mqtt](https://www.zigbee2mqtt.io/) database. Join a device to the +controller's Zigbee 3.0 mesh and the driver resolves its model, wires the right +Control4 proxies and variables, exposes its readings, and lets you configure it +from the **Settings** tab - no per-device driver to hand-write. + +# Index + +
+ +- [System Requirements](#system-requirements) + +- [Features](#features) + +- [Installer Setup](#installer-setup) + + - [Driver Installation](#driver-installation) + - [Joining a Device](#joining-a-device) + - [Driver Setup](#driver-setup) + - [Driver Tabs](#driver-tabs) + - [Settings](#settings) + - [Driver Properties](#driver-properties) + - [Cloud Settings](#cloud-settings) + - [Driver Settings](#driver-settings) + - [Driver Actions](#driver-actions) + - [Connections](#connections) + +- [Programming](#programming) + + - [Events](#events) + - [Variables](#variables) + - [Commands](#commands) + +- [Support](#support) + +- [Changelog](#changelog) + +
+ +# System Requirements + +- Control4 OS 4.2.0 or later +- A controller running the **Zigbee 3.0** stack with an open network +- A Zigbee 3.0 device listed in the + [supported devices](https://github.com/finitelabs/control4-zigbee3/blob/main/SUPPORTED_DEVICES.md) + matrix + +# Features + +- Support for thousands of Zigbee 3.0 devices, generated from the zigbee2mqtt + database and refreshed as that project adds more +- One generic driver per joined device: it speaks ZCL directly and needs no + device-specific driver +- Automatically resolves the joined device's model and builds its proxies, + readings, and settings +- Switches and relays presented as Control4 relay connections, one per gang, so + single and multi-gang wired switches and plugs can be controlled and used in + programming +- Bulbs and fixtures controlled as standard Control4 lights through the + companion **Zigbee 3 Light** driver, with dimming, color temperature, and + color enabled automatically from what the device reports +- Deadbolts and levers controlled as standard Control4 locks through the + companion **Zigbee 3 Lock** driver, with lock, unlock, and status feedback +- Wireless remotes and scene controllers fire programming events for each button + action (single, double, hold, and more), so button presses can drive any + Control4 programming +- Per-device configuration from the **Settings** tab, enforced across driver + reloads and delivered reliably to battery-powered (sleepy) devices +- Live readings published as Control4 variables for programming +- IAS security-sensor enrollment handled automatically +- Battery, trouble, and offline/online alerts for programming +- **Identify** and other device actions from the Actions tab + +# Installer Setup + +## Driver Installation + +Driver installation and setup are similar to most other drivers. Below is an +outline of the basic steps for your convenience. + +1. Download the latest `control4-zigbee3.zip` from + [GitHub](https://github.com/finitelabs/control4-zigbee3/releases/latest). +1. Extract and + [install](https://www.control4.com/help/c4/software/cpro/dealer-composer-help/content/composerpro_userguide/adding_drivers_manually.htm) + all `.c4z` files. +1. Use the "Search" tab to find the "Zigbee 3 Device" driver and add one to your + project for each physical device you intend to join. +
Search Drivers +1. Continue to [Joining a Device](#joining-a-device). + +## Joining a Device + +Add one **Zigbee 3 Device** to the project per physical device, then join each +device to the controller's Zigbee 3.0 network: + +1. Confirm the controller is running the **Zigbee 3.0** stack. +1. Open the **Connections** view and select the **Network** tab. +1. Select **Zigbee Network**, then + [double-click](https://docs.control4.com/help/c4/software/cpro/dealer-composer-help/content/composerpro_userguide/connecting_zigbee_devices.htm) + this driver in the **Zigbee Network Connections** list (or highlight it and + click **Identify**). This opens the identify window and starts a 60 second + pairing timer. +1. Within that window, put the device into pairing mode (usually a factory reset + or a press of the device's Zigbee button, see the device's manual). On + success its address fills in and it shows online in the **Zigbee Mesh Routing + Tree**. +1. The device's model resolves once it reports in, and its readings, settings, + and actions populate in the **Settings** tab automatically. + +> Battery-powered devices sleep to save power. If a setting shows as _Applying_, +> the change is queued and delivered the next time the device wakes. Press the +> device's pairing button to wake it; some devices need several presses over the +> sync window before every queued setting and binding lands. + +## Driver Setup + +### Driver Tabs + +While in +[System Design mode](https://www.control4.com/help/c4/software/cpro/dealer-composer-help/content/composerpro_userguide/system_design_view.htm), +the driver adds a **Settings** tab next to the "Properties", "Actions", and +"Lua" tabs. + +#### Settings + +The **Settings** tab is where you view and configure the joined device. It has +four views, switched with the tabs across the top. + +##### Device view + +Settings tab - Device view + +1. The resolved device name and model (with its ModelIdentifier). +1. Connection status - **Online**, **Offline**, or the current activity. +1. Last-seen time and, for IAS sensors, the enrollment state. +1. The device's live readings, also published as variables for programming. A + reading with a settings cog can have its reporting rate tuned: how often it + reports at most, how often at least, and how much it must change to report. + Faster updates cost more battery on sleepy sensors. + +##### Bindings view + +The **Bindings** view confirms the device is wired up to deliver events in real +time, and - for remotes - lets you watch button presses arrive live. + +Settings tab - Bindings view + +1. Overall bind status: **Bound** (every cluster confirmed), **Partial** (some + confirmed), **Sent** (binds queued, waiting for the device to next wake), + **Checking** (an attempt is in flight), **Awaiting device** (settled but not + yet confirmed, self-heals on the next wake), or **On poll** (a poll-only or + IAS-enrolled device with nothing to bind). +1. The Zigbee coordinator this device bound to and the gateway endpoint used. +1. Each endpoint the device binds, with a named chip per bound cluster (On/Off, + Dimming, Scenes, or a manufacturer cluster carrying several readings at once, + for example _Illuminance, Device Temperature, Battery_), colored by its own + state: green **Bound** once a report or press confirms it, blue **Sent** + while a queued bind waits for the device, or amber **Checking** / **Awaiting + device** until it is confirmed. +1. For a remote, the last button press the driver saw, with its time. +1. Per-button press counts since the driver last started - press a button on the + remote and watch it register here. + +Real-time bindings make a device push unsolicited reports and button presses +over the mesh instead of only answering the periodic poll. The driver +(re)establishes them whenever the device is awake and self-heals: a bind is +**Sent** as soon as the coordinator accepts it, then confirmed to **Bound** the +moment real traffic - a report or a button press - arrives on that cluster. +Battery devices apply a queued bind on their next wake, so a fresh remote can +read **Sent** until its first press. IAS sensors (many door, window, and motion +sensors) enroll with the coordinator instead of binding, and show here as +reporting on the standard poll. + +##### Settings view + +Settings tab - Settings view + +1. How many settings this device exposes. +1. An enum setting, edited with a dropdown. +1. A numeric setting, edited with a number field alongside its allowed range. +1. A setting being applied - re-sent until the (possibly sleepy) device confirms + it. +1. A read-only setting: the device reports it but no writable path could be + derived. + +Changes are enforced across driver reloads and re-sent until the device confirms +them; **Discard changes** stops enforcing your edits and reverts to the device's +own values. + +##### Driver view + +Settings tab - Driver view + +1. Driver status and version (read-only). +1. Log level. +1. Log mode. +1. Automatic updates (and, in the OSS build, the update channel). + +This view mirrors the native [Cloud](#cloud-settings) and +[Driver](#driver-settings) properties; editing either side syncs. + +### Driver Properties + +#### Cloud Settings + +##### Automatic Updates \[ Off | **_On_** \] + +Enables or disables automatic driver updates from GitHub releases. + +##### Update Channel \[ **_Production_** | Prerelease \] + +Sets the update channel for which releases are considered during automatic +updates from GitHub releases. + +#### Driver Settings + +##### Driver Status (read-only) + +Displays the current state of the device - for example _Waiting for device_, +_Online_, _Offline_, or a pending configuration change. + +##### Driver Version (read-only) + +Displays the current version of the driver. + +##### Log Level \[ 0 - Fatal | 1 - Error | 2 - Warning | **_3 - Info_** | 4 - Debug | 5 - Trace | 6 - Ultra \] + +Sets the logging level. Default is `3 - Info`. + +##### Log Mode \[ **_Off_** | Print | Log | Print and Log \] + +Sets the logging mode. Default is `Off`. + +### Driver Actions + +#### Identify + +Blinks the device so you can locate it during setup. Works on any Zigbee 3.0 +device. Other device-specific actions (for example a smoke detector self-test) +are run from the **Execute Action** programming command. + +#### Re-establish Bindings + +Forgets and re-establishes the device's real-time bindings (see the **Bindings** +view). The driver keeps bindings across reloads and only re-checks them against +the device, so you rarely need this - use it if the Bindings view looks wrong, +or after a device is reset outside Composer. + +#### Update Drivers + +Trigger the driver to update from the latest release on GitHub, regardless of +the current version. + +## Connections + +### ZIGBEE (consumer) + +Bind this to the controller's Zigbee Server so the driver can reach the physical +device. This is the only static connection; the driver adds the rest dynamically +once a device resolves. + +### Dynamic providers + +The driver has no fixed proxy - when a device resolves it publishes only the +provider connections that device needs, which the companion drivers and Control4 +programming bind to: + +- **Light** (`ZIGBEE_LIGHT`) - one per light endpoint; bind a + [Zigbee 3 Light](https://github.com/finitelabs/control4-zigbee3) companion. +- **Lock** (`ZIGBEE_LOCK`) - one per lock endpoint; bind a + [Zigbee 3 Lock](https://github.com/finitelabs/control4-zigbee3) companion. +- **Relay** (`RELAY`) - one control connection per switch gang. +- **Contact Sensor** (`CONTACT_SENSOR`) - one per binary sensor (motion, + contact, leak, smoke, and so on). +- **Value** (`TEMPERATURE_VALUE`, `HUMIDITY_VALUE`, and similar) - one per + measurement that maps to a Control4 value connection. Readings without one + (air quality, device temperature) are published only as variables. + +# Programming + +## Events + +| Event | Description | +| --------------- | -------------------------------------------------------------------- | +| Battery Low | Fires when the device reports a low battery | +| Trouble | Fires when the device reports a fault or tamper condition | +| Offline Warning | Fires when the device has failed to report and is considered offline | +| Back Online | Fires when the device reports again after having gone offline | + +For wireless remotes and scene controllers, the driver also adds one event per +button action (for example _1 Single_, _2 Hold_) once the device resolves, so +each press can trigger Control4 programming. + +## Variables + +The driver publishes each of the device's readings (motion, contact, +temperature, humidity, illuminance, pressure, air quality such as CO2, PM2.5, +and PM10, electrical readings such as power, voltage, current, and energy on +metering plugs, battery, and others, depending on the device) as Control4 +variables so they can be used in programming. + +## Commands + +| Command | Parameters | Description | +| ----------------- | ---------- | ----------------------------------------------------- | +| Set Configuration | Setting | Writes a device-supported setting to a value | +| Execute Action | Action | Runs a per-device action such as Identify or Selftest | + +> **Note:** Both parameters are dynamic lists that populate once the device +> resolves. `Setting` offers each `Setting: Value` combination the device +> supports; `Action` offers the same per-device actions as the **Settings** tab, +> so a routine such as a monthly smoke-detector self-test can be scheduled. + +# Support + +If you have any questions, supported-device requests, or issues to report, you +can file an issue on GitHub: + +https://github.com/finitelabs/control4-zigbee3/issues/new + +Buy Me A Coffee + +# Changelog + + + +## Unreleased + +Initial release. One generic driver that speaks ZCL directly to any joined +Zigbee 3.0 device: adding a device is a data refresh from the zigbee2mqtt +database rather than new code, so thousands of devices are supported. The driver +resolves the joined model and builds its proxies, readings, and settings +automatically. + +### Added + +- Sensors: motion, contact, and similar security sensors enroll automatically, + and every reading is published as a Control4 variable for programming. A + device that reports the same reading on more than one endpoint (a multi-probe + sensor, a multi-zone presence sensor) surfaces each one as its own reading, + variable, and reporting control rather than collapsing them into one. +- Energy monitoring: metering plugs and switches publish power, voltage, + current, energy, and power factor, each scaled by the device's own multiplier + and divisor attributes. +- Real-time bindings: reporting and button clusters are bound to the coordinator + so the device pushes changes at once instead of waiting for a poll. Binds + persist across reloads, confirm on a sleepy device's next wake, and are + reconciled against the device's own table. A Bindings tab shows their state, + and a Re-establish Bindings action re-runs them. +- Tunable update rate: a cog on each Device-tab reading sets how often it + reports (minimum and maximum interval, and the change threshold). +- Settings: per-device configuration from a Settings tab, covering standard ZCL + and manufacturer-specific settings (including vendor custom clusters), + delivered reliably to sleepy devices and enforced across reloads. +- Alerts and actions: battery, trouble, and offline/online alerts, plus Identify + and other device actions from the Actions tab. +- Buttons and remotes: wireless remotes and scene controllers fire Control4 + programming events, one per button action (e.g. "1 Single", "2 Hold"), decoded + from standard ZCL Scenes, On/Off, and Level commands. +- Companion drivers: a **Zigbee 3 Lock** and a **Zigbee 3 Light** bind to a + joined Zigbee 3 Device to present a deadbolt or lever, or a bulb or fixture, + as a standard Control4 lock or light. Lock, unlock, dimming, color + temperature, and color are enabled from what the device reports. +- Switches and relays: any switch is presented as a Control4 relay, one per gang + over ZCL On/Off, with multi-gang endpoints (l1/l2, left/right) resolved from + the zigbee2mqtt database. diff --git a/SUPPORTED_DEVICES.md b/SUPPORTED_DEVICES.md new file mode 100644 index 0000000..49068df --- /dev/null +++ b/SUPPORTED_DEVICES.md @@ -0,0 +1,3866 @@ + + +# Supported devices + +This driver brings generic **Zigbee 3.0** sensors into Control4. The device +knowledge below is **derived from the [zigbee2mqtt](https://www.zigbee2mqtt.io/) +project's open device database** - an enormous community effort we build on and +credit gladly. What follows is our own honest accounting of the devices this +driver can actually decode today, not a copy of theirs: a model appears here +only when the runtime has a working decode path for its primary sensor, the same +gate that decides which devices the driver claims on the mesh. + +A device that merely *joins* is not enough - the driver must be able to turn its +reports into Control4 state. Devices whose primary sensor streams over Tuya's +manufacturer cluster are supported only where we could map the triggering +datapoint (see [Not yet supported](#not-yet-supported)). + +_Generated 2026-08-30 from the zigbee2mqtt database. Regenerate with_ +`make generate`. + +## At a glance + +- **3820** device models supported, across **385** vendors +- Decode paths: Standard ZCL 3442 · Tuya 232 · Aqara/LUMI 146 + +> **Decode path** is how the runtime reads the device: **Standard ZCL** uses the +> normal Zigbee clusters (IAS Zone, Occupancy, measurement); **Aqara/LUMI** +> decodes Xiaomi's `0xFCC0` manufacturer cluster; **Tuya** decodes the `0xEF00` +> datapoint stream. + +## Supported models + +| Vendor | Model | Sensors | Decode path | +| ----------------------------------- | ------------------------------------------------ | -------------------------------------------------------------------- | ------------ | +| ADEO | 83633205 | Motion, Battery, Illuminance, Temperature, Humidity | Standard ZCL | +| ADEO | 84845506 | | Standard ZCL | +| ADEO | 84845509 | | Standard ZCL | +| ADEO | 84870054 | | Standard ZCL | +| ADEO | 84870058 | | Standard ZCL | +| ADEO | 9CZA-A806ST-Q1A | | Standard ZCL | +| ADEO | 9CZA-A806ST-Q1Z | | Standard ZCL | +| ADEO | 9CZA-G1521-Q1A | | Standard ZCL | +| ADEO | 9CZA-M350ST-Q1A | | Standard ZCL | +| ADEO | 9CZA-P470T-A1A | | Standard ZCL | +| ADEO | BD05C-FL-21-G-ENK | | Standard ZCL | +| ADEO | HR-C99C-Z-C045 | Battery | Standard ZCL | +| ADEO | IA-CDZFB2AA007NA-MZN-01 | | Standard ZCL | +| ADEO | IA-CDZFB2AA007NA-MZN-02 | | Standard ZCL | +| ADEO | IA-CDZOTAAA007MA-MAN | | Standard ZCL | +| ADEO | IC-CDZFB2AC004HA-MZN | | Standard ZCL | +| ADEO | IC-CDZFB2AC005HA-MZN | | Standard ZCL | +| ADEO | IG-CDZB2AG009RA-MZN-01 | | Standard ZCL | +| ADEO | IG-CDZFB2AG010RA-MNZ | | Standard ZCL | +| ADEO | IG-CDZFB2G009RA-MZN-02 | | Standard ZCL | +| ADEO | IG-CDZOTAAG014RA-MAN | | Standard ZCL | +| ADEO | IM-CDZDGAAA0005KA_MAN | | Standard ZCL | +| ADEO | IM-CDZDGAAG005KA-MZN | | Standard ZCL | +| ADEO | IP-CDZOTAAP005JA-MAN | | Standard ZCL | +| ADEO | IST-CDZFB2AS007NA-MZN-01 | | Standard ZCL | +| ADEO | IST-CDZFB2AS007NA-MZN-02 | | Standard ZCL | +| ADEO | LDSENK01F | | Standard ZCL | +| ADEO | LDSENK01S | | Standard ZCL | +| ADEO | LDSENK02F | | Standard ZCL | +| ADEO | LDSENK02S | | Standard ZCL | +| ADEO | LDSENK08 | Contact, Vibration, Battery | Standard ZCL | +| ADEO | LDSENK10 | Motion | Standard ZCL | +| ADEO | PEZ1-042-1020-C1D1 | | Standard ZCL | +| ADEO | SIN-4-1-20_EQU | | Standard ZCL | +| ADEO | SIN-4-1-20_LEX | | Standard ZCL | +| ADEO | SIN-4-1-21_EQU | | Standard ZCL | +| ADEO | SIN-4-1-22_LEX | | Standard ZCL | +| ADEO | SIN-4-FP-21_EQU | | Standard ZCL | +| ADEO | ZB-DoorSensor-D0007 | Contact, Battery | Standard ZCL | +| ADEO | ZBEK-30 | | Standard ZCL | +| ADEO | ZBEK-32 | | Standard ZCL | +| ADEO | ZBEK-33 | | Standard ZCL | +| ADEO | ZBEK-37 | | Standard ZCL | +| AOYAN | AY-204Z | Motion, Battery | Standard ZCL | +| AOYAN | AY-601ZL | | Standard ZCL | +| AVATTO | LZWSM16-1 | | Standard ZCL | +| AVATTO | TRV60_thermostat | Battery, Humidity | Tuya | +| AVATTO | TS0601_thermostat_14 | Battery | Tuya | +| AVATTO | ZBS16 | | Tuya | +| AVATTO | ZDMS16-1 | | Standard ZCL | +| AVATTO | ZDMS16-2 | | Standard ZCL | +| AVATTO | ZDMS16-US-W2 | | Standard ZCL | +| AVATTO | ZWPM16 | | Tuya | +| AVATTO | ZWSH16 | Battery, Temperature, Humidity | Tuya | +| Acova | TAFFETAS2/PERCALE2 | Motion | Standard ZCL | +| Acuity Brands Lighting (ABL) | RB56AC | | Standard ZCL | +| Acuity Brands Lighting (ABL) | RB56SC | | Standard ZCL | +| Acuity Brands Lighting (ABL) | WF4C_WF6C | | Standard ZCL | +| AduroSmart | 15090054 | Battery | Standard ZCL | +| AduroSmart | 81809/81813 | | Standard ZCL | +| AduroSmart | 81809FBA | | Standard ZCL | +| AduroSmart | 81810 | | Standard ZCL | +| AduroSmart | 81812/81814 | | Standard ZCL | +| AduroSmart | 81813-V2 | | Standard ZCL | +| AduroSmart | 81825 | | Standard ZCL | +| AduroSmart | 81848 | | Standard ZCL | +| AduroSmart | 81849 | | Standard ZCL | +| AduroSmart | 81855 | | Standard ZCL | +| AduroSmart | 81863 | | Standard ZCL | +| AduroSmart | 81895 | | Standard ZCL | +| AduroSmart | 81898 | | Standard ZCL | +| AduroSmart | 81949 | | Standard ZCL | +| AduroSmart | 81998 | | Standard ZCL | +| AduroSmart | AD-CTW123001 | | Standard ZCL | +| AduroSmart | AD-RGBWH3001 | | Standard ZCL | +| AduroSmart | BPU3 | | Standard ZCL | +| AduroSmart | E1XCTW3001 | | Standard ZCL | +| Aeotec | ZGA002 | Device Temp | Standard ZCL | +| Aeotec | ZGA003 | Device Temp | Standard ZCL | +| Aeotec | ZGA004 | Device Temp | Standard ZCL | +| Airam | 4713406 | | Standard ZCL | +| Airam | 4713407 | | Standard ZCL | +| Airam | AIRAM-CTR.U | | Standard ZCL | +| Airam | CTR.UBX | | Standard ZCL | +| Airzone | AZAI6ZBEMHI | | Standard ZCL | +| Ajax Online | AJ_RGBCCT_CTRL | | Standard ZCL | +| Ajax Online | AJ_ZB_GU10 | | Standard ZCL | +| Ajax Online | AJ_ZIGPROA60 | | Standard ZCL | +| Ajax Online | Aj_Zigbee_Led_Strip | | Standard ZCL | +| Ajax Online | ZB-CCT_Filament | | Standard ZCL | +| Ajax Online | ZB_A60_RGBCW | | Standard ZCL | +| Akuvox | M423-9E | Battery, Temperature, Humidity | Standard ZCL | +| Alab | alab.switch | | Standard ZCL | +| Alchemy | AL8RGB13W-AP | | Standard ZCL | +| Alchemy | AL8TC13W-AP | | Standard ZCL | +| Aldi | 141L100RC | | Standard ZCL | +| Alecto | SMART-HEAT10 | Battery | Standard ZCL | +| Amina Distribution AS | amina S | | Standard ZCL | +| Anchor | 67200BL | | Standard ZCL | +| Aqara | CL-L02D | Device Temp | Aqara/LUMI | +| Aqara | DJT11LM | Vibration, Battery, Device Temp | Aqara/LUMI | +| Aqara | DLKZMK11LM | Device Temp | Aqara/LUMI | +| Aqara | DLKZMK12LM | | Aqara/LUMI | +| Aqara | DS-K02D/DS-K02E | | Aqara/LUMI | +| Aqara | DWZTCGQ11LM | Contact, Battery | Aqara/LUMI | +| Aqara | FP1E | Motion, Device Temp | Aqara/LUMI | +| Aqara | FP310 | Motion, Battery, Illuminance, Humidity, Temperature | Aqara/LUMI | +| Aqara | GZCGQ11LM | Battery, Illuminance | Aqara/LUMI | +| Aqara | H1-EU | | Aqara/LUMI | +| Aqara | HLQDQ01LM | | Aqara/LUMI | +| Aqara | JT-BZ-01AQ/A | Gas | Aqara/LUMI | +| Aqara | JWDL001A | Device Temp | Aqara/LUMI | +| Aqara | JWSP001A | Device Temp | Aqara/LUMI | +| Aqara | JY-GZ-01AQ | Smoke, Battery | Aqara/LUMI | +| Aqara | KD-R01D | Device Temp | Aqara/LUMI | +| Aqara | KQJCMB11LM | Temperature, Humidity | Aqara/LUMI | +| Aqara | LGYCDD01LM | Device Temp | Aqara/LUMI | +| Aqara | LLKZMK11LM | Device Temp | Aqara/LUMI | +| Aqara | LLKZMK12LM | Device Temp | Aqara/LUMI | +| Aqara | MCCGQ11LM | Contact, Battery, Device Temp | Aqara/LUMI | +| Aqara | MCCGQ12LM | Contact, Battery | Aqara/LUMI | +| Aqara | MCCGQ13LM | Contact, Battery | Aqara/LUMI | +| Aqara | MCCGQ14LM | Contact, Battery | Aqara/LUMI | +| Aqara | MFKZQ01LM | Battery, Device Temp | Aqara/LUMI | +| Aqara | PS-S04D | Motion, Battery, Illuminance, Humidity, Temperature | Aqara/LUMI | +| Aqara | QBCZ11LM | Device Temp | Aqara/LUMI | +| Aqara | QBCZ14LM | Device Temp | Aqara/LUMI | +| Aqara | QBCZ15LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG03LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG04LM | | Aqara/LUMI | +| Aqara | QBKG11LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG12LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG17LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG18LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG19LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG20LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG21LM | | Aqara/LUMI | +| Aqara | QBKG22LM | | Aqara/LUMI | +| Aqara | QBKG23LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG24LM | | Aqara/LUMI | +| Aqara | QBKG25LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG26LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG27LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG28LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG29LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG30LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG31LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG32LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG33LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG34LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG38LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG39LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG40LM | Device Temp | Aqara/LUMI | +| Aqara | QBKG41LM | Device Temp | Aqara/LUMI | +| Aqara | RTCGQ11LM | Motion, Battery, Device Temp, Illuminance | Aqara/LUMI | +| Aqara | RTCGQ12LM | Motion, Illuminance, Device Temp, Battery | Aqara/LUMI | +| Aqara | RTCGQ13LM | Motion, Device Temp, Battery | Aqara/LUMI | +| Aqara | RTCGQ14LM | Motion, Illuminance, Device Temp, Battery | Aqara/LUMI | +| Aqara | RTCGQ15LM | Motion, Illuminance, Device Temp, Battery | Aqara/LUMI | +| Aqara | RTCZCGQ11LM | Motion, Device Temp | Aqara/LUMI | +| Aqara | SJCGQ11LM | Water, Battery, Device Temp | Aqara/LUMI | +| Aqara | SJCGQ12LM | Water, Battery | Aqara/LUMI | +| Aqara | SJCGQ13LM | Water, Battery, Device Temp | Aqara/LUMI | +| Aqara | SP-EUC01 | Device Temp | Aqara/LUMI | +| Aqara | SRTS-A01 | Battery, Device Temp | Aqara/LUMI | +| Aqara | SSM-U01 | Device Temp | Aqara/LUMI | +| Aqara | SSM-U02 | Device Temp | Aqara/LUMI | +| Aqara | SSWQD02LM | Device Temp | Aqara/LUMI | +| Aqara | SSWQD03LM | Device Temp | Aqara/LUMI | +| Aqara | SSWQD22LM | Device Temp | Aqara/LUMI | +| Aqara | SSWQDYH02 | Device Temp | Aqara/LUMI | +| Aqara | T2_E27 | Device Temp | Aqara/LUMI | +| Aqara | T2_E27_CCT | Device Temp | Aqara/LUMI | +| Aqara | TDL01LM | Device Temp | Aqara/LUMI | +| Aqara | TH-S04D | Battery, Temperature, Humidity | Aqara/LUMI | +| Aqara | UT-A01E | Humidity | Aqara/LUMI | +| Aqara | VC-X01D | Battery | Aqara/LUMI | +| Aqara | VOCKQJK11LM | Device Temp, Battery, Temperature, Humidity | Aqara/LUMI | +| Aqara | WP-P01D | Device Temp | Aqara/LUMI | +| Aqara | WS-EUK01 | Device Temp | Aqara/LUMI | +| Aqara | WS-EUK02 | Device Temp | Aqara/LUMI | +| Aqara | WS-EUK03 | Device Temp | Aqara/LUMI | +| Aqara | WS-EUK04 | Device Temp | Aqara/LUMI | +| Aqara | WS-K01D | Device Temp | Aqara/LUMI | +| Aqara | WS-K02E | Device Temp | Aqara/LUMI | +| Aqara | WS-K03E | Device Temp | Aqara/LUMI | +| Aqara | WS-K04E | Device Temp | Aqara/LUMI | +| Aqara | WS-K05E | Device Temp | Aqara/LUMI | +| Aqara | WS-K07E | Device Temp | Aqara/LUMI | +| Aqara | WS-K08E | Device Temp | Aqara/LUMI | +| Aqara | WS-USC01 | Device Temp | Aqara/LUMI | +| Aqara | WS-USC02 | Device Temp | Aqara/LUMI | +| Aqara | WS-USC03 | Device Temp | Aqara/LUMI | +| Aqara | WS-USC04 | Device Temp | Aqara/LUMI | +| Aqara | WSDCGQ11LM | Battery, Temperature, Humidity, Pressure | Aqara/LUMI | +| Aqara | WSDCGQ12LM | Temperature, Humidity, Pressure, Device Temp, Battery | Aqara/LUMI | +| Aqara | WXCJKG11LM | Battery | Aqara/LUMI | +| Aqara | WXCJKG12LM | Battery | Aqara/LUMI | +| Aqara | WXKG11LM | Battery, Device Temp | Aqara/LUMI | +| Aqara | WXKG15LM | Battery | Aqara/LUMI | +| Aqara | WXKG20LM | Battery, Device Temp | Aqara/LUMI | +| Aqara | XDD11LM | Device Temp | Aqara/LUMI | +| Aqara | XDD12LM | Device Temp | Aqara/LUMI | +| Aqara | XDD13LM | Device Temp | Aqara/LUMI | +| Aqara | ZNCJMB14LM | | Aqara/LUMI | +| Aqara | ZNCLBL01LM | Battery, Device Temp, Illuminance | Aqara/LUMI | +| Aqara | ZNCZ11LM | Device Temp | Aqara/LUMI | +| Aqara | ZNCZ12LM | Device Temp | Aqara/LUMI | +| Aqara | ZNCZ15LM | Device Temp | Aqara/LUMI | +| Aqara | ZNDDMK11LM | Device Temp | Aqara/LUMI | +| Aqara | ZNDDQDQ11LM | Device Temp | Aqara/LUMI | +| Aqara | ZNDDQDQ12LM | Device Temp | Aqara/LUMI | +| Aqara | ZNDDQDQ13LM | Device Temp | Aqara/LUMI | +| Aqara | ZNJLBL01LM | Battery, Device Temp | Aqara/LUMI | +| Aqara | ZNLDP12LM | Device Temp | Aqara/LUMI | +| Aqara | ZNLDP13LM | Device Temp | Aqara/LUMI | +| Aqara | ZNQBCZ11LM | Device Temp | Aqara/LUMI | +| Aqara | ZNQBKG24LM | Device Temp | Aqara/LUMI | +| Aqara | ZNQBKG25LM | Device Temp | Aqara/LUMI | +| Aqara | ZNQBKG26LM | Device Temp | Aqara/LUMI | +| Aqara | ZNQBKG31LM | Device Temp | Aqara/LUMI | +| Aqara | ZNQBKG38LM | Device Temp | Aqara/LUMI | +| Aqara | ZNQBKG39LM | Device Temp | Aqara/LUMI | +| Aqara | ZNQBKG40LM | Device Temp | Aqara/LUMI | +| Aqara | ZNQBKG41LM | Device Temp | Aqara/LUMI | +| Aqara | ZNQBKG42LM | Device Temp | Aqara/LUMI | +| Aqara | ZNQBKG43LM | Device Temp | Aqara/LUMI | +| Aqara | ZNQBKG44LM | Device Temp | Aqara/LUMI | +| Aqara | ZNQBKG45LM | Device Temp | Aqara/LUMI | +| Aqara | ZNTGMK11LM | | Aqara/LUMI | +| Aqara | ZNTGMK12LM | Device Temp | Aqara/LUMI | +| Aqara | ZNXDD01LM | Device Temp | Aqara/LUMI | +| Aqara | ZNXNKG01LM | Device Temp | Aqara/LUMI | +| Aqara | ZNYB01LM | | Aqara/LUMI | +| Arteco | ZP-301Z | Motion, Illuminance | Tuya | +| Arteco | ZS-300Z | Soil Moisture, Temperature, Humidity, Illuminance | Tuya | +| Arteco | ZS-301Z | Temperature, Soil Moisture, Humidity, Illuminance | Tuya | +| Arteco | ZS-SF00 | Battery, Soil Moisture, Temperature, Humidity, Illuminance | Tuya | +| Atlantic Group | 100050060900 | Motion | Standard ZCL | +| Atsmart | Z6 | | Standard ZCL | +| Aurora | AU-A1ZB2WDM-Slave | | Standard ZCL | +| Aurora Lighting | AU-A1CE14ZCX6 | | Standard ZCL | +| Aurora Lighting | AU-A1GSZ9B/27 | | Standard ZCL | +| Aurora Lighting | AU-A1GSZ9CX | | Standard ZCL | +| Aurora Lighting | AU-A1GSZ9RGBW_HV-GSCXZB269K | | Standard ZCL | +| Aurora Lighting | AU-A1GUZB5/30 | | Standard ZCL | +| Aurora Lighting | AU-A1GUZBCX5 | | Standard ZCL | +| Aurora Lighting | AU-A1GUZBRGBW | | Standard ZCL | +| Aurora Lighting | AU-A1VG125Z5E/19 | | Standard ZCL | +| Aurora Lighting | AU-A1VGSZ5E/19 | | Standard ZCL | +| Aurora Lighting | AU-A1ZB110 | | Standard ZCL | +| Aurora Lighting | AU-A1ZB2WDM | | Standard ZCL | +| Aurora Lighting | AU-A1ZBDSS | | Standard ZCL | +| Aurora Lighting | AU-A1ZBDWS | Contact, Battery | Standard ZCL | +| Aurora Lighting | AU-A1ZBMPRO1ZX | | Standard ZCL | +| Aurora Lighting | AU-A1ZBPIA | Device Temp | Standard ZCL | +| Aurora Lighting | AU-A1ZBPIAB | | Standard ZCL | +| Aurora Lighting | AU-A1ZBPIRS | Motion, Illuminance | Standard ZCL | +| Aurora Lighting | AU-A1ZBR16A | | Standard ZCL | +| Aurora Lighting | AU-A1ZBR1GW | Battery | Standard ZCL | +| Aurora Lighting | AU-A1ZBR2GW | Battery | Standard ZCL | +| Aurora Lighting | AU-A1ZBRC | Battery | Standard ZCL | +| Aurora Lighting | AU-A1ZBSCRGBCX | | Standard ZCL | +| AutomatOn | AUT000069 | | Standard ZCL | +| AwoX | 110285 | | Standard ZCL | +| AwoX | 110308 | | Standard ZCL | +| AwoX | 12226 | | Standard ZCL | +| AwoX | 33943/33944/33946 | | Standard ZCL | +| AwoX | 33952 | | Standard ZCL | +| AwoX | 33955 | | Standard ZCL | +| AwoX | 33957 | | Standard ZCL | +| AwoX | AwoX-light | | Standard ZCL | +| AwoX | EBF_RGB_Zm | | Standard ZCL | +| AwoX | EGLO_ZM_RGB_W | | Standard ZCL | +| AwoX | EPIR_Zm | Motion, Battery | Standard ZCL | +| AwoX | ERCU_WS_Zm | | Standard ZCL | +| AwoX | EZMB-RGB-TW-I2C | | Standard ZCL | +| BITUO TECHNIK | SDM01B-U01 | | Standard ZCL | +| BITUO TECHNIK | SDM01W-U01 | | Standard ZCL | +| BITUO TECHNIK | SDM02-U00 | | Standard ZCL | +| BITUO TECHNIK | SDM02-U01 | | Standard ZCL | +| BITUO TECHNIK | SDM02-U02 | | Standard ZCL | +| BITUO TECHNIK | SPM01-U00 | | Standard ZCL | +| BITUO TECHNIK | SPM01-U01 | | Standard ZCL | +| BITUO TECHNIK | SPM01-U02 | | Standard ZCL | +| BITUO TECHNIK | SPM02-U00 | | Standard ZCL | +| BITUO TECHNIK | SPM02-U01 | | Standard ZCL | +| BITUO TECHNIK | SPM02-U02 | | Standard ZCL | +| BOX | ERC2201-Z | | Standard ZCL | +| BOX | EWS1154-Z | | Standard ZCL | +| BTicino | 4411C/L4411C/N4411C/NT4411C | | Standard ZCL | +| BTicino | K4003C/L4003C/N4003C/NT4003C | | Standard ZCL | +| BTicino | L4531C | | Standard ZCL | +| BYUN | M415-5C | Gas | Standard ZCL | +| BYUN | M415-6C | Smoke | Standard ZCL | +| Bacchus | Bacchus Water level meter | Temperature, Battery | Standard ZCL | +| Bacchus | Duck Pool Thermometer | Temperature, Battery | Standard ZCL | +| Bacchus | Flower_Sensor_v2 | Soil Moisture, Temperature, Illuminance, Battery | Standard ZCL | +| Bacchus | Flower_Sensor_v4 | Soil Moisture, Temperature, Illuminance, Battery | Standard ZCL | +| Bacchus | Mercury_3ph_Counter | Temperature | Standard ZCL | +| Bacchus | Mercury_Counter | Temperature | Standard ZCL | +| Bacchus | Presence_Sensor_v2 | Motion, Illuminance | Standard ZCL | +| Bacchus | Presence_Sensor_v2.6 | Motion, Illuminance | Standard ZCL | +| Bacchus | Water_Station | Water | Standard ZCL | +| Bankamp | 2189/1-xx | | Standard ZCL | +| Bega | 13557 | | Standard ZCL | +| Bega | 70049 | | Standard ZCL | +| Bega | 85000 | | Standard ZCL | +| Belkin | F7C033 | | Standard ZCL | +| BlitzWolf | BW-IS3 | Motion | Standard ZCL | +| BlitzWolf | BW-SS7_1gang | | Standard ZCL | +| BlitzWolf | BW-SS7_2gang | | Standard ZCL | +| Bosch | 8750001213 | Smoke, Temperature, Humidity, Illuminance, Battery | Standard ZCL | +| Bosch | BMCT-DZ | | Standard ZCL | +| Bosch | BMCT-RZ | | Standard ZCL | +| Bosch | BMCT-SLZ | | Standard ZCL | +| Bosch | BSD-2 | Smoke, Battery | Standard ZCL | +| Bosch | BSEN-C2 | Contact, Battery | Standard ZCL | +| Bosch | BSEN-C2D | Contact, Battery | Standard ZCL | +| Bosch | BSEN-CV | Contact, Vibration, Battery | Standard ZCL | +| Bosch | BSEN-M | Motion, Illuminance, Temperature | Standard ZCL | +| Bosch | BSEN-W | Water, Battery | Standard ZCL | +| Bosch | BSP-FD | | Standard ZCL | +| Bosch | BSP-FZ2 | | Standard ZCL | +| Bosch | BTH-RM | Humidity, Battery | Standard ZCL | +| Bosch | BTH-RM230Z | Humidity | Standard ZCL | +| Bosch | ISW-ZPR1-WP13 | Motion, Temperature, Battery | Standard ZCL | +| Bosch | RADION TriTech ZB | Motion, Temperature, Battery, Illuminance | Standard ZCL | +| Bouffalolab | RMC002 | | Standard ZCL | +| Brimate | FZB8708HD-S1 | Motion | Standard ZCL | +| Brun Holding | Fire Fence | Battery, Temperature | Standard ZCL | +| Busch-Jaeger | 6717-84 | | Standard ZCL | +| Busch-Jaeger | 6735/6736/6737 | | Standard ZCL | +| CASAIA | CCB432 | | Standard ZCL | +| CASAIA | CSAC451-WTC-E | | Standard ZCL | +| CASAIA | CSLC601-D-E | | Standard ZCL | +| CASAIA | CTHS-317-ET | Temperature, Battery | Standard ZCL | +| CLEODE | ZPLUG_Boost | | Standard ZCL | +| COOLO | CS-201Z | Temperature, Humidity, Soil Moisture, Battery | Tuya | +| CREE | B00TN589ZG | | Standard ZCL | +| CTM Lyng | 4503145 | | Standard ZCL | +| CTM Lyng | 6254380 | Device Temp | Standard ZCL | +| CTM Lyng | AX_Valve_Controller | Water | Standard ZCL | +| CTM Lyng | AX_Water_Sensor | Water, Battery | Standard ZCL | +| CTM Lyng | CTM_MBD_Dim | Motion, Illuminance | Standard ZCL | +| CTM Lyng | MBD-S | Motion, Illuminance | Standard ZCL | +| CTM Lyng | mKomfy_Sensor | Battery, Temperature | Standard ZCL | +| CTM Lyng | mStikk_Outlet | | Standard ZCL | +| CTM Lyng | mSwitch_Mic | Smoke, Temperature, Battery | Standard ZCL | +| CTM Lyng | mTouch_Air_Sensor | Battery, Temperature, Humidity | Standard ZCL | +| CTM Lyng | mTouch_Astro | | Standard ZCL | +| CTM Lyng | mTouch_Bryter | Battery, Temperature | Standard ZCL | +| CTM Lyng | mTouch_Dim | | Standard ZCL | +| CTM Lyng | mkomfy25 | | Standard ZCL | +| CWD | HLL6948V1 | | Standard ZCL | +| CY-LIGHTING | DM A60F | | Standard ZCL | +| Calex | 421782 | | Standard ZCL | +| Calex | 421786 | | Standard ZCL | +| Calex | 421792 | | Standard ZCL | +| Candeo | C-RFZB-SM1 | | Standard ZCL | +| Candeo | C-ZB-DM201-2G | | Standard ZCL | +| Candeo | C-ZB-DM204 | | Standard ZCL | +| Candeo | C-ZB-DM204v2 | | Standard ZCL | +| Candeo | C-ZB-LC20-CCT | | Standard ZCL | +| Candeo | C-ZB-LC20-Dim | | Standard ZCL | +| Candeo | C-ZB-LC20-RGB | | Standard ZCL | +| Candeo | C-ZB-LC20-RGBCCT | | Standard ZCL | +| Candeo | C-ZB-LC20-RGBW | | Standard ZCL | +| Candeo | C-ZB-RD1 | | Standard ZCL | +| Candeo | C-ZB-RD1P-DIM | | Standard ZCL | +| Candeo | C-ZB-RD1P-DPM | | Standard ZCL | +| Candeo | C-ZB-RD1P-REM | | Standard ZCL | +| Candeo | C-ZB-SEDC | Contact, Battery | Standard ZCL | +| Candeo | C-ZB-SEMO | Motion, Battery, Illuminance | Standard ZCL | +| Candeo | C-ZB-SETE | Temperature, Humidity, Battery | Standard ZCL | +| Candeo | C-ZB-SEWA | Water, Battery | Standard ZCL | +| Candeo | C-ZB-SM205-2G | | Standard ZCL | +| Candeo | C-ZB-SM30-2G | | Standard ZCL | +| Candeo | C201 | | Standard ZCL | +| Candeo | C202 | | Standard ZCL | +| Candeo | C202.1 | | Standard ZCL | +| Candeo | C203 | | Standard ZCL | +| Candeo | C204 | | Standard ZCL | +| Candeo | C205 | | Standard ZCL | +| Candeo | C210 | | Standard ZCL | +| Centralite | 3200-fr | | Standard ZCL | +| Centralite | 3310-G | Temperature, Humidity, Battery | Standard ZCL | +| Centralite | 3315-Geu | Water, Temperature, Battery | Standard ZCL | +| Centralite | 3323-G | Contact, Temperature | Standard ZCL | +| Centralite | 3328-G | Motion, Temperature | Standard ZCL | +| Centralite | 3400-D | Motion, Battery, Temperature | Standard ZCL | +| Centralite | 3420-G | | Standard ZCL | +| Centralite | 4200-C | | Standard ZCL | +| Centralite | 4256050-RZHAC | | Standard ZCL | +| Centralite | 4256050-ZHAC | | Standard ZCL | +| Centralite | 4256251-RZHAC | | Standard ZCL | +| Centralite | 4257050-RZHAC | | Standard ZCL | +| Centralite | 4257050-ZHAC | | Standard ZCL | +| Chacon | ZB-PM-01 | | Standard ZCL | +| Cleverio | SS300 | Battery, Temperature, Humidity | Standard ZCL | +| ClickSmart+ | CMA30651 | | Standard ZCL | +| ClickSmart+ | CSP041 | | Standard ZCL | +| ClickSmart+ | CSP042 | | Standard ZCL | +| ClickSmart+ | CSP043 | | Standard ZCL | +| ClickSmart+ | CSP051 | | Standard ZCL | +| ClickSmart+ | CSP052 | | Standard ZCL | +| Climax | CO-8ZBS | Carbon Monoxide, Battery | Standard ZCL | +| Climax | PRL-1ZBS-12/24V | | Standard ZCL | +| Climax | PSM-29ZBS | | Standard ZCL | +| Climax | PSM-29ZBSR | | Standard ZCL | +| Climax | PSS-23ZBS | | Standard ZCL | +| Climax | RS-23ZBS | Temperature, Humidity | Standard ZCL | +| Climax | SD-8SCZBS | Smoke, Battery | Standard ZCL | +| Climax | WLS-15ZBS | Water, Battery | Standard ZCL | +| Climax | WS-15ZBS | Water | Standard ZCL | +| Commercial Electric | 53170161 | | Standard ZCL | +| Coswall | SM-PW801EZ | | Standard ZCL | +| Custom devices (DiY) | ACW02-ZB | | Standard ZCL | +| Custom devices (DiY) | CC2538.ROUTER.V2 | Device Temp | Standard ZCL | +| Custom devices (DiY) | DNCKATSD001 | | Standard ZCL | +| Custom devices (DiY) | DNCKATSW001 | | Standard ZCL | +| Custom devices (DiY) | DNCKATSW002 | | Standard ZCL | +| Custom devices (DiY) | DNCKATSW003 | | Standard ZCL | +| Custom devices (DiY) | DNCKATSW004 | | Standard ZCL | +| Custom devices (DiY) | LYWSD03MMC | Battery, Temperature, Humidity | Standard ZCL | +| Custom devices (DiY) | MHO-C401N | Battery, Temperature, Humidity | Standard ZCL | +| Custom devices (DiY) | ZG-204ZL-z | Motion, Battery, Illuminance | Standard ZCL | +| Custom devices (DiY) | ZeeFlora | Soil Moisture, Battery, Temperature, Illuminance | Standard ZCL | +| Custom devices (DiY) | ZigUP | | Standard ZCL | +| Custom devices (DiY) | b-parasite | Temperature, Humidity, Battery, Soil Moisture, Illuminance | Standard ZCL | +| Custom devices (DiY) | m5NanoC6 | | Standard ZCL | +| Custom devices (DiY) | ptvo_counter_2ch | Battery | Standard ZCL | +| D-Link | DCH-B112 | Contact, Vibration, Battery | Standard ZCL | +| DIRECTSIGNS | DS-Z-001DE | | Standard ZCL | +| DIYRuZ | DIYRuZ_AirSense | Temperature, Humidity, Pressure | Standard ZCL | +| DIYRuZ | DIYRuZ_Flower | Soil Moisture, Battery, Humidity, Pressure, Temperature, Illuminance | Standard ZCL | +| DIYRuZ | DIYRuZ_Geiger | | Standard ZCL | +| DIYRuZ | DIYRuZ_R4_5 | | Standard ZCL | +| DIYRuZ | DIYRuZ_R8_8 | | Standard ZCL | +| DIYRuZ | DIYRuZ_RT | Temperature | Standard ZCL | +| DIYRuZ | DIYRuZ_magnet | Contact, Battery | Standard ZCL | +| DIYRuZ | DIYRuZ_rspm | | Standard ZCL | +| DNAKE | CS-Z-CZ-2402 | | Standard ZCL | +| DOMRAEM | DOM-Z-105P_CCT | | Standard ZCL | +| DOMRAEM | DOM-Z-105P_DIMMER | | Standard ZCL | +| DOMRAEM | DOM-Z-105P_RGB | | Standard ZCL | +| DOMRAEM | DOM-Z-105P_RGBCCT | | Standard ZCL | +| DOMRAEM | DOM-Z-105P_RGBW | | Standard ZCL | +| DOMRAEM | DOM-Z-105P_WW/CW | | Standard ZCL | +| DQHOME | dqhome.re4 | | Standard ZCL | +| Danalock | V3-BTZB/V3-BTZBE | Battery | Standard ZCL | +| Danfoss | Icon | Battery, Temperature | Standard ZCL | +| Danfoss | Icon2 | Battery, Temperature, Humidity | Standard ZCL | +| Datek | 0402946 | Battery | Standard ZCL | +| Datek | HBR2917E | Battery, Temperature | Standard ZCL | +| Datek | HLU2909K | Temperature | Standard ZCL | +| Datek | HSE2905E | Temperature | Standard ZCL | +| Datek | HSE2919E | Water, Battery, Temperature | Standard ZCL | +| Datek | HSE2920E | Contact, Temperature | Standard ZCL | +| Datek | HSE2927E | Motion, Temperature, Illuminance | Standard ZCL | +| Datek | HSE2936T | Contact, Temperature | Standard ZCL | +| Dawon DNS | KB-B540R-ZB | | Standard ZCL | +| Dawon DNS | PM-B430-ZB | | Standard ZCL | +| Dawon DNS | PM-B530-ZB | | Standard ZCL | +| Dawon DNS | PM-B540-ZB | Device Temp | Standard ZCL | +| Dawon DNS | PM-C140-ZB | | Standard ZCL | +| Dawon DNS | PM-C150-ZB | | Standard ZCL | +| Dawon DNS | PM-S140-ZB | | Standard ZCL | +| Dawon DNS | PM-S140R-ZB | | Standard ZCL | +| Dawon DNS | PM-S150-ZB | | Standard ZCL | +| Dawon DNS | PM-S240-ZB | | Standard ZCL | +| Dawon DNS | PM-S240R-ZB | | Standard ZCL | +| Dawon DNS | PM-S250-ZB | | Standard ZCL | +| Dawon DNS | PM-S340-ZB | | Standard ZCL | +| Dawon DNS | PM-S340R-ZB | | Standard ZCL | +| Dawon DNS | PM-S350-ZB | | Standard ZCL | +| Dawon DNS | SG-V100-ZB | Battery | Standard ZCL | +| Dawon DNS | TH-110-ZB | Battery, Temperature, Humidity | Standard ZCL | +| Develco | AQSZB-110 | Temperature, Humidity, Battery | Standard ZCL | +| Develco | Co019 | | Standard ZCL | +| Develco | EMIZB-132 | | Standard ZCL | +| Develco | FLSZB-110 | Water, Temperature, Battery | Standard ZCL | +| Develco | HESZB-120 | Smoke, Temperature, Battery | Standard ZCL | +| Develco | HMSZB-110 | Temperature, Humidity, Battery | Standard ZCL | +| Develco | IOMZB-110 | | Standard ZCL | +| Develco | MOSZB-130 | Motion | Standard ZCL | +| Develco | MOSZB-140 | Motion, Temperature, Illuminance, Battery | Standard ZCL | +| Develco | MOSZB-141 | Motion | Standard ZCL | +| Develco | MOSZB-153 | Motion, Temperature, Illuminance, Battery | Standard ZCL | +| Develco | SBTZB-110 | Battery | Standard ZCL | +| Develco | SIRZB-110 | Temperature, Battery | Standard ZCL | +| Develco | SMRZB-143 | Device Temp | Standard ZCL | +| Develco | SMRZB-332 | | Standard ZCL | +| Develco | SMSZB-120 | Smoke, Temperature, Battery | Standard ZCL | +| Develco | SPLZB-131 | Device Temp | Standard ZCL | +| Develco | SPLZB-132 | Device Temp | Standard ZCL | +| Develco | SPLZB-134 | Device Temp | Standard ZCL | +| Develco | SPLZB-137 | | Standard ZCL | +| Develco | SPLZB-141 | | Standard ZCL | +| Develco | WISZB-120 | Contact, Temperature, Battery | Standard ZCL | +| Develco | WISZB-121 | Contact, Battery | Standard ZCL | +| Develco | WISZB-134 | Contact, Battery | Standard ZCL | +| Develco | WISZB-137 | Vibration, Temperature, Battery | Standard ZCL | +| Develco | WISZB-138 | Contact, Temperature, Battery | Standard ZCL | +| Develco | ZHEMI101 | | Standard ZCL | +| Dongguan Pinjia Technology Co.,LTD. | PJ3201A | Motion, Illuminance | Tuya | +| Dowsing & Reynolds | DR3000 | | Standard ZCL | +| Dresden Elektronik | BN-600085 | Battery | Standard ZCL | +| Dresden Elektronik | BN-600087 | Battery | Standard ZCL | +| Dresden Elektronik | FLS-A | | Standard ZCL | +| Dresden Elektronik | FLS-CT | | Standard ZCL | +| Dresden Elektronik | FLS-H | | Standard ZCL | +| Dresden Elektronik | FLS-PP | | Standard ZCL | +| Dresden Elektronik | Kobold | | Standard ZCL | +| EDP | PLUG EDP RE:DY | | Standard ZCL | +| EDP | SWITCH EDP RE:DY | | Standard ZCL | +| EFEKTA | DIYRuZ_AirSense_Reloaded | Temperature, Pressure, Humidity | Standard ZCL | +| EFEKTA | EFEKTA_AQ_Smart_Monitor | Temperature, Humidity | Standard ZCL | +| EFEKTA | EFEKTA_AQ_Smart_Monitor_Gen2 | Temperature, Humidity, Illuminance | Standard ZCL | +| EFEKTA | EFEKTA_Air_Monitor | Battery | Standard ZCL | +| EFEKTA | EFEKTA_Air_Quality_Station | Temperature, Humidity, Illuminance | Standard ZCL | +| EFEKTA | EFEKTA_Air_Quality_Station_2 | Temperature, Humidity, Illuminance | Standard ZCL | +| EFEKTA | EFEKTA_Air_Quality_Station_2c | Temperature, Humidity, Illuminance | Standard ZCL | +| EFEKTA | EFEKTA_Air_Quality_Station_2o | Temperature, Humidity, Illuminance | Standard ZCL | +| EFEKTA | EFEKTA_CO2_Smart_Monitor | Temperature, Humidity | Standard ZCL | +| EFEKTA | EFEKTA_CO2_Smart_Monitor_Gen2 | Temperature, Humidity, Illuminance | Standard ZCL | +| EFEKTA | EFEKTA_DigiBaro | Pressure, Temperature, Humidity, Battery | Standard ZCL | +| EFEKTA | EFEKTA_PST_DUO_V1 | Pressure, Temperature, Battery | Standard ZCL | +| EFEKTA | EFEKTA_PST_DUO_V1_LR | Pressure, Temperature, Battery | Standard ZCL | +| EFEKTA | EFEKTA_PST_POW_DUO_V1_LR | Pressure, Temperature, Battery | Standard ZCL | +| EFEKTA | EFEKTA_PST_POW_DUO_V2_LR | Pressure, Temperature, Battery | Standard ZCL | +| EFEKTA | EFEKTA_PST_POW_V1_LR | Pressure, Temperature, Battery | Standard ZCL | +| EFEKTA | EFEKTA_PST_POW_V2_LR | Pressure, Temperature, Battery | Standard ZCL | +| EFEKTA | EFEKTA_PST_V1 | Pressure, Temperature, Battery | Standard ZCL | +| EFEKTA | EFEKTA_PST_V1_LR | Pressure, Temperature, Battery | Standard ZCL | +| EFEKTA | EFEKTA_PS_POW_PRO | Pressure, Battery | Standard ZCL | +| EFEKTA | EFEKTA_PWS | Soil Moisture, Battery, Temperature | Standard ZCL | +| EFEKTA | EFEKTA_PWS_Max | Soil Moisture, Battery, Illuminance, Temperature, Humidity | Standard ZCL | +| EFEKTA | EFEKTA_PWS_MaxPro | Soil Moisture, Battery, Illuminance, Temperature, Humidity | Standard ZCL | +| EFEKTA | EFEKTA_Pixel_Open_Air | Temperature, Humidity | Standard ZCL | +| EFEKTA | EFEKTA_Pixel_Open_Air_II | Temperature, Humidity | Standard ZCL | +| EFEKTA | EFEKTA_Smart_AQ_Box_R3 | Pressure, Temperature, Humidity | Standard ZCL | +| EFEKTA | EFEKTA_T1_MAX | Temperature, Battery | Standard ZCL | +| EFEKTA | EFEKTA_T1_NTC10K | Temperature, Battery | Standard ZCL | +| EFEKTA | EFEKTA_T1_POW_NTC10K | Temperature, Battery | Standard ZCL | +| EFEKTA | EFEKTA_T1_Y | Temperature, Battery | Standard ZCL | +| EFEKTA | EFEKTA_T1_Y_LR | Temperature, Battery | Standard ZCL | +| EFEKTA | EFEKTA_T1_v2 | Temperature, Battery | Standard ZCL | +| EFEKTA | EFEKTA_T1_v2_LR | Temperature, Battery | Standard ZCL | +| EFEKTA | EFEKTA_T8_POW | Temperature, Battery | Standard ZCL | +| EFEKTA | EFEKTA_TDS_Monitor | Temperature | Standard ZCL | +| EFEKTA | EFEKTA_THP | Battery, Temperature, Humidity, Pressure | Standard ZCL | +| EFEKTA | EFEKTA_THP_LR | Battery, Temperature, Humidity, Pressure | Standard ZCL | +| EFEKTA | EFEKTA_TH_DUO | Temperature, Humidity, Battery | Standard ZCL | +| EFEKTA | EFEKTA_TH_DUO_LR | Temperature, Humidity, Battery | Standard ZCL | +| EFEKTA | EFEKTA_TH_POW | Temperature, Humidity, Battery | Standard ZCL | +| EFEKTA | EFEKTA_TH_v1 | Temperature, Humidity, Battery | Standard ZCL | +| EFEKTA | EFEKTA_TH_v1_LR | Temperature, Humidity, Battery | Standard ZCL | +| EFEKTA | EFEKTA_TH_v2 | Temperature, Humidity, Battery | Standard ZCL | +| EFEKTA | EFEKTA_TH_v2_LR | Temperature, Humidity, Battery | Standard ZCL | +| EFEKTA | EFEKTA_eAir_Monitor | Battery | Standard ZCL | +| EFEKTA | EFEKTA_eFlora | Soil Moisture, Battery, Temperature, Humidity, Illuminance | Standard ZCL | +| EFEKTA | EFEKTA_eFlora_Max_Pro | Soil Moisture, Battery, Temperature, Humidity, Illuminance | Standard ZCL | +| EFEKTA | EFEKTA_eFlora_Pro | Soil Moisture, Battery, Temperature, Humidity, Illuminance | Standard ZCL | +| EFEKTA | EFEKTA_eFlower_Pro | Soil Moisture, Battery, Illuminance, Temperature, Humidity | Standard ZCL | +| EFEKTA | EFEKTA_eON213wz | Battery, Temperature, Humidity, Pressure | Standard ZCL | +| EFEKTA | EFEKTA_eON213z | Battery, Temperature, Humidity | Standard ZCL | +| EFEKTA | EFEKTA_eON29wz | Battery, Illuminance, Temperature, Humidity, Pressure | Standard ZCL | +| EFEKTA | EFEKTA_ePST_POW | Pressure, Temperature, Battery | Standard ZCL | +| EFEKTA | EFEKTA_ePST_POW_V2 | Pressure, Temperature, Battery | Standard ZCL | +| EFEKTA | EFEKTA_ePWS | Battery, Soil Moisture, Temperature | Standard ZCL | +| EFEKTA | EFEKTA_eTH102 | Battery, Temperature, Humidity | Standard ZCL | +| EFEKTA | EFEKTA_eTH102z | Temperature, Humidity, Battery | Standard ZCL | +| EFEKTA | EFEKTA_eTH102zex | Temperature, Humidity, Battery | Standard ZCL | +| EFEKTA | EFEKTA_eTH_POW | Temperature, Humidity, Battery | Standard ZCL | +| EFEKTA | EFEKTA_iAQ | Temperature, Humidity, Illuminance | Standard ZCL | +| EFEKTA | EFEKTA_iAQ2_R2 | Temperature, Humidity, Pressure, Illuminance | Standard ZCL | +| EFEKTA | EFEKTA_iAQ3 | Temperature, Humidity, Illuminance | Standard ZCL | +| EFEKTA | EFEKTA_iAQ_S_I | Temperature, Humidity, Illuminance | Standard ZCL | +| EFEKTA | EFEKTA_iAQ_S_II | Temperature, Humidity, Pressure, Illuminance | Standard ZCL | +| EFEKTA | EFEKTA_iAQ_S_III | Temperature, Humidity, Illuminance | Standard ZCL | +| EFEKTA | EFEKTA_miniPWS | Soil Moisture, Battery | Standard ZCL | +| EFEKTA | Egony_Flower | Soil Moisture, Battery, Temperature, Illuminance | Standard ZCL | +| EFEKTA | MODKAM_Flower | Soil Moisture, Temperature, Illuminance, Battery | Standard ZCL | +| EFEKTA | Netuya_CO2_Smart_Box | | Standard ZCL | +| EFEKTA | Open_PM_Monitor | | Standard ZCL | +| EFEKTA | SNZB-02_EFEKTA | Battery, Temperature, Humidity | Standard ZCL | +| EFEKTA | zFlora_Pro | Soil Moisture, Battery, Temperature, Humidity, Illuminance | Standard ZCL | +| EFEKTA | zFlora_ProMax | Soil Moisture, Battery, Temperature, Humidity, Illuminance | Standard ZCL | +| EFEKTA | zFlora_S | Soil Moisture, Battery, Temperature, Humidity | Standard ZCL | +| EFEKTA | zFlora_S_Max | Soil Moisture, Battery, Temperature, Humidity, Illuminance | Standard ZCL | +| EFEKTA | zFlora_X_Max | Soil Moisture, Temperature, Illuminance, Battery | Standard ZCL | +| EGLO | 12242 | | Standard ZCL | +| EGLO | 300686 | | Standard ZCL | +| EGLO | 900024/12253 | | Standard ZCL | +| EGLO | 900091 | | Standard ZCL | +| EGLO | 901471 | | Standard ZCL | +| EGLO | 98847 | | Standard ZCL | +| EGLO | 99099 | | Standard ZCL | +| EGLO | 99106 | | Standard ZCL | +| ELKO | 316GLEDRF | | Standard ZCL | +| ELKO | 4523430 | | Standard ZCL | +| ELKO | EKO01825 | | Standard ZCL | +| ELKO | EKO05806 | | Standard ZCL | +| ENGO | ECB62-ZB | | Tuya | +| ENGO | EONE | Humidity, Battery | Tuya | +| ENGO | EONE-230W | Humidity | Tuya | +| ENGO | EONE-BATB | Humidity, Battery | Tuya | +| ETOP | HT-08 | | Standard ZCL | +| ETOP | HT-10 | | Standard ZCL | +| EVN | ZB24100VS | | Standard ZCL | +| EVN | ZBHS4RGBW | Battery | Standard ZCL | +| EVN | ZBPD23400 | | Standard ZCL | +| EasyAccess | EasyCode903G2.1 | Battery | Standard ZCL | +| Eaton/Halo LED | RL460WHZHA69 | | Standard ZCL | +| EchoStar | SAGE206611 | | Standard ZCL | +| EcoDim | ECO-DIM.06-ZGB | | Standard ZCL | +| EcoDim | ECO-DIM.13 | | Standard ZCL | +| EcoDim | ED-10010 | Battery | Standard ZCL | +| EcoDim | ED-10011 | Battery | Standard ZCL | +| EcoDim | ED-10012 | Battery | Standard ZCL | +| EcoDim | ED-10013 | Battery | Standard ZCL | +| EcoDim | ED-10014 | Battery | Standard ZCL | +| EcoDim | ED-10015 | Battery | Standard ZCL | +| EcoDim | ED-10041 | | Standard ZCL | +| EcoDim | ED-10042 | | Standard ZCL | +| EcoDim | Eco-Dim.05 | | Standard ZCL | +| EcoDim | Eco-Dim.07/Eco-Dim.10 | | Standard ZCL | +| EcoSmart | A9A19A60WESDZ02 | | Standard ZCL | +| EcoSmart | A9BR3065WESDZ02 | | Standard ZCL | +| EcoSmart | D1523 | | Standard ZCL | +| EcoSmart | D1531 | | Standard ZCL | +| EcoSmart | D1532 | | Standard ZCL | +| EcoSmart | D1533 | | Standard ZCL | +| EcoSmart | D1542 | | Standard ZCL | +| EcoSmart | D1821 | | Standard ZCL | +| Ecolink | 4655BC0-R | Contact, Temperature | Standard ZCL | +| Ecolink | FFZB1-SM-ECO | Temperature, Battery | Standard ZCL | +| Ekaza | EKAC-T3095Z | | Standard ZCL | +| Ekaza | EKAC-T3096Z | | Standard ZCL | +| Ekaza | Mercurio-3 | | Standard ZCL | +| Enbrighten | 43076 | | Standard ZCL | +| Enbrighten | 43078 | | Standard ZCL | +| Enbrighten | 43080 | | Standard ZCL | +| Enbrighten | 43082 | | Standard ZCL | +| Enkin | ZDM150 | | Standard ZCL | +| Ensystec | Ensystec-Leak-Protect-Zigbee | Water | Standard ZCL | +| Envilar | 1CH-HP-RELAY-7853 | | Standard ZCL | +| Envilar | 2CH-ZG-BOX-RELAY | | Standard ZCL | +| Envilar | 5463 | | Standard ZCL | +| Envilar | 5480 | | Standard ZCL | +| Envilar | 5491 | | Standard ZCL | +| Envilar | 7848 | | Standard ZCL | +| Envilar | 7859 | | Standard ZCL | +| Envilar | ZG102-BOX-UNIDIM | | Standard ZCL | +| Envilar | ZG302-BOX-RELAY | | Standard ZCL | +| Envilar | ZG50CC-CCT-DRIVER | | Standard ZCL | +| Envilar | ZGR904-S | Battery | Standard ZCL | +| Envilar | ZG_LED_DRIVER42CC | | Standard ZCL | +| EssentielB | EB-E14-FLA-CCT | | Standard ZCL | +| EssentielB | EB-E14-P45-RGBW | | Standard ZCL | +| EssentielB | EB-E27-A60-CCT | | Standard ZCL | +| EssentielB | EB-E27-A60-CCT-FC | | Standard ZCL | +| EssentielB | EB-E27-A60-RGBW | | Standard ZCL | +| EssentielB | EB-E27-G95-CCT-FV | | Standard ZCL | +| EssentielB | EB-E27-ST64-CCT-FV | | Standard ZCL | +| EssentielB | EB-GU10-MR16-CCT | | Standard ZCL | +| EssentielB | EB-GU10-MR16-RGBW | | Standard ZCL | +| EssentielB | EB-SB-1B | Battery | Standard ZCL | +| EuControls | LCM-1C09-ZB | | Standard ZCL | +| Evvr | SRB01 | | Standard ZCL | +| Excellux | DHT0001 | Battery, Temperature, Humidity | Tuya | +| Excellux | EZ-104UPT | Battery, Temperature, Illuminance, Pressure | Tuya | +| Excellux | ZG-101K | Battery | Tuya | +| Excellux | ZG-102MV | Contact, Vibration, Battery | Tuya | +| Excellux | ZG-103V | Vibration, Battery | Tuya | +| Excellux | ZG-104PLV | Motion, Vibration, Battery, Illuminance | Tuya | +| Excellux | ZG-105NTH | Battery, Temperature, Humidity | Tuya | +| Excellux | ZG-109TDS | Battery, Temperature, Humidity | Tuya | +| Excellux | ZG-301A | Illuminance | Tuya | +| Excellux | ZS-300TF | Battery, Soil Moisture, Temperature, Humidity, Illuminance | Tuya | +| EyZEE | \_TZE284_0kihjsys | | Standard ZCL | +| FORIA | F00MB00-04-1 | Vibration | Standard ZCL | +| FORIA | F00XN00-04-1 | Battery | Standard ZCL | +| Fantem | ZB003-X | Motion, Temperature, Humidity, Battery, Illuminance | Standard ZCL | +| Fantem | ZB006-X | | Standard ZCL | +| Feibit | FMRC209W | Battery | Standard ZCL | +| Feibit | FZCWD2HW-YH | | Standard ZCL | +| Feibit | FZCWF2LW-BW | | Standard ZCL | +| Feibit | NZSN421W-Q | Battery | Standard ZCL | +| Feibit | SBM01ZB | Motion, Battery | Standard ZCL | +| Feibit | SCA01ZB | Carbon Monoxide, Battery | Standard ZCL | +| Feibit | SDM01ZB | Contact, Battery | Standard ZCL | +| Feibit | SFS01ZB | | Standard ZCL | +| Feibit | SGA01ZB | Gas | Standard ZCL | +| Feibit | SKY01-TS1-101 | | Standard ZCL | +| Feibit | SLS301ZB_2 | | Standard ZCL | +| Feibit | SLS301ZB_3 | | Standard ZCL | +| Feibit | SSA01ZB | Smoke, Battery | Standard ZCL | +| Feibit | SSKT11IW-F1 | | Standard ZCL | +| Feibit | SSS401ZB | | Standard ZCL | +| Feibit | SSS401ZB-T | | Standard ZCL | +| Feibit | STH01ZB | Temperature, Humidity, Battery | Standard ZCL | +| Feibit | SWA01ZB | Water, Battery | Standard ZCL | +| Feibit | SZSN325W-Q | | Standard ZCL | +| Feibit | TSKT106W-M1 | | Standard ZCL | +| Feibit | TSKT113W-H4 | | Standard ZCL | +| Feibit | TSKT222W-H4 | | Standard ZCL | +| Feibit | TZSC302W-V1 | | Standard ZCL | +| Feibit | TZSN408W-V1 | | Standard ZCL | +| Feibit | TZSW22FW-L4 | | Standard ZCL | +| FireAngel | W2-Module | Carbon Monoxide, Battery | Standard ZCL | +| FireAngel | ZBCO-AE-10X-EUR | Carbon Monoxide | Standard ZCL | +| Fischer & Honsel | 020B0B | | Standard ZCL | +| FrankEver | FK-BV05 | | Standard ZCL | +| FrankEver | FK_V02 | | Standard ZCL | +| Frient | EMIZB-141 | Battery | Standard ZCL | +| Frient | EMIZB-151 | | Standard ZCL | +| Frient | SIRZB-112 | Battery | Standard ZCL | +| Frient | SMRZB-153 | | Standard ZCL | +| Frient | SMRZB-342 | Device Temp | Standard ZCL | +| Frient | WISZB-131 | Contact, Battery, Temperature | Standard ZCL | +| Futurehome | 4509243 | | Standard ZCL | +| Futurehome | TS0601_futurehome_thermostat | | Tuya | +| GE | 22670 | | Standard ZCL | +| GE | 45852GE | | Standard ZCL | +| GE | 45853GE | | Standard ZCL | +| GE | 45856GE | | Standard ZCL | +| GE | 45857GE | | Standard ZCL | +| GE | POTLK-WH02 | | Standard ZCL | +| GE | PQC19-DY01 | | Standard ZCL | +| GE | PSB19-SW27 | | Standard ZCL | +| GE | PTAPT-WH02 | | Standard ZCL | +| GIDEALED | ZC05M | | Standard ZCL | +| GIDERWEL | GD-ZCRGB012 | | Standard ZCL | +| GISE | GSKS-ZB | Smoke, Battery | Tuya | +| GMY Smart Bulb | B07KG5KF5R | | Standard ZCL | +| GS | BDHM8E27W70-I1 | | Standard ZCL | +| GS | BRHM8E27W70-I1 | | Standard ZCL | +| GS | SGMHM-I1 | Gas | Standard ZCL | +| GS | SGPHM-I1 | Gas | Standard ZCL | +| GS | SKHMP30-I1 | | Standard ZCL | +| GS | SMHM-I1 | Motion, Battery | Standard ZCL | +| GS | SOHM-I1 | Contact, Battery | Standard ZCL | +| GS | SSHM-I1 | Smoke, Battery | Standard ZCL | +| GS | STHM-I1H | Temperature, Humidity, Battery | Standard ZCL | +| GS | SWHM-I1 | Water, Battery | Standard ZCL | +| Gewiss | GWA1201 | | Standard ZCL | +| Gewiss | GWA1521 | | Standard ZCL | +| Gewiss | GWA1522 | | Standard ZCL | +| Girier | JR-ZDS01 | | Standard ZCL | +| Girier | TZE284_4cqhd2ha | Vibration | Tuya | +| Gledopto | GD-CZ-006 | | Standard ZCL | +| Gledopto | GL-B-001P | | Standard ZCL | +| Gledopto | GL-B-001Z | | Standard ZCL | +| Gledopto | GL-B-001ZS | | Standard ZCL | +| Gledopto | GL-B-002P | | Standard ZCL | +| Gledopto | GL-B-003P | | Standard ZCL | +| Gledopto | GL-B-004P | | Standard ZCL | +| Gledopto | GL-B-007P | | Standard ZCL | +| Gledopto | GL-B-007Z | | Standard ZCL | +| Gledopto | GL-B-007ZS | | Standard ZCL | +| Gledopto | GL-B-008P | | Standard ZCL | +| Gledopto | GL-B-008Z | | Standard ZCL | +| Gledopto | GL-B-008ZS | | Standard ZCL | +| Gledopto | GL-C-003P | | Standard ZCL | +| Gledopto | GL-C-004P | | Standard ZCL | +| Gledopto | GL-C-006 | | Standard ZCL | +| Gledopto | GL-C-006P | | Standard ZCL | +| Gledopto | GL-C-006S | | Standard ZCL | +| Gledopto | GL-C-007-1ID | | Standard ZCL | +| Gledopto | GL-C-007-2ID | | Standard ZCL | +| Gledopto | GL-C-007P | | Standard ZCL | +| Gledopto | GL-C-007S | | Standard ZCL | +| Gledopto | GL-C-008-1ID | | Standard ZCL | +| Gledopto | GL-C-008-2ID | | Standard ZCL | +| Gledopto | GL-C-008P | | Standard ZCL | +| Gledopto | GL-C-008S | | Standard ZCL | +| Gledopto | GL-C-009 | | Standard ZCL | +| Gledopto | GL-C-009P | | Standard ZCL | +| Gledopto | GL-C-009S | | Standard ZCL | +| Gledopto | GL-C-103P | | Standard ZCL | +| Gledopto | GL-C-310P | | Standard ZCL | +| Gledopto | GL-D-001P | | Standard ZCL | +| Gledopto | GL-D-002P | | Standard ZCL | +| Gledopto | GL-D-003P | | Standard ZCL | +| Gledopto | GL-D-003Z | | Standard ZCL | +| Gledopto | GL-D-003ZS | | Standard ZCL | +| Gledopto | GL-D-004P | | Standard ZCL | +| Gledopto | GL-D-004Z | | Standard ZCL | +| Gledopto | GL-D-004ZS | | Standard ZCL | +| Gledopto | GL-D-005P | | Standard ZCL | +| Gledopto | GL-D-005Z | | Standard ZCL | +| Gledopto | GL-D-005ZS | | Standard ZCL | +| Gledopto | GL-D-006P | | Standard ZCL | +| Gledopto | GL-D-007P | | Standard ZCL | +| Gledopto | GL-D-008P | | Standard ZCL | +| Gledopto | GL-D-009P | | Standard ZCL | +| Gledopto | GL-D-010P | | Standard ZCL | +| Gledopto | GL-D-013P | | Standard ZCL | +| Gledopto | GL-D-015P | | Standard ZCL | +| Gledopto | GL-FL-001P | | Standard ZCL | +| Gledopto | GL-FL-004P | | Standard ZCL | +| Gledopto | GL-FL-004TZ | | Standard ZCL | +| Gledopto | GL-FL-004TZS | | Standard ZCL | +| Gledopto | GL-FL-005P | | Standard ZCL | +| Gledopto | GL-FL-005TZ | | Standard ZCL | +| Gledopto | GL-FL-005TZS | | Standard ZCL | +| Gledopto | GL-FL-006P | | Standard ZCL | +| Gledopto | GL-FL-006TZ | | Standard ZCL | +| Gledopto | GL-FL-006TZS | | Standard ZCL | +| Gledopto | GL-FL-007P | | Standard ZCL | +| Gledopto | GL-G-001P | | Standard ZCL | +| Gledopto | GL-G-001Z | | Standard ZCL | +| Gledopto | GL-G-001ZS | | Standard ZCL | +| Gledopto | GL-G-002P | | Standard ZCL | +| Gledopto | GL-G-003P | | Standard ZCL | +| Gledopto | GL-G-004P | | Standard ZCL | +| Gledopto | GL-G-005P | | Standard ZCL | +| Gledopto | GL-G-007Z | | Standard ZCL | +| Gledopto | GL-G-101P | | Standard ZCL | +| Gledopto | GL-H-001 | | Standard ZCL | +| Gledopto | GL-LB-001P | | Standard ZCL | +| Gledopto | GL-MC-001 | | Standard ZCL | +| Gledopto | GL-MC-001P | | Standard ZCL | +| Gledopto | GL-MC-002P | | Standard ZCL | +| Gledopto | GL-P-101P | | Standard ZCL | +| Gledopto | GL-S-003Z | | Standard ZCL | +| Gledopto | GL-S-004P | | Standard ZCL | +| Gledopto | GL-S-004Z | | Standard ZCL | +| Gledopto | GL-S-004ZS | | Standard ZCL | +| Gledopto | GL-S-005Z | | Standard ZCL | +| Gledopto | GL-S-006P | | Standard ZCL | +| Gledopto | GL-S-007P | | Standard ZCL | +| Gledopto | GL-S-007Z | | Standard ZCL | +| Gledopto | GL-S-007ZS | | Standard ZCL | +| Gledopto | GL-S-008Z | | Standard ZCL | +| Gledopto | GL-S-014P | | Standard ZCL | +| Gledopto | GL-SD-001 | | Standard ZCL | +| Gledopto | GL-SD-001P | | Standard ZCL | +| Gledopto | GL-SD-002 | | Standard ZCL | +| Gledopto | GL-SD-003P | | Standard ZCL | +| Gledopto | GL-SD-301P | | Standard ZCL | +| Gledopto | GL-SPI-206P | | Standard ZCL | +| Gledopto | GL-W-001Z | | Standard ZCL | +| Gumax | LST103 | | Standard ZCL | +| HFH Solutions | 303-0136 | | Standard ZCL | +| HOBEIAN | ZG-102ZM | Contact, Vibration, Battery | Tuya | +| HOBEIAN | ZG-204ZE | Motion, Illuminance, Battery | Tuya | +| HOBEIAN | ZG-204ZH | Motion, Illuminance, Temperature, Humidity, Battery | Tuya | +| HOBEIAN | ZG-204ZK | Motion, Battery | Tuya | +| HOBEIAN | ZG-204ZQ | Motion, Illuminance, Temperature, Humidity, Battery | Tuya | +| HOBEIAN | ZG-204ZV | Motion, Illuminance, Temperature, Humidity, Battery | Tuya | +| HOBEIAN | ZG-204ZX | Motion, Illuminance, Temperature, Humidity, Battery | Tuya | +| HOBEIAN | ZG-210Z | Temperature, Humidity, Battery | Tuya | +| HOBEIAN | ZG-223Z | Illuminance, Battery | Tuya | +| HOBEIAN | ZG-226Z | Water, Battery | Tuya | +| HOBEIAN | ZG-228Z | Vibration, Battery | Tuya | +| HOBEIAN | ZG-302ZL | Motion | Tuya | +| HOBEIAN | ZG-302ZM | Motion | Tuya | +| HOBEIAN | ZG-303Z | Temperature, Humidity, Soil Moisture, Battery | Tuya | +| HOBEIAN | ZG-IR01 | Temperature, Humidity, Battery | Tuya | +| HOFTRONIC | HD300W-ZB | | Standard ZCL | +| HORNBACH | 10011722 | | Standard ZCL | +| HORNBACH | 10011723 | | Standard ZCL | +| HORNBACH | 10011724 | | Standard ZCL | +| HORNBACH | 10011725 | | Standard ZCL | +| HORNBACH | 10297665 | | Standard ZCL | +| HORNBACH | 10297666 | | Standard ZCL | +| HORNBACH | 10297667 | | Standard ZCL | +| HORNBACH | 10447293 | | Standard ZCL | +| HORNBACH | 10454466 | | Standard ZCL | +| HORNBACH | 10454467 | | Standard ZCL | +| HORNBACH | 10454468 | | Standard ZCL | +| HORNBACH | 10454469 | | Standard ZCL | +| HORNBACH | 10454470 | | Standard ZCL | +| HORNBACH | 10454471 | | Standard ZCL | +| HZC Electric | D077-ZG | | Standard ZCL | +| HZC Electric | D086-ZG | | Standard ZCL | +| HZC Electric | D692-ZG | | Standard ZCL | +| HZC Electric | S093TH-ZG | Temperature, Humidity | Standard ZCL | +| HZC Electric | S900W-ZG | Water, Battery | Standard ZCL | +| HZC Electric | S902M-ZG | Motion, Battery, Illuminance | Standard ZCL | +| Halemeier | HA-ZBM-MW2 | Battery | Standard ZCL | +| Halemeier | HA-ZGMW2-E | | Standard ZCL | +| Halemeier | HA-ZM12/24-1K | | Standard ZCL | +| Halemeier | HA-ZM12/24-4K | | Standard ZCL | +| Halemeier | HA-ZM12/24-mw2 | | Standard ZCL | +| Halemeier | HA-ZM12mw2-4K | | Standard ZCL | +| Halemeier | HA-ZSM-MW2 | Battery | Standard ZCL | +| Halemeier | HA-ZX1 | Battery | Standard ZCL | +| Halo Smart Labs | HALO | Smoke, Carbon Monoxide, Battery, Temperature, Humidity, Pressure | Standard ZCL | +| Halo Smart Labs | HALO+ | Smoke, Carbon Monoxide, Battery, Temperature, Humidity, Pressure | Standard ZCL | +| Hampton Bay | 54668161 | | Standard ZCL | +| Hampton Bay | 99432 | | Standard ZCL | +| Handshake Finland | 2619839 | | Standard ZCL | +| Haozee | HZ-SL10 | Temperature, Soil Moisture, Battery | Tuya | +| Haozee | HZ-WT02 | Battery | Standard ZCL | +| HeatHUB | HHST001 | Humidity | Tuya | +| Heatit | 1444420 | | Standard ZCL | +| Heiman | D1-EFA | Contact, Battery | Standard ZCL | +| Heiman | HM-5HA-E | Battery, Temperature | Standard ZCL | +| Heiman | HM-636THV-AC-M | Smoke, Battery, Temperature, Humidity | Standard ZCL | +| Heiman | HM-722ESY-E Plus | Carbon Monoxide, Battery, Temperature | Standard ZCL | +| Heiman | HS15A-M | Smoke, Battery | Standard ZCL | +| Heiman | HS1CA-E | Carbon Monoxide, Battery | Standard ZCL | +| Heiman | HS1CA-E-PLUS | Carbon Monoxide, Battery, Temperature | Standard ZCL | +| Heiman | HS1CA-M | Carbon Monoxide, Battery | Standard ZCL | +| Heiman | HS1CG | Gas | Standard ZCL | +| Heiman | HS1CG-E | Gas | Standard ZCL | +| Heiman | HS1CG-E_3.0 | Gas | Standard ZCL | +| Heiman | HS1CG-M | Gas | Standard ZCL | +| Heiman | HS1CG_H | Gas | Standard ZCL | +| Heiman | HS1CG_M | Gas | Standard ZCL | +| Heiman | HS1DS | Contact, Battery | Standard ZCL | +| Heiman | HS1HT | Battery, Temperature, Humidity | Standard ZCL | +| Heiman | HS1HT-N | Temperature, Humidity, Battery | Standard ZCL | +| Heiman | HS1MIS-3.0 | Motion, Battery | Standard ZCL | +| Heiman | HS1MS-EF | Motion | Standard ZCL | +| Heiman | HS1MS-M | Motion | Standard ZCL | +| Heiman | HS1RGB | | Standard ZCL | +| Heiman | HS1RM-E | | Standard ZCL | +| Heiman | HS1SA-E | Smoke, Battery | Standard ZCL | +| Heiman | HS1SA-E Lover | Smoke, Battery | Standard ZCL | +| Heiman | HS1SA-E-PLUS | Smoke, Battery, Temperature | Standard ZCL | +| Heiman | HS1VS-EF | Vibration, Battery | Standard ZCL | +| Heiman | HS1VS-N | Vibration, Battery | Standard ZCL | +| Heiman | HS1WL/HS3WL | Water, Battery | Standard ZCL | +| Heiman | HS2AQ-EF-3.0 | Temperature, Battery, Humidity | Standard ZCL | +| Heiman | HS2AQ-EM | Battery, Temperature, Humidity | Standard ZCL | +| Heiman | HS2ESK-E | | Standard ZCL | +| Heiman | HS2FD-EF1-3.0 | Motion | Standard ZCL | +| Heiman | HS2RNL | Battery | Standard ZCL | +| Heiman | HS2SA-1 | Smoke, Battery | Tuya | +| Heiman | HS2SA-EF-3.0 | Smoke, Battery | Standard ZCL | +| Heiman | HS2SK | | Standard ZCL | +| Heiman | HS2SK_nxp | | Standard ZCL | +| Heiman | HS2SW1A/HS2SW1A-N | Device Temp | Standard ZCL | +| Heiman | HS2SW2A/HS2SW2A-N | Device Temp | Standard ZCL | +| Heiman | HS2SW3A/HS2SW3A-N | Device Temp | Standard ZCL | +| Heiman | HS2WDS | | Standard ZCL | +| Heiman | HS2WDSC-E | Battery | Standard ZCL | +| Heiman | HS2WDSR-E | Battery | Standard ZCL | +| Heiman | HS2WL | Water, Temperature, Battery | Standard ZCL | +| Heiman | HS3AQ | Battery, Humidity, Temperature | Standard ZCL | +| Heiman | HS3CG | Gas | Standard ZCL | +| Heiman | HS3DS | Contact, Battery | Standard ZCL | +| Heiman | HS3HT | Battery, Temperature, Humidity | Standard ZCL | +| Heiman | HS3MS | Motion | Standard ZCL | +| Heiman | HS3SA/HS1SA | Smoke, Battery | Standard ZCL | +| Heiman | HS8DS-EFA | Contact, Battery | Standard ZCL | +| Heiman | HS8MIS-EF1-3.0 | Motion | Standard ZCL | +| Heiman | HS8MLS-EF1-3.0 | Motion | Standard ZCL | +| Heiman | HS8OS-EF1-3.0 | Motion | Standard ZCL | +| Heiman | HS9MS-E | Motion, Battery | Standard ZCL | +| Heiman | Heiman-M1 | Contact | Standard ZCL | +| Heiman | M1-PE | Motion, Battery, Illuminance, Temperature, Humidity | Standard ZCL | +| Heiman | PIR_TPV12 | Motion, Battery | Standard ZCL | +| Heimgard Technologies | HC-BPW4-1 | Battery | Standard ZCL | +| Heimgard Technologies | HC-IWDIM-1 | | Standard ZCL | +| Heimgard Technologies | HC-IWSWI-1 | | Standard ZCL | +| Heimgard Technologies | HC-SLM-1 | Battery | Standard ZCL | +| Heimgard Technologies | HT-DWM-2 | Contact, Battery | Standard ZCL | +| Heimgard Technologies | HT-MOT-2 | Motion, Battery | Standard ZCL | +| Heimgard Technologies | HT-SLM-2 | Battery | Standard ZCL | +| Heimgard Technologies | HT-SLM-3 | Battery | Standard ZCL | +| Heimgard Technologies | HT-SMO-2 | Smoke, Battery | Standard ZCL | +| Hej | GLSK3ZB-1711 | | Standard ZCL | +| Hej | GLSK3ZB-1712 | | Standard ZCL | +| Hej | GLSK3ZB-1713 | | Standard ZCL | +| Hej | GLSK6ZB-1714 | | Standard ZCL | +| Hej | GLSK6ZB-1715 | | Standard ZCL | +| Hej | GLSK6ZB-1716 | | Standard ZCL | +| Hej | KKZ-DO021 | Contact, Battery | Standard ZCL | +| Hej | KKZ-MO021 | Motion, Battery | Standard ZCL | +| Hilux | D160-ZG | | Standard ZCL | +| Hilux | DZ8 | | Standard ZCL | +| Hive | 1613V | | Standard ZCL | +| Hive | DWS003 | Contact, Temperature, Battery | Standard ZCL | +| Hive | FWGU10Bulb02UK | | Standard ZCL | +| Hive | FWGU10Bulb03UK | | Standard ZCL | +| Hive | HALIGHTDIMWWB22 | | Standard ZCL | +| Hive | HALIGHTDIMWWE14 | | Standard ZCL | +| Hive | HALIGHTDIMWWE27 | | Standard ZCL | +| Hive | HV-CE14CXZB6 | | Standard ZCL | +| Hive | HV-GSCXZB229B | | Standard ZCL | +| Hive | HV-GSCXZB269 | | Standard ZCL | +| Hive | HV-GSCXZB279_HV-GSCXZB229_HV-GSCXZB229K | | Standard ZCL | +| Hive | HV-GUCXZB5 | | Standard ZCL | +| Hive | KEYPAD001 | Motion, Battery, Contact | Standard ZCL | +| Hive | MOT003 | Motion, Temperature, Battery | Standard ZCL | +| Hive | SLT6b | Battery, Temperature | Standard ZCL | +| Homcloud | HY-SZLUMPIR | Motion, Illuminance, Battery | Tuya | +| HomeSeer | DS150ZB | Contact, Battery | Standard ZCL | +| Hommyn | MS-20-Z | Motion, Battery | Standard ZCL | +| Hommyn | WS-20-Z | Water | Standard ZCL | +| Honyar | U2-86K11ND10-ZD | | Standard ZCL | +| Honyar | U2-86K21ND10-ZD | | Standard ZCL | +| Honyar | U2-86K31ND10-ZD | | Standard ZCL | +| Honyar | U86K31ND6 | | Standard ZCL | +| Honyar | U86Z13A16-ZJH(HA) | | Standard ZCL | +| Honyar | U86Z223A10-ZJU01(GD) | | Standard ZCL | +| IKEA | 90504044 | | Standard ZCL | +| IKEA | E1524/E1810 | Battery | Standard ZCL | +| IKEA | E1525/E1745 | Motion, Battery | Standard ZCL | +| IKEA | E160x/E170x/E190x | | Standard ZCL | +| IKEA | E1743 | Battery | Standard ZCL | +| IKEA | E1744 | Battery | Standard ZCL | +| IKEA | E1812 | Battery | Standard ZCL | +| IKEA | E1836 | | Standard ZCL | +| IKEA | E1841 | Battery | Standard ZCL | +| IKEA | E1842 | Water | Standard ZCL | +| IKEA | E2001/E2002/E2313 | Battery | Standard ZCL | +| IKEA | E2007 | | Standard ZCL | +| IKEA | E2013 | Contact, Battery | Standard ZCL | +| IKEA | E2112 | Temperature, Humidity | Standard ZCL | +| IKEA | E2123 | Battery | Standard ZCL | +| IKEA | E2134 | Motion, Illuminance, Battery | Standard ZCL | +| IKEA | E2201 | Battery | Standard ZCL | +| IKEA | E2202 | Water, Battery | Standard ZCL | +| IKEA | E22x4 | | Standard ZCL | +| IKEA | E22xx | | Standard ZCL | +| IKEA | E2435/E2491 | | Standard ZCL | +| IKEA | E2489 | Battery | Standard ZCL | +| IKEA | E2490 | Battery | Standard ZCL | +| IKEA | E2499 | | Standard ZCL | +| IKEA | G2015 | | Standard ZCL | +| IKEA | ICPSHC24-10EU-IL-1/ICPSHC24-10EU-IL-2 | | Standard ZCL | +| IKEA | ICPSHC24-30-IL44-1 | | Standard ZCL | +| IKEA | ICPSHC24-30EU-IL-1/ICPSHC24-10EU-IL-2 | | Standard ZCL | +| IKEA | ICTC-G-1 | Battery | Standard ZCL | +| IKEA | KAJPLATS_CWS | | Standard ZCL | +| IKEA | KAJPLATS_WS | | Standard ZCL | +| IKEA | KAJPLATS_WS_clear | | Standard ZCL | +| IKEA | L1527 | | Standard ZCL | +| IKEA | L1528 | | Standard ZCL | +| IKEA | L1529 | | Standard ZCL | +| IKEA | L1530 | | Standard ZCL | +| IKEA | L1531 | | Standard ZCL | +| IKEA | L2112 | | Standard ZCL | +| IKEA | L2205 | | Standard ZCL | +| IKEA | L2206 | | Standard ZCL | +| IKEA | L2207 | | Standard ZCL | +| IKEA | L2208 | | Standard ZCL | +| IKEA | LED1536G5 | | Standard ZCL | +| IKEA | LED1537R6/LED1739R5 | | Standard ZCL | +| IKEA | LED1545G12 | | Standard ZCL | +| IKEA | LED1546G12 | | Standard ZCL | +| IKEA | LED1622G12 | | Standard ZCL | +| IKEA | LED1623G12 | | Standard ZCL | +| IKEA | LED1624G9 | | Standard ZCL | +| IKEA | LED1649C5 | | Standard ZCL | +| IKEA | LED1650R5 | | Standard ZCL | +| IKEA | LED1732G11 | | Standard ZCL | +| IKEA | LED1733G7 | | Standard ZCL | +| IKEA | LED1736G9 | | Standard ZCL | +| IKEA | LED1738G7 | | Standard ZCL | +| IKEA | LED1835C6 | | Standard ZCL | +| IKEA | LED1836G9 | | Standard ZCL | +| IKEA | LED1837R5 | | Standard ZCL | +| IKEA | LED1842G3 | | Standard ZCL | +| IKEA | LED1923R5 | | Standard ZCL | +| IKEA | LED1924G9 | | Standard ZCL | +| IKEA | LED1925G6 | | Standard ZCL | +| IKEA | LED1934G3 | | Standard ZCL | +| IKEA | LED1935C3 | | Standard ZCL | +| IKEA | LED1936G5 | | Standard ZCL | +| IKEA | LED1937T5 | | Standard ZCL | +| IKEA | LED1949C5 | | Standard ZCL | +| IKEA | LED2002G5 | | Standard ZCL | +| IKEA | LED2003G10 | | Standard ZCL | +| IKEA | LED2004G8 | | Standard ZCL | +| IKEA | LED2005R5/LED2106R3 | | Standard ZCL | +| IKEA | LED2006R9 | | Standard ZCL | +| IKEA | LED2008G3 | | Standard ZCL | +| IKEA | LED2009C3 | | Standard ZCL | +| IKEA | LED2035G10 | | Standard ZCL | +| IKEA | LED2101G4 | | Standard ZCL | +| IKEA | LED2102G3 | | Standard ZCL | +| IKEA | LED2103G5 | | Standard ZCL | +| IKEA | LED2104R3 | | Standard ZCL | +| IKEA | LED2107C4 | | Standard ZCL | +| IKEA | LED2109G6 | | Standard ZCL | +| IKEA | LED2110R3 | | Standard ZCL | +| IKEA | LED2111G6 | | Standard ZCL | +| IKEA | LED2201G8 | | Standard ZCL | +| IKEA | T1820 | | Standard ZCL | +| IKEA | T1828 | | Standard ZCL | +| IKEA | T1829 | | Standard ZCL | +| IKEA | T2011 | | Standard ZCL | +| IKEA | T2030 | | Standard ZCL | +| IKEA | T2035 | | Standard ZCL | +| IKEA | T2037 | | Standard ZCL | +| IKEA | T2105 | | Standard ZCL | +| IKEA | T2106 | | Standard ZCL | +| IMOU | ZP1-EN | Motion, Battery | Standard ZCL | +| IMOU | ZTM1-EN | Battery, Temperature, Humidity | Standard ZCL | +| IOTPerfect | PF-PM02D-TYZ | | Standard ZCL | +| IT Commander | ITCMDR_Click | Battery | Standard ZCL | +| IT Commander | ITCMDR_Contact | Contact, Battery | Standard ZCL | +| Idinio | 0140302 | | Standard ZCL | +| Iluminize | 511.000 | | Standard ZCL | +| Iluminize | 511.010 | | Standard ZCL | +| Iluminize | 511.012 | | Standard ZCL | +| Iluminize | 511.020 | | Standard ZCL | +| Iluminize | 511.040 | | Standard ZCL | +| Iluminize | 511.050 | | Standard ZCL | +| Iluminize | 511.10 | | Standard ZCL | +| Iluminize | 511.201 | | Standard ZCL | +| Iluminize | 511.202 | | Standard ZCL | +| Iluminize | 511.324 | Battery | Standard ZCL | +| Iluminize | 511.524 | | Standard ZCL | +| Iluminize | 511.541 | | Standard ZCL | +| Iluminize | 511.544 | | Standard ZCL | +| Iluminize | 511.557 | | Standard ZCL | +| Iluminize | 5110.40 | | Standard ZCL | +| Iluminize | 5112.80 | | Standard ZCL | +| Iluminize | 5120.1100 | | Standard ZCL | +| Iluminize | 5120.1110 | | Standard ZCL | +| Iluminize | 5120.1200 | | Standard ZCL | +| Iluminize | 5120.1210 | | Standard ZCL | +| Iluminize | 5120.2110 | | Standard ZCL | +| Iluminize | 5120.2210 | | Standard ZCL | +| Iluminize | 5121.10 | | Standard ZCL | +| Iluminize | 5123.1110 | | Standard ZCL | +| Iluminize | 5144.01 | Battery | Standard ZCL | +| Iluminize | 5144.11 | Battery | Standard ZCL | +| Iluminize | 5144.21 | Battery | Standard ZCL | +| Iluminize | 5715 | | Standard ZCL | +| Iluminize | 5717 | | Standard ZCL | +| Imhotep Creation | E-Ctrl | Motion | Standard ZCL | +| Immax | 07001L/07005B | | Standard ZCL | +| Immax | 07004D/07005L | | Standard ZCL | +| Immax | 07008L | | Standard ZCL | +| Immax | 07042L | | Standard ZCL | +| Immax | 07043M | Motion, Battery | Standard ZCL | +| Immax | 07045L | Contact | Standard ZCL | +| Immax | 07047L | Motion, Battery, Temperature, Humidity, Illuminance | Standard ZCL | +| Immax | 07048L | | Standard ZCL | +| Immax | 07073L | | Standard ZCL | +| Immax | 07088L | | Standard ZCL | +| Immax | 07089L | | Standard ZCL | +| Immax | 07115L | | Standard ZCL | +| Immax | 07502L | Motion, Battery, Temperature, Humidity, Illuminance | Standard ZCL | +| Immax | 07703L | | Standard ZCL | +| Immax | 07743L | | Standard ZCL | +| Immax | 07752L | | Standard ZCL | +| Immax | TS0502C | | Standard ZCL | +| Innr | AE 260 | | Standard ZCL | +| Innr | AE 262 | | Standard ZCL | +| Innr | AE 264 | | Standard ZCL | +| Innr | AE 270 T | | Standard ZCL | +| Innr | AE 270 T-2 | | Standard ZCL | +| Innr | AE 280 C | | Standard ZCL | +| Innr | AE 282 C | | Standard ZCL | +| Innr | AE 287 C | | Standard ZCL | +| Innr | BB 262 | | Standard ZCL | +| Innr | BB 282 C | | Standard ZCL | +| Innr | BB 287 C | | Standard ZCL | +| Innr | BB 287 C-2 | | Standard ZCL | +| Innr | BE 220 | | Standard ZCL | +| Innr | BF 263 | | Standard ZCL | +| Innr | BF 265 | | Standard ZCL | +| Innr | BY 165 | | Standard ZCL | +| Innr | BY 178 T | | Standard ZCL | +| Innr | BY 185 C | | Standard ZCL | +| Innr | BY 266 | | Standard ZCL | +| Innr | BY 285 C | | Standard ZCL | +| Innr | BY 286 C | | Standard ZCL | +| Innr | DL 110 N | | Standard ZCL | +| Innr | DL 110 W | | Standard ZCL | +| Innr | FL 120 C | | Standard ZCL | +| Innr | FL 122 C | | Standard ZCL | +| Innr | FL 130 C | | Standard ZCL | +| Innr | FL 140 C | | Standard ZCL | +| Innr | FL 142 C | | Standard ZCL | +| Innr | FL 230 C | | Standard ZCL | +| Innr | FL 250 C | | Standard ZCL | +| Innr | OFL 120 C | | Standard ZCL | +| Innr | OFL 122 C | | Standard ZCL | +| Innr | OFL 140 C | | Standard ZCL | +| Innr | OFL 142 C | | Standard ZCL | +| Innr | OGL 130 C | | Standard ZCL | +| Innr | OLS 210 | | Standard ZCL | +| Innr | OPL 130 C | | Standard ZCL | +| Innr | OSL 130 C | | Standard ZCL | +| Innr | OSL 132 C | | Standard ZCL | +| Innr | OSL 140 C | | Standard ZCL | +| Innr | OSL 232 C | | Standard ZCL | +| Innr | OSP 210 | | Standard ZCL | +| Innr | OSP 240 | | Standard ZCL | +| Innr | PL 110 | | Standard ZCL | +| Innr | PL 115 | | Standard ZCL | +| Innr | RB 145 | | Standard ZCL | +| Innr | RB 148 T | | Standard ZCL | +| Innr | RB 162 | | Standard ZCL | +| Innr | RB 165 | | Standard ZCL | +| Innr | RB 172 W | | Standard ZCL | +| Innr | RB 175 W | | Standard ZCL | +| Innr | RB 178 T | | Standard ZCL | +| Innr | RB 185 C | | Standard ZCL | +| Innr | RB 243 | | Standard ZCL | +| Innr | RB 245 | | Standard ZCL | +| Innr | RB 246 T | | Standard ZCL | +| Innr | RB 247 T | | Standard ZCL | +| Innr | RB 248 T | | Standard ZCL | +| Innr | RB 249 T | | Standard ZCL | +| Innr | RB 250 C | | Standard ZCL | +| Innr | RB 251 C | | Standard ZCL | +| Innr | RB 252 C | | Standard ZCL | +| Innr | RB 255 C | | Standard ZCL | +| Innr | RB 256 C | | Standard ZCL | +| Innr | RB 262 | | Standard ZCL | +| Innr | RB 265 | | Standard ZCL | +| Innr | RB 266 | | Standard ZCL | +| Innr | RB 267 | | Standard ZCL | +| Innr | RB 272 T | | Standard ZCL | +| Innr | RB 278 T | | Standard ZCL | +| Innr | RB 279 T | | Standard ZCL | +| Innr | RB 282 C | | Standard ZCL | +| Innr | RB 285 C | | Standard ZCL | +| Innr | RB 286 C | | Standard ZCL | +| Innr | RB 287 C | | Standard ZCL | +| Innr | RC 110 | | Standard ZCL | +| Innr | RC 210 | Battery | Standard ZCL | +| Innr | RC 250 | Battery | Standard ZCL | +| Innr | RCL 110 | | Standard ZCL | +| Innr | RCL 231 T | | Standard ZCL | +| Innr | RCL 232 C | | Standard ZCL | +| Innr | RCL 240 T | | Standard ZCL | +| Innr | RCL 241 T | | Standard ZCL | +| Innr | RCL 242 C | | Standard ZCL | +| Innr | RF 261 | | Standard ZCL | +| Innr | RF 262 | | Standard ZCL | +| Innr | RF 263 | | Standard ZCL | +| Innr | RF 264 | | Standard ZCL | +| Innr | RF 265 | | Standard ZCL | +| Innr | RF 271 T | | Standard ZCL | +| Innr | RF 273 T | | Standard ZCL | +| Innr | RF 274 T | | Standard ZCL | +| Innr | RS 122 | | Standard ZCL | +| Innr | RS 125 | | Standard ZCL | +| Innr | RS 128 T | | Standard ZCL | +| Innr | RS 225 | | Standard ZCL | +| Innr | RS 226 | | Standard ZCL | +| Innr | RS 227 T | | Standard ZCL | +| Innr | RS 228 T | | Standard ZCL | +| Innr | RS 229 T | | Standard ZCL | +| Innr | RS 230 C | | Standard ZCL | +| Innr | RS 232 C | | Standard ZCL | +| Innr | RS 240 | | Standard ZCL | +| Innr | RS 241 T | | Standard ZCL | +| Innr | RS 242 C | | Standard ZCL | +| Innr | RSL 110 | | Standard ZCL | +| Innr | RSL 115 | | Standard ZCL | +| Innr | SL 110 M | | Standard ZCL | +| Innr | SL 110 N | | Standard ZCL | +| Innr | SL 110 W | | Standard ZCL | +| Innr | SP 110 | | Standard ZCL | +| Innr | SP 120 | | Standard ZCL | +| Innr | SP 220 | | Standard ZCL | +| Innr | SP 222 | | Standard ZCL | +| Innr | SP 224 | | Standard ZCL | +| Innr | SP 234 | | Standard ZCL | +| Innr | SP 240 | | Standard ZCL | +| Innr | ST 110 | | Standard ZCL | +| Innr | UC 110 | | Standard ZCL | +| Inovelli | VZM30-SN | Temperature, Humidity | Standard ZCL | +| Inovelli | VZM31-SN | | Standard ZCL | +| Inovelli | VZM32-SN | Motion, Illuminance | Standard ZCL | +| Inovelli | VZM36 | | Standard ZCL | +| Insta | 57004000 | | Standard ZCL | +| Insta | 57005000 | | Standard ZCL | +| Insta | InstaRemote | | Standard ZCL | +| Intuis | intuisradiator | Motion | Standard ZCL | +| Iolloi | ID-UK21FW09 | | Standard ZCL | +| Iris | 27087-03 | Battery | Standard ZCL | +| Iris | 3210-L | | Standard ZCL | +| Iris | 3315-L | Water, Temperature, Battery | Standard ZCL | +| Iris | 3320-L | Contact, Temperature, Battery | Standard ZCL | +| Iris | 3326-L | Motion, Temperature, Battery | Standard ZCL | +| Iris | 3450-L | Motion, Battery | Standard ZCL | +| Iris | 3460-L | Battery, Temperature | Standard ZCL | +| Iris | IL06_1 | Contact, Temperature, Battery | Standard ZCL | +| Iris | iL03_1 | | Standard ZCL | +| Iris | iL07_1 | Motion, Temperature, Humidity, Battery | Standard ZCL | +| J.XUAN | DSZ01 | Contact, Battery | Standard ZCL | +| J.XUAN | PRZ01 | Motion, Battery | Standard ZCL | +| J.XUAN | SPZ01 | | Standard ZCL | +| JAVIS | JS-MC-SENSOR-ZB | Motion, Illuminance | Standard ZCL | +| JIAWEN | JW-A04-CT | | Standard ZCL | +| JIAWEN | K2RGBW01 | | Standard ZCL | +| JUMITECH APS | J2182548 | | Standard ZCL | +| Jasco | 43132 | | Standard ZCL | +| Jasco Products | 43095 | | Standard ZCL | +| Jasco Products | ZB3102 | | Standard ZCL | +| KAMI | N20 | Contact | Standard ZCL | +| KMPCIL | KMPCIL-tag-001 | Motion, Battery, Vibration, Temperature | Standard ZCL | +| KMPCIL | KMPCIL_RES005 | Motion, Battery, Temperature, Humidity, Pressure, Illuminance | Standard ZCL | +| KURVIA | ZB-CL01 | | Standard ZCL | +| Keen Home | RS-THP-MP-1.0 | Battery, Temperature, Humidity, Pressure | Standard ZCL | +| Keen Home | SV01 | Temperature, Battery, Pressure | Standard ZCL | +| Keen Home | SV02 | Temperature, Battery, Pressure | Standard ZCL | +| KlikAanKlikUit | ZCC-250 | | Standard ZCL | +| KlikAanKlikUit | ZCC-3500 | | Standard ZCL | +| KlikAanKlikUit | ZCM-1800 | | Standard ZCL | +| Konke | 2AJZ4KPBS | Motion, Battery | Standard ZCL | +| Konke | 2AJZ4KPDR | Contact, Battery | Standard ZCL | +| Konke | 2AJZ4KPFT | Temperature, Humidity, Battery | Standard ZCL | +| Konke | KK-BS-J01W | Motion, Battery | Standard ZCL | +| Konke | KK-DS-J01W | Contact, Battery | Standard ZCL | +| Konke | KK-ES-J01W | Battery, Humidity, Temperature, Illuminance | Standard ZCL | +| Konke | KK-LP-Q01D | | Standard ZCL | +| Konke | KK-LP-Q02D | | Standard ZCL | +| Konke | KK-LP-Q03D | | Standard ZCL | +| Konke | KK-QD-Y01w | | Standard ZCL | +| Konke | KK-WA-J01W | Water, Battery | Standard ZCL | +| Konke | LH07321 | Water | Standard ZCL | +| Konke | TW-S1 | Smoke | Standard ZCL | +| Ksentry Electronics | KS-SM001 | | Standard ZCL | +| Kwikset | 66492-001 | Battery | Standard ZCL | +| Kwikset | 99100-006 | Battery | Standard ZCL | +| Kwikset | 99100-045 | Battery | Standard ZCL | +| Kwikset | 99120-021 | Battery | Standard ZCL | +| Kwikset | 99140-002 | Battery | Standard ZCL | +| Kwikset | 99140-031 | Battery | Standard ZCL | +| Kwikset | 99140-139 | Battery | Standard ZCL | +| L&S Lighting | 756200027 | | Standard ZCL | +| L&S Lighting | 756200030 | | Standard ZCL | +| L&S Lighting | 756200643 | | Standard ZCL | +| L&S Lighting | A319463 | | Standard ZCL | +| LDS | FWBulb03UK | | Standard ZCL | +| LDS | PFMOT001 | Motion, Battery | Standard ZCL | +| LDS | ZBT-RGBWLight-A0000 | | Standard ZCL | +| LED-Trading | 9134 | | Standard ZCL | +| LED-Trading | HK-LN-DIM-A | | Standard ZCL | +| LEDRON | QS-Zigbee-D04 | | Standard ZCL | +| LEDVANCE | 4058075168572 | | Standard ZCL | +| LEDVANCE | 4058075173989 | | Standard ZCL | +| LEDVANCE | 4058075181472 | | Standard ZCL | +| LEDVANCE | 4058075208339 | | Standard ZCL | +| LEDVANCE | 4058075208353 | | Standard ZCL | +| LEDVANCE | 4058075208360 | | Standard ZCL | +| LEDVANCE | 4058075208384 | | Standard ZCL | +| LEDVANCE | 4058075208391 | | Standard ZCL | +| LEDVANCE | 4058075208414 | | Standard ZCL | +| LEDVANCE | 4058075208421 | | Standard ZCL | +| LEDVANCE | 4058075364547 | | Standard ZCL | +| LEDVANCE | 4058075364561 | | Standard ZCL | +| LEDVANCE | 4058075485174 | | Standard ZCL | +| LEDVANCE | 4058075724587 | | Standard ZCL | +| LEDVANCE | 4058075728981 | | Standard ZCL | +| LEDVANCE | 4058075729001 | | Standard ZCL | +| LEDVANCE | 4058075729025 | | Standard ZCL | +| LEDVANCE | 4058075729049 | | Standard ZCL | +| LEDVANCE | 4058075729063 | | Standard ZCL | +| LEDVANCE | 4058075729087 | | Standard ZCL | +| LEDVANCE | 4058075729100 | | Standard ZCL | +| LEDVANCE | 4058075729124 | | Standard ZCL | +| LEDVANCE | 4058075729148 | | Standard ZCL | +| LEDVANCE | 4058075729162 | | Standard ZCL | +| LEDVANCE | 4058075729186 | | Standard ZCL | +| LEDVANCE | 4058075729209 | | Standard ZCL | +| LEDVANCE | 4058075729223 | | Standard ZCL | +| LEDVANCE | 4058075729247 | | Standard ZCL | +| LEDVANCE | 4058075729285 | | Standard ZCL | +| LEDVANCE | 4058075729308 | | Standard ZCL | +| LEDVANCE | 4058075729322 | | Standard ZCL | +| LEDVANCE | 4058075729346 | | Standard ZCL | +| LEDVANCE | 4058075729360 | | Standard ZCL | +| LEDVANCE | 4058075729384 | | Standard ZCL | +| LEDVANCE | 4058075823976 | | Standard ZCL | +| LEDVANCE | 4058075824010 | | Standard ZCL | +| LEDVANCE | 4099854293276 | | Standard ZCL | +| LEDVANCE | 4099854295232 | | Standard ZCL | +| LEDVANCE | 4099854513718 | | Standard ZCL | +| LEDVANCE | 74746 | | Standard ZCL | +| LEDVANCE | AC08560 | | Standard ZCL | +| LEDVANCE | AC23684 | | Standard ZCL | +| LEDVANCE | AC25697 | | Standard ZCL | +| LEDVANCE | AC25702 | | Standard ZCL | +| LEDVANCE | AC25704 | | Standard ZCL | +| LEDVANCE | AC26940/AC31266 | | Standard ZCL | +| LEDVANCE | AC33901 | | Standard ZCL | +| LEDVANCE | AC33903 | | Standard ZCL | +| LEDVANCE | AC33905 | | Standard ZCL | +| LEDVANCE | AC33906 | | Standard ZCL | +| LEDVANCE | GPDRPLOP401100CE | | Standard ZCL | +| LEDVANCE | SMARTZBA60RGBW | | Standard ZCL | +| LEDVANCE | ST8EM-CON | | Standard ZCL | +| LELLKI | CM001 | | Standard ZCL | +| LELLKI | JZ-ZB-001 | | Standard ZCL | +| LELLKI | JZ-ZB-002 | | Standard ZCL | +| LELLKI | JZ-ZB-003 | | Standard ZCL | +| LELLKI | WK34-EU | | Standard ZCL | +| LELLKI | WP30-EU | | Standard ZCL | +| LELLKI | WP33-EU/WP34-EU | | Standard ZCL | +| LELLKI | XF-EU-S100-1-M | | Standard ZCL | +| LG Electronics | B1027EB0Z01 | | Standard ZCL | +| LG Electronics | B1027EB0Z02 | | Standard ZCL | +| LG Electronics | B1027EB4Z01 | | Standard ZCL | +| Lanesto | 322054 | | Standard ZCL | +| LeapMMW | MTD085-ZB | Motion, Illuminance | Tuya | +| Leedarson | 5AA-SS-ZA-H0 | Motion, Illuminance | Standard ZCL | +| Leedarson | 6xy-M350ST-W1Z | | Standard ZCL | +| Leedarson | 7A-SS-ZABC-H0 | Motion, Battery, Temperature, Humidity, Illuminance | Standard ZCL | +| Leedarson | 8A-SS-BA-H0 | Motion, Battery | Standard ZCL | +| Leedarson | A806S-Q1G | | Standard ZCL | +| Leedarson | A806S-Q1R | | Standard ZCL | +| Leedarson | LDHD2AZW | Contact, Temperature, Battery | Standard ZCL | +| Leedarson | M350STW1 | | Standard ZCL | +| Leedarson | ZA806SQ1TCF | | Standard ZCL | +| Leedarson | ZBT-CCTLight-Candle0904 | | Standard ZCL | +| Leedarson | ZBT-CCTLight-GLS0904 | | Standard ZCL | +| Leedarson | ZBT-DIMLight-GLS0800 | | Standard ZCL | +| Leedarson | ZM350STW1TCF | | Standard ZCL | +| Legrand | 064873 | Battery | Standard ZCL | +| Legrand | 064882 | | Standard ZCL | +| Legrand | 064888 | | Standard ZCL | +| Legrand | 067694 | Battery | Standard ZCL | +| Legrand | 067755 | Battery | Standard ZCL | +| Legrand | 067766 | | Standard ZCL | +| Legrand | 067767 | Battery | Standard ZCL | +| Legrand | 067771 | | Standard ZCL | +| Legrand | 067772 | | Standard ZCL | +| Legrand | 067773 | Battery | Standard ZCL | +| Legrand | 067774 | Battery | Standard ZCL | +| Legrand | 067775/741811 | | Standard ZCL | +| Legrand | 067797 | | Standard ZCL | +| Legrand | 199182 | | Standard ZCL | +| Legrand | 281506 | | Standard ZCL | +| Legrand | 412015 | | Standard ZCL | +| Legrand | 412170 | | Standard ZCL | +| Legrand | 412171 | | Standard ZCL | +| Legrand | 412173 | | Standard ZCL | +| Legrand | 412175 | | Standard ZCL | +| Legrand | 752189 | Battery | Standard ZCL | +| Legrand | WNAL10/WNRL10 | | Standard ZCL | +| Legrand | WNAL50/WNRL50 | | Standard ZCL | +| Legrand | WNAL63 | Battery | Standard ZCL | +| Legrand | WNRR15/WNRR20 | | Standard ZCL | +| Letsleds | HLC929-Z-RGBW-4C-IA-OTA-3.0 | | Standard ZCL | +| Leviton | DG15A-1BW | | Standard ZCL | +| Leviton | DG15S-1BW | | Standard ZCL | +| Leviton | DG3HL-1BW | | Standard ZCL | +| Leviton | DG6HD-1BW | | Standard ZCL | +| Leviton | DL15S-1BZ | | Standard ZCL | +| Leviton | ZS057-D0Z | | Standard ZCL | +| LiXee | ZiPulses | Battery, Temperature | Standard ZCL | +| Lidl | 14153806L | | Standard ZCL | +| Lidl | FB20-002 | | Standard ZCL | +| Lidl | FB21-001 | | Standard ZCL | +| Lidl | HG06335/HG07310 | Motion, Battery | Standard ZCL | +| Lidl | HG06336 | Contact, Battery | Standard ZCL | +| Lidl | HG06337 | | Standard ZCL | +| Lidl | HG06338 | | Standard ZCL | +| Lidl | HG06467 | | Standard ZCL | +| Lidl | HG06619 | | Standard ZCL | +| Lidl | HG06620 | | Standard ZCL | +| Lidl | HG08164 | Battery | Standard ZCL | +| Lidl | HG08633 | | Standard ZCL | +| Lidl | HG08673 | | Standard ZCL | +| Lidl | PSBZS A1 | Battery | Tuya | +| LifeControl | MCLH-02 | | Standard ZCL | +| LifeControl | MCLH-03 | | Standard ZCL | +| LifeControl | MCLH-04 | Contact, Battery | Standard ZCL | +| LifeControl | MCLH-05 | Motion, Battery | Standard ZCL | +| LifeControl | MCLH-07 | Water, Battery | Standard ZCL | +| LifeControl | MCLH-08 | Temperature, Humidity, Battery | Standard ZCL | +| Light Solutions | 200106V3 | | Standard ZCL | +| Light Solutions | 200403V2-B | | Standard ZCL | +| Light Solutions | 3004482/3137308/3137309 | | Standard ZCL | +| Light Solutions | 42-032 | | Standard ZCL | +| Light Solutions | 91-943 | | Standard ZCL | +| Light Solutions | 91-943-PRO | | Standard ZCL | +| Light Solutions | 91-943-PRO-RGBCW | | Standard ZCL | +| Light Solutions | 91-947-micro | | Standard ZCL | +| Lincukoo | CZB01 | Battery | Standard ZCL | +| Lincukoo | CZF02 | Battery | Tuya | +| Lincukoo | E02C-Z10T | Temperature, Humidity, Battery | Tuya | +| Lincukoo | EZC04 | Temperature, Humidity | Tuya | +| Lincukoo | EZCP04 | Temperature, Humidity | Tuya | +| Lincukoo | R12LM-Z10T | Motion, Illuminance | Tuya | +| Lincukoo | R12LM-Z11T | Motion, Illuminance | Tuya | +| Lincukoo | SZLM04U | Motion, Illuminance, Battery | Tuya | +| Lincukoo | SZLMR10 | Motion, Illuminance | Tuya | +| Lincukoo | SZLR08 | Motion, Illuminance | Tuya | +| Lincukoo | SZLR08T | Motion, Illuminance | Tuya | +| Lincukoo | SZR07 | Motion, Illuminance | Tuya | +| Lincukoo | SZT04 | Temperature, Humidity, Battery | Tuya | +| Lincukoo | SZT06 | Temperature, Humidity, Battery | Standard ZCL | +| Linkind | LS21001 | Water, Battery | Standard ZCL | +| Linkind | ZL00030014 | | Standard ZCL | +| Linkind | ZL1000100-CCT-US-V1A02 | | Standard ZCL | +| Linkind | ZL100010008 | | Standard ZCL | +| Linkind | ZL1000400-CCT-EU-2-V1A02 | | Standard ZCL | +| Linkind | ZL100050004 | | Standard ZCL | +| Linkind | ZL1000700-22-EU-V1A02 | | Standard ZCL | +| Linkind | ZL1000701-27-EU-V1A02 | | Standard ZCL | +| Linkind | ZL13100314 | | Standard ZCL | +| Linkind | ZS1100400-IN-V1A02 | Motion, Battery | Standard ZCL | +| Linkind | ZS110050078 | Contact, Battery | Standard ZCL | +| Linkind | ZS130000078 | Motion, Battery | Standard ZCL | +| Linkind | ZS190000118 | | Standard ZCL | +| Linkind | ZS230002 | Battery | Standard ZCL | +| Linkind | ZS232000178 | Battery | Standard ZCL | +| LinknLink | eMotion Air | Motion, Temperature, Humidity, Illuminance, Battery | Standard ZCL | +| Linptech | ES1ZZ(TY) | Motion, Illuminance | Standard ZCL | +| LivingWise | LVS-SM10ZW | Contact | Standard ZCL | +| LivingWise | LVS-SN10ZW_SN11 | Motion, Battery | Standard ZCL | +| LivingWise | LVS-ZB15R | | Standard ZCL | +| LivingWise | LVS-ZB15S | | Standard ZCL | +| LivingWise | LVS-ZB500D | | Standard ZCL | +| Livolo | TI0001 | | Standard ZCL | +| Livolo | TI0001-cover | Motion | Standard ZCL | +| Livolo | TI0001-curtain-switch | | Standard ZCL | +| Livolo | TI0001-dimmer | | Standard ZCL | +| Livolo | TI0001-hygrometer | Humidity, Temperature | Standard ZCL | +| Livolo | TI0001-illuminance | Illuminance | Standard ZCL | +| Livolo | TI0001-pir | Motion | Standard ZCL | +| Livolo | TI0001-socket | | Standard ZCL | +| Livolo | TI0001-switch | | Standard ZCL | +| Livolo | TI0001-switch-2gang | | Standard ZCL | +| Lonsonho | 4000116784070 | | Standard ZCL | +| Lonsonho | QS-Zigbee-D02-TRIAC-2C-L | | Standard ZCL | +| Lonsonho | QS-Zigbee-D02-TRIAC-2C-LN | | Standard ZCL | +| Lonsonho | QS-Zigbee-D02-TRIAC-LN | | Standard ZCL | +| Lonsonho | QS-Zigbee-S04-2C-LN | | Standard ZCL | +| Lonsonho | QS-Zigbee-S05-LN | | Standard ZCL | +| Lonsonho | VM-Zigbee-S02-0-10V | | Standard ZCL | +| Lonsonho | X701A | | Standard ZCL | +| Lonsonho | X711A | | Standard ZCL | +| Lonsonho | X712A | | Standard ZCL | +| Lonsonho | X713A | | Standard ZCL | +| Lonsonho | ZB-RGBCW | | Standard ZCL | +| Lubeez | 12AB | | Standard ZCL | +| Lupus | 12050 | | Standard ZCL | +| Lupus | 12126 | | Standard ZCL | +| Lupus | 12127 | | Standard ZCL | +| Lutron | LZL4BWHL01 | | Standard ZCL | +| Lutron | Z3-1BRL | Battery | Standard ZCL | +| Lytko | L101Z-DBI | Temperature, Humidity | Standard ZCL | +| Lytko | L101Z-SBI | Temperature, Humidity | Standard ZCL | +| Lytko | L101Ze-DLM | | Standard ZCL | +| Lytko | L101Ze-SLM | | Standard ZCL | +| M-ELEC | ML-ST-BP-DIM | | Standard ZCL | +| M-ELEC | ML-ST-D200 | | Standard ZCL | +| M-ELEC | ML-ST-D200-NF | | Standard ZCL | +| M-ELEC | ML-ST-R200 | | Standard ZCL | +| MLI | 404078 | | Standard ZCL | +| MLI | 404114 | | Standard ZCL | +| MakeGood | MG-AUZG01 | | Standard ZCL | +| MakeGood | MG-GPO01 | | Standard ZCL | +| Matcall | ZG401224 | | Standard ZCL | +| Matcall | ZG430700 | | Standard ZCL | +| Meazon | MEAZON_BIZY_PLUG | | Standard ZCL | +| Meazon | MEAZON_DINRAIL | | Standard ZCL | +| Megaman | LC201060 | | Standard ZCL | +| Meian | GA01 | Gas | Tuya | +| Mercator Ikuü | SISWD11-ZB | | Standard ZCL | +| Mercator Ikuü | SMA02P | Motion, Battery | Standard ZCL | +| Mercator Ikuü | SMA03P | Battery, Temperature, Humidity | Standard ZCL | +| Mercator Ikuü | SMA04P | Contact, Battery | Standard ZCL | +| Mercator Ikuü | SMD4109W-RGB-ZB | | Standard ZCL | +| Mercator Ikuü | SPP02G | | Standard ZCL | +| Mercator Ikuü | SPP02GIP | | Standard ZCL | +| Mercator Ikuü | SPP04G | | Standard ZCL | +| Mercator Ikuü | SPPUSB02 | | Standard ZCL | +| Mercator Ikuü | SSW03G | | Standard ZCL | +| Mercator Ikuü | SSWF01G | | Standard ZCL | +| Merrytek | MSA201Z | Motion, Illuminance | Tuya | +| MiBoxer | FUT038Z | | Standard ZCL | +| MiaoMiaoCe | MHO-C122 | Temperature, Humidity, Battery | Standard ZCL | +| MiaoMiaoCe | MHO-C401 | Temperature, Humidity, Battery | Standard ZCL | +| Micro Matic Norge AS | ZB250 | | Standard ZCL | +| MindY | Leleka | Temperature, Humidity, Pressure, Illuminance | Standard ZCL | +| Modular | MWM002 | | Standard ZCL | +| Moes | ADCBZI01 | Battery, Illuminance | Tuya | +| Moes | BRT-100-TRV | Battery | Standard ZCL | +| Moes | ERS-10TZBVB-AA | Battery | Standard ZCL | +| Moes | MS-104BZ | | Standard ZCL | +| Moes | MS-104Z | | Standard ZCL | +| Moes | SFL02-Z-1 | | Standard ZCL | +| Moes | SFL02-Z-2 | | Standard ZCL | +| Moes | SFL02-Z-3 | | Standard ZCL | +| Moes | SFL02-Z-4 | | Standard ZCL | +| Moes | SR-ZS | | Standard ZCL | +| Moes | ZC-HM | Carbon Monoxide, Battery | Tuya | +| Moes | ZHT-PT01-M-MS | | Standard ZCL | +| Moes | ZK-EU-2U | | Standard ZCL | +| Moes | ZM6LT1 | | Tuya | +| Moes | ZP-LZ-FR2U | | Standard ZCL | +| Moes | ZS-D1 | | Standard ZCL | +| Moes | ZS-D2 | | Standard ZCL | +| Moes | ZS-D3 | | Standard ZCL | +| Moes | ZS-EUB_1gang | | Standard ZCL | +| Moes | ZSS-HM-SSD01 | Smoke, Battery | Tuya | +| Moes | ZSS-QT-LTH-C | Battery, Temperature, Humidity, Illuminance | Standard ZCL | +| Moes | ZSS-ZK-THL | Battery, Humidity, Temperature, Illuminance | Standard ZCL | +| Moes | ZTS-EU_1gang | | Standard ZCL | +| Moes | ZTS-EU_2gang | | Standard ZCL | +| Moes | ZTS-EU_3gang | | Standard ZCL | +| Moes | ZTS-EU_4gang | | Standard ZCL | +| Moes | ZWV-YC | Battery | Standard ZCL | +| MultIR | MIR-IR100 | Motion, Battery, Illuminance | Standard ZCL | +| MultIR | MIR-MC100 | Contact, Battery | Standard ZCL | +| MultIR | MIR-SM200 | Smoke, Battery | Standard ZCL | +| MultIR | MIR-TE600 | Battery, Temperature, Humidity | Standard ZCL | +| MultIR | MIR-WA100 | Water, Battery | Standard ZCL | +| Mumubiz | TYZGTH1CH-D1RF | Temperature, Humidity | Standard ZCL | +| Mumubiz | TYZGTH4CH-D1RF | Temperature, Humidity | Standard ZCL | +| MySmartHouse | msh.AirQMon | | Standard ZCL | +| MySmartHouse | msh.bme280psm | Battery, Temperature, Humidity, Pressure | Standard ZCL | +| MySmartHouse | msh.ds18b20psm | Battery, Temperature | Standard ZCL | +| MySmartHouse | msh.ina226 | | Standard ZCL | +| MySmartHouse | msh.ina226m | Temperature | Standard ZCL | +| MySmartHouse | msh.pzem | Temperature | Standard ZCL | +| Müller Licht | 404000/404005/404012/404019 | | Standard ZCL | +| Müller Licht | 404001 | | Standard ZCL | +| Müller Licht | 404002 | | Standard ZCL | +| Müller Licht | 404006/404008/404004 | | Standard ZCL | +| Müller Licht | 404017 | | Standard ZCL | +| Müller Licht | 404021 | | Standard ZCL | +| Müller Licht | 404022/404049C | | Standard ZCL | +| Müller Licht | 404023 | | Standard ZCL | +| Müller Licht | 404024 | | Standard ZCL | +| Müller Licht | 404028/44435 | | Standard ZCL | +| Müller Licht | 404031 | | Standard ZCL | +| Müller Licht | 404036/45327/45317/45328 | | Standard ZCL | +| Müller Licht | 404037/404038 | | Standard ZCL | +| Müller Licht | 404051 | | Standard ZCL | +| Müller Licht | 404062 | | Standard ZCL | +| Müller Licht | 404065 | | Standard ZCL | +| Müller Licht | 404122/404123 | | Standard ZCL | +| Müller Licht | 404127 | | Standard ZCL | +| Müller Licht | 4041xx | | Standard ZCL | +| Müller Licht | 44435 | | Standard ZCL | +| Müller Licht | 45391 | | Standard ZCL | +| Müller Licht | 45723 | | Standard ZCL | +| Müller Licht | 45727 | | Standard ZCL | +| Müller Licht | 45728 | | Standard ZCL | +| Müller Licht | 45730 | | Standard ZCL | +| Müller Licht | MDGARD401 | | Standard ZCL | +| Müller Licht | MLI-404011/MLI-404049 | | Standard ZCL | +| NEO | NAS-AB02B0 | Temperature, Humidity | Standard ZCL | +| NEO | NAS-PD07 | Motion, Humidity, Temperature | Standard ZCL | +| NEO | NAS-PS09B2 | Motion | Tuya | +| NEO | NAS-PS10B2 | Motion | Tuya | +| NEO | NAS-STH02B2 | Humidity, Temperature, Battery | Tuya | +| NEO | NAS-TH07B2 | Temperature, Humidity, Battery | Standard ZCL | +| NEO | NAS-WV03B | Battery | Tuya | +| NEO | NAS-WV03B2 | Battery | Tuya | +| NET2GRID | N2G-SP | | Standard ZCL | +| Namron | 1402755 | | Standard ZCL | +| Namron | 1402767 | | Standard ZCL | +| Namron | 1402768 | | Standard ZCL | +| Namron | 1402769 | | Standard ZCL | +| Namron | 1402790 | Battery, Temperature | Standard ZCL | +| Namron | 3308431 | | Standard ZCL | +| Namron | 3802960 | | Standard ZCL | +| Namron | 3802961 | | Standard ZCL | +| Namron | 3802962 | | Standard ZCL | +| Namron | 3802963 | | Standard ZCL | +| Namron | 3802964 | | Standard ZCL | +| Namron | 3802965 | | Standard ZCL | +| Namron | 3802966 | | Standard ZCL | +| Namron | 3802967 | | Standard ZCL | +| Namron | 3802968 | | Standard ZCL | +| Namron | 4512700 | | Standard ZCL | +| Namron | 4512701 | Battery | Standard ZCL | +| Namron | 4512702 | Battery | Standard ZCL | +| Namron | 4512703 | Battery | Standard ZCL | +| Namron | 4512704 | | Standard ZCL | +| Namron | 4512705 | Battery | Standard ZCL | +| Namron | 4512706 | Battery | Standard ZCL | +| Namron | 4512707 | | Standard ZCL | +| Namron | 4512708 | | Standard ZCL | +| Namron | 4512719 | Battery | Standard ZCL | +| Namron | 4512721 | Battery | Standard ZCL | +| Namron | 4512726 | Battery | Standard ZCL | +| Namron | 4512728 | Battery | Standard ZCL | +| Namron | 4512729 | Battery | Standard ZCL | +| Namron | 4512733 | | Standard ZCL | +| Namron | 4512735 | | Standard ZCL | +| Namron | 4512737/4512738 | | Standard ZCL | +| Namron | 4512739 | | Standard ZCL | +| Namron | 4512749 | Temperature | Standard ZCL | +| Namron | 4512749-N | Temperature | Standard ZCL | +| Namron | 4512750 | | Standard ZCL | +| Namron | 4512752/4512753 | | Tuya | +| Namron | 4512758 | | Standard ZCL | +| Namron | 4512760 | | Standard ZCL | +| Namron | 4512761 | | Standard ZCL | +| Namron | 4512762 | Contact, Battery | Standard ZCL | +| Namron | 4512763 | Motion | Standard ZCL | +| Namron | 4512764 | Water, Battery | Standard ZCL | +| Namron | 4512765 | Battery, Temperature, Humidity | Standard ZCL | +| Namron | 4512766 | | Standard ZCL | +| Namron | 4512767 | | Standard ZCL | +| Namron | 4512768 | | Standard ZCL | +| Namron | 4512770 | Motion, Battery, Temperature, Humidity, Illuminance | Standard ZCL | +| Namron | 4512773 | Battery | Standard ZCL | +| Namron | 4512776/4512777 | | Standard ZCL | +| Namron | 4512782 / 4512781 / 4566700 / 4566701 | | Standard ZCL | +| Namron | 4512785 | Device Temp | Standard ZCL | +| Namron | 4512788 | | Standard ZCL | +| Namron | 4512789 | Device Temp | Standard ZCL | +| Namron | 4512791 | | Standard ZCL | +| Namron | 4512792 | | Standard ZCL | +| Namron | 4566702 | Humidity | Standard ZCL | +| Namron | 540139X | | Standard ZCL | +| Namron | 89665 | | Standard ZCL | +| Nanoleaf | NL08-0800 | | Standard ZCL | +| Netica | FRZ1 | Temperature, Humidity | Standard ZCL | +| Netvox | Z809A | | Standard ZCL | +| Nexelec | Open'R | Temperature, Humidity, Battery | Standard ZCL | +| Niko | 170-33505/170-34605 | | Standard ZCL | +| Niko | 552-720X1 | Battery | Standard ZCL | +| Niko | 552-720X2 | Battery | Standard ZCL | +| Niko | 552-720X4 | Battery | Standard ZCL | +| Niko | 552-721X1 | | Standard ZCL | +| Niko | 552-721X2 | | Standard ZCL | +| Niko | 552-72201 | | Standard ZCL | +| Niko | 552-80401 | Motion, Battery | Standard ZCL | +| Niko | 552-80698 | | Standard ZCL | +| Niko | 552-80699 | | Standard ZCL | +| Ninja Blocks | Z809AF | | Standard ZCL | +| Niviss | PS-ZIGBEE-SMART-CONTROLER-1CH-DIMMABLE | | Standard ZCL | +| NoDieby | ND-01 | Motion | Standard ZCL | +| NodOn | FPS-4-1-00 | Temperature, Humidity | Standard ZCL | +| NodOn | IRB-4-1-00 | Humidity | Standard ZCL | +| NodOn | SDO-4-1-00 | Contact, Battery | Standard ZCL | +| NodOn | SEM-4-1-00 | | Standard ZCL | +| NodOn | SEM-4-3-20 | | Standard ZCL | +| NodOn | SIN-4-1-20 | | Standard ZCL | +| NodOn | SIN-4-1-20_PRO | | Standard ZCL | +| NodOn | SIN-4-1-21 | | Standard ZCL | +| NodOn | SIN-4-2-20 | | Standard ZCL | +| NodOn | SIN-4-2-20_PRO | | Standard ZCL | +| NodOn | SIN-4-FP-20 | | Standard ZCL | +| NodOn | SIN-4-FP-21 | | Standard ZCL | +| NodOn | STPH-4-1-00 | Battery, Temperature, Humidity | Standard ZCL | +| Nordtronic | 98423051 | | Standard ZCL | +| Nordtronic | 98424072 | | Standard ZCL | +| Nordtronic | 98425031 | | Standard ZCL | +| Nordtronic | 98425033 | | Standard ZCL | +| Nordtronic | 98425034 | | Standard ZCL | +| Nordtronic | 98425271 | | Standard ZCL | +| Nordtronic | 98426061 | Battery | Standard ZCL | +| Nous | A11Z | | Standard ZCL | +| Nous | D4Z | | Tuya | +| Nous | D5Z | Device Temp | Tuya | +| Nous | E12 | Carbon Monoxide | Tuya | +| Nous | E13 | Water, Battery | Tuya | +| Nous | E5 | Temperature, Humidity, Battery | Standard ZCL | +| Nous | E6 | Temperature, Humidity, Battery | Standard ZCL | +| Nous | E9 | Gas | Tuya | +| Nous | SZ-T04 | Temperature, Humidity, Battery | Standard ZCL | +| Nova Digital | FZB-1 | | Standard ZCL | +| Nova Digital | NFZB-03 | | Standard ZCL | +| Nova Digital | NFZB-2 | | Standard ZCL | +| Nova Digital | QZ-4x4-6 W/B | | Standard ZCL | +| Nova Digital | SA-4W | | Standard ZCL | +| Nova Digital | TO-6 W/B | | Standard ZCL | +| Nova Digital | TO-DM-W/B | | Standard ZCL | +| Nova Digital | TO-WK-1W/B | | Tuya | +| Nova Digital | TO-WK-2W/B | | Tuya | +| Nova Digital | ZVL-PRO | Battery | Tuya | +| Novato | ZIS-01P | Motion, Illuminance, Battery | Tuya | +| Novato | ZIS-03 | Motion, Illuminance | Tuya | +| Novato | ZPV-01 | Battery | Tuya | +| Novato | ZRM01 | | Standard ZCL | +| Novato | ZRM02 | | Standard ZCL | +| Novato | ZSN-03P | Temperature, Humidity | Tuya | +| Nue / 3A | 3A12S-15 | | Standard ZCL | +| Nue / 3A | HGZB-01 | | Standard ZCL | +| Nue / 3A | HGZB-01A | | Standard ZCL | +| Nue / 3A | HGZB-02A | | Standard ZCL | +| Nue / 3A | HGZB-02S | | Standard ZCL | +| Nue / 3A | HGZB-042 | | Standard ZCL | +| Nue / 3A | HGZB-043 | | Standard ZCL | +| Nue / 3A | HGZB-045 | | Standard ZCL | +| Nue / 3A | HGZB-04D / HGZB-4D-UK | | Standard ZCL | +| Nue / 3A | HGZB-06A | | Standard ZCL | +| Nue / 3A | HGZB-13A | Contact | Standard ZCL | +| Nue / 3A | HGZB-14A | Water, Battery | Standard ZCL | +| Nue / 3A | HGZB-1S | | Standard ZCL | +| Nue / 3A | HGZB-20-UK | | Standard ZCL | +| Nue / 3A | HGZB-20A | | Standard ZCL | +| Nue / 3A | HGZB-41 | | Standard ZCL | +| Nue / 3A | HGZB-42 | | Standard ZCL | +| Nue / 3A | HGZB-42-UK / HGZB-41 / HGZB-41-UK | | Standard ZCL | +| Nue / 3A | HGZB-43 | | Standard ZCL | +| Nue / 3A | HGZB-44 | | Standard ZCL | +| Nue / 3A | HGZB-4S | | Standard ZCL | +| Nue / 3A | HGZB-DLC4-N12B | | Standard ZCL | +| Nue / 3A | LXN56-TS27LX1.2 | | Standard ZCL | +| Nue / 3A | LXN59-2S7LX1.0 | | Standard ZCL | +| Nue / 3A | LXZB-02A | | Standard ZCL | +| Nue / 3A | MG-AUWS01 | | Standard ZCL | +| Nue / 3A | NUE-AUWZO2 | | Standard ZCL | +| Nue / 3A | NUE-ZBFLB | | Standard ZCL | +| Nue / 3A | WL-SD001-9W | | Standard ZCL | +| Nue / 3A | XY12S-15 | | Standard ZCL | +| Nue / 3A | ZW-EC-01 | | Standard ZCL | +| Nyce | NCZ-3010 | Contact, Battery | Standard ZCL | +| Nyce | NCZ-3011-HA | Contact, Battery | Standard ZCL | +| Nyce | NCZ-3014-HA | Contact, Battery | Standard ZCL | +| Nyce | NCZ-3041-HA | Motion, Humidity, Temperature, Battery | Standard ZCL | +| Nyce | NCZ-3043-HA | Motion, Humidity, Temperature, Battery | Standard ZCL | +| Nyce | NCZ-3045-HA | Motion, Humidity, Temperature, Battery | Standard ZCL | +| ONOKOM | AUX-1-ZB-S | | Standard ZCL | +| ONOKOM | DK-1-ZB-S | | Standard ZCL | +| ONOKOM | GR-3-ZB-S | | Standard ZCL | +| ONOKOM | HR-1-ZB-S | | Standard ZCL | +| ONOKOM | HS-3-ZB-S | | Standard ZCL | +| ONOKOM | HT-1-ZB-S | | Standard ZCL | +| ONOKOM | MD-1-ZB-S | | Standard ZCL | +| ONOKOM | MD-3-ZB-S | | Standard ZCL | +| ONOKOM | ME-1-ZB-S | | Standard ZCL | +| ONOKOM | OK-AC-H-AUX-1-ZB-S-A | | Standard ZCL | +| ONOKOM | OK-AC-H-DK-1-ZB-S-A | | Standard ZCL | +| ONOKOM | OK-AC-H-GR-1-ZB-S-A | | Standard ZCL | +| ONOKOM | OK-AC-H-HR-1-ZB-S-A | | Standard ZCL | +| ONOKOM | OK-AC-H-HS-3-ZB-S-A | | Standard ZCL | +| ONOKOM | OK-AC-H-HT-1-ZB-S-A | | Standard ZCL | +| ONOKOM | OK-AC-H-MD-1-ZB-S-A | | Standard ZCL | +| ONOKOM | OK-AC-H-MD-3-ZB-S-A | | Standard ZCL | +| ONOKOM | OK-AC-H-ME-1-ZB-S-A | | Standard ZCL | +| ONOKOM | OK-AC-H-TCL-1-ZB-S-A | | Standard ZCL | +| ONOKOM | OK-AC-H-TCL-3-ZB-S-A | | Standard ZCL | +| ONOKOM | TCL-1-ZB-S | | Standard ZCL | +| ONOKOM | TCL-3-ZB-S | | Standard ZCL | +| ORVIBO | CM10ZW | | Standard ZCL | +| ORVIBO | DD10Z | | Standard ZCL | +| ORVIBO | DM10ZW | | Standard ZCL | +| ORVIBO | DS20Z07B | | Standard ZCL | +| ORVIBO | DSZ12060 | | Standard ZCL | +| ORVIBO | DTZ09039 | | Standard ZCL | +| ORVIBO | OR-ZB-S010-3C | | Standard ZCL | +| ORVIBO | R11W2Z | | Standard ZCL | +| ORVIBO | R20W2Z | | Standard ZCL | +| ORVIBO | R30W3Z | | Standard ZCL | +| ORVIBO | RL804CZB | | Standard ZCL | +| ORVIBO | RL804QZB | | Standard ZCL | +| ORVIBO | SM10ZW | Contact, Battery | Standard ZCL | +| ORVIBO | SM20 | Contact, Battery | Standard ZCL | +| ORVIBO | SN10ZW | Motion, Battery | Standard ZCL | +| ORVIBO | ST20 | Humidity, Temperature, Battery | Standard ZCL | +| ORVIBO | ST21 | Temperature, Humidity, Battery | Standard ZCL | +| ORVIBO | ST30 | Battery, Humidity, Temperature | Standard ZCL | +| ORVIBO | SW21 | Water | Standard ZCL | +| ORVIBO | SW30 | Water | Standard ZCL | +| ORVIBO | T18W3Z | | Standard ZCL | +| ORVIBO | T21W1Z | | Standard ZCL | +| ORVIBO | T21W2Z | | Standard ZCL | +| ORVIBO | T30W3Z | | Standard ZCL | +| ORVIBO | T40W1Z | | Standard ZCL | +| ORVIBO | T40W2Z | | Standard ZCL | +| ORVIBO | T40W3Z_v1 | | Standard ZCL | +| ORVIBO | T40W3Z_v2 | | Standard ZCL | +| ORVIBO | T40W4Z | | Standard ZCL | +| ORVIBO | T41W1Z | | Standard ZCL | +| ORVIBO | T41W2Z | | Standard ZCL | +| OSRAM | 4052899926110 | | Standard ZCL | +| OSRAM | 4052899926127 | | Standard ZCL | +| OSRAM | 4052899926158 | | Standard ZCL | +| OSRAM | 4052899930377 | | Standard ZCL | +| OSRAM | 4058075036147 | | Standard ZCL | +| OSRAM | 4058075036185 | | Standard ZCL | +| OSRAM | 4058075047853 | | Standard ZCL | +| OSRAM | 4058075148338 | | Standard ZCL | +| OSRAM | 4058075816459 | Battery | Standard ZCL | +| OSRAM | 4058075816718 | | Standard ZCL | +| OSRAM | 4058075816732 | | Standard ZCL | +| OSRAM | 4058075816794 | | Standard ZCL | +| OSRAM | 4062172044776_1 | | Standard ZCL | +| OSRAM | 4062172044776_2 | | Standard ZCL | +| OSRAM | 4062172044776_3 | | Standard ZCL | +| OSRAM | 4062172044776_4 | | Standard ZCL | +| OSRAM | 4099854461767/4099854461774 | | Standard ZCL | +| OSRAM | 595UGR22 | | Standard ZCL | +| OSRAM | 71150 | | Standard ZCL | +| OSRAM | 73699 | | Standard ZCL | +| OSRAM | 73741_LIGHTIFY | | Standard ZCL | +| OSRAM | 73889 | | Standard ZCL | +| OSRAM | AA68199 | | Standard ZCL | +| OSRAM | AA69697 | | Standard ZCL | +| OSRAM | AA70155 | | Standard ZCL | +| OSRAM | AB3257001NJ | | Standard ZCL | +| OSRAM | AB32840 | | Standard ZCL | +| OSRAM | AB35996 | | Standard ZCL | +| OSRAM | AB390020055 | | Standard ZCL | +| OSRAM | AB401130055 | | Standard ZCL | +| OSRAM | AC01353010G | Motion, Temperature, Battery | Standard ZCL | +| OSRAM | AC0251100NJ/AC0251600NJ/AC0251700NJ | Battery | Standard ZCL | +| OSRAM | AC0363900NJ | | Standard ZCL | +| OSRAM | AC03641 | | Standard ZCL | +| OSRAM | AC03642 | | Standard ZCL | +| OSRAM | AC03645 | | Standard ZCL | +| OSRAM | AC03647 | | Standard ZCL | +| OSRAM | AC03648 | | Standard ZCL | +| OSRAM | AC08559 | | Standard ZCL | +| OSRAM | AC08560-DIM | | Standard ZCL | +| OSRAM | AC08562 | | Standard ZCL | +| OSRAM | AC10691 | | Standard ZCL | +| OSRAM | AC10786-DIM | | Standard ZCL | +| OSRAM | AC10787 | | Standard ZCL | +| OSRAM | AC16381 | | Standard ZCL | +| OSRAM | ST8AU-CON | | Standard ZCL | +| OWON | CB432 | | Standard ZCL | +| OWON | DWS312 | Contact, Battery | Standard ZCL | +| OWON | PC321 | | Standard ZCL | +| OWON | PCT504 | Motion, Humidity | Standard ZCL | +| OWON | PCT512 | Motion, Humidity | Standard ZCL | +| OWON | PIR313-E | Motion, Battery, Temperature, Humidity, Illuminance | Standard ZCL | +| OWON | PIR313-P | Motion, Battery | Standard ZCL | +| OWON | PIR323-PTH | Motion, Temperature, Humidity | Standard ZCL | +| OWON | SLC603 | Battery | Standard ZCL | +| OWON | SLC631 | Contact | Standard ZCL | +| OWON | SPM915 | Contact, Battery | Standard ZCL | +| OWON | THS317 | Battery, Temperature, Humidity | Standard ZCL | +| OWON | THS317-ET | Battery, Temperature | Standard ZCL | +| OWON | WSP402 | | Standard ZCL | +| OWON | WSP403 | | Standard ZCL | +| OWON | WSP404 | | Standard ZCL | +| Onesti Products AS | Nimly | Battery | Standard ZCL | +| Onesti Products AS | S4RX-110 | Device Temp | Standard ZCL | +| Onesti Products AS | easyCodeTouch_v1 | Battery | Standard ZCL | +| OpenLumi | GWRJN5169 | Device Temp | Standard ZCL | +| Orztech | \_TZE200_7a5ob7xq | | Standard ZCL | +| Orztech | \_TZE200_b0ihkhxh | | Standard ZCL | +| Orztech | \_TZE200_htj3hcpl | | Standard ZCL | +| Orztech | \_TZE200_pcg0rykt | | Standard ZCL | +| Orztech | \_TZE200_xo3vpoah | | Standard ZCL | +| Oujiabao | CR701-YZ | Carbon Monoxide, Gas | Standard ZCL | +| Ourtop | ATMS10013Z3 | | Tuya | +| Oz Smart Things | DL41-03-10-R-ZB | | Standard ZCL | +| PEQ | 3300-P | Contact, Temperature, Battery | Standard ZCL | +| PLAID SYSTEMS | PS-SPRZMS-SLP3 | Humidity, Temperature, Battery | Standard ZCL | +| Paul Neuhaus | 100.001.96 | | Standard ZCL | +| Paul Neuhaus | 100.075.74 | | Standard ZCL | +| Paul Neuhaus | 100.110.51 | | Standard ZCL | +| Paul Neuhaus | 100.425.90 | | Standard ZCL | +| Paul Neuhaus | 100.462.31 | | Standard ZCL | +| Paul Neuhaus | 100.491.61 | | Standard ZCL | +| Paul Neuhaus | E0040006 | | Standard ZCL | +| Paul Neuhaus | NLG-CCT light | | Standard ZCL | +| Paul Neuhaus | NLG-RGB-TW light | | Standard ZCL | +| Paul Neuhaus | NLG-RGBW\_\_light | | Standard ZCL | +| Paul Neuhaus | NLG-RGBW_light | | Standard ZCL | +| Paul Neuhaus | NLG-TW light | | Standard ZCL | +| Paulmann | 150257 | | Standard ZCL | +| Paulmann | 291.52 | | Standard ZCL | +| Paulmann | 371000001 | | Standard ZCL | +| Paulmann | 371000002 | | Standard ZCL | +| Paulmann | 371050043 | | Standard ZCL | +| Paulmann | 371222402 | | Standard ZCL | +| Paulmann | 371232040 | | Standard ZCL | +| Paulmann | 4137 | | Standard ZCL | +| Paulmann | 500.43 | | Standard ZCL | +| Paulmann | 500.44 | | Standard ZCL | +| Paulmann | 500.45 | | Standard ZCL | +| Paulmann | 500.46 | | Standard ZCL | +| Paulmann | 500.47 | | Standard ZCL | +| Paulmann | 500.48 | | Standard ZCL | +| Paulmann | 500.67 | | Standard ZCL | +| Paulmann | 50043 | | Standard ZCL | +| Paulmann | 50044/50045 | | Standard ZCL | +| Paulmann | 50049/500.63 | | Standard ZCL | +| Paulmann | 50064 | | Standard ZCL | +| Paulmann | 501.22 | | Standard ZCL | +| Paulmann | 501.31 | | Standard ZCL | +| Paulmann | 501.34 | Battery | Standard ZCL | +| Paulmann | 501.37 | Battery | Standard ZCL | +| Paulmann | 501.39 | | Standard ZCL | +| Paulmann | 501.40 | Battery | Standard ZCL | +| Paulmann | 501.41 | Battery | Standard ZCL | +| Paulmann | 50394 | | Standard ZCL | +| Paulmann | 924.70 | | Standard ZCL | +| Paulmann | 929.60 | | Standard ZCL | +| Paulmann | 929.63 | | Standard ZCL | +| Paulmann | 929.66 | | Standard ZCL | +| Paulmann | 93999 | | Standard ZCL | +| Paulmann | 94191 | | Standard ZCL | +| Paulmann | 948.47/29165 | | Standard ZCL | +| Paulmann | 94842 | | Standard ZCL | +| Paulmann | 968.93 | | Standard ZCL | +| Paulmann | 984.42 | | Standard ZCL | +| Paulmann | CCT-I | | Standard ZCL | +| Perenio | PECLS01 | Water, Battery | Standard ZCL | +| Perenio | PECMS01 | Motion, Battery | Standard ZCL | +| Perenio | PECWS01 | Contact, Battery | Standard ZCL | +| Perenio | PEHPL0X | | Standard ZCL | +| Perenio | PEHWE20 | | Standard ZCL | +| Philio | PAT04-A | Water, Battery | Standard ZCL | +| Philips | 046677476816 | | Standard ZCL | +| Philips | 046677551780 | | Standard ZCL | +| Philips | 046677562229 | | Standard ZCL | +| Philips | 046677577490 | | Standard ZCL | +| Philips | 046677577520 | | Standard ZCL | +| Philips | 046677577957 | | Standard ZCL | +| Philips | 046677578138 | | Standard ZCL | +| Philips | 046677584658 | | Standard ZCL | +| Philips | 046677584719 | | Standard ZCL | +| Philips | 046677585235 | | Standard ZCL | +| Philips | 046677590161 | | Standard ZCL | +| Philips | 046677592530 | | Standard ZCL | +| Philips | 046677592622 | | Standard ZCL | +| Philips | 046677803087 | | Standard ZCL | +| Philips | 13190230 | | Standard ZCL | +| Philips | 1740193P0 | | Standard ZCL | +| Philips | 1740293P0 | | Standard ZCL | +| Philips | 1740393P0 | | Standard ZCL | +| Philips | 1741530P7 | | Standard ZCL | +| Philips | 1741730V7 | | Standard ZCL | +| Philips | 1741830P7 | | Standard ZCL | +| Philips | 1741930V7 | | Standard ZCL | +| Philips | 1742030P7 | | Standard ZCL | +| Philips | 1742330P7 | | Standard ZCL | +| Philips | 1742830P7 | | Standard ZCL | +| Philips | 1742930P7 | | Standard ZCL | +| Philips | 1743030P7 | | Standard ZCL | +| Philips | 1743130P7 | | Standard ZCL | +| Philips | 1743230P7 | | Standard ZCL | +| Philips | 1743430P7 | | Standard ZCL | +| Philips | 17435/30/P7 | | Standard ZCL | +| Philips | 17436/30/P7 | | Standard ZCL | +| Philips | 1743730P7 | | Standard ZCL | +| Philips | 1743830P7 | | Standard ZCL | +| Philips | 1743830V7 | | Standard ZCL | +| Philips | 1743930P7 | | Standard ZCL | +| Philips | 1744130P7 | | Standard ZCL | +| Philips | 1744230P7 | | Standard ZCL | +| Philips | 1745130P7 | | Standard ZCL | +| Philips | 1745430P7 | | Standard ZCL | +| Philips | 1745530P7 | | Standard ZCL | +| Philips | 1745630P7 | | Standard ZCL | +| Philips | 1745730V7 | | Standard ZCL | +| Philips | 1745930P7 | | Standard ZCL | +| Philips | 1745930V7 | | Standard ZCL | +| Philips | 1746130P7 | | Standard ZCL | +| Philips | 1746230V7 | | Standard ZCL | +| Philips | 1746330P7 | | Standard ZCL | +| Philips | 1746430P7 | | Standard ZCL | +| Philips | 1746447P7 | | Standard ZCL | +| Philips | 1746530P7 | | Standard ZCL | +| Philips | 1746547P7 | | Standard ZCL | +| Philips | 1746630P7 | | Standard ZCL | +| Philips | 1746630V7 | | Standard ZCL | +| Philips | 1746730V7 | | Standard ZCL | +| Philips | 3115331PH | | Standard ZCL | +| Philips | 31154 | | Standard ZCL | +| Philips | 3216131P5 | | Standard ZCL | +| Philips | 3216131P6 | | Standard ZCL | +| Philips | 3216231P5 | | Standard ZCL | +| Philips | 3216231P6 | | Standard ZCL | +| Philips | 3216331P5 | | Standard ZCL | +| Philips | 3216331P6 | | Standard ZCL | +| Philips | 3216431P5 | | Standard ZCL | +| Philips | 3216431P6 | | Standard ZCL | +| Philips | 3261030P6 | | Standard ZCL | +| Philips | 3261030P7 | | Standard ZCL | +| Philips | 3261031P6 | | Standard ZCL | +| Philips | 3261048P6 | | Standard ZCL | +| Philips | 3261330P6 | | Standard ZCL | +| Philips | 3261331P6 | | Standard ZCL | +| Philips | 3261331P7 | | Standard ZCL | +| Philips | 3261348P6 | | Standard ZCL | +| Philips | 3306431P7 | | Standard ZCL | +| Philips | 33850000 | | Standard ZCL | +| Philips | 3402831P7 | | Standard ZCL | +| Philips | 3417511P9 | | Standard ZCL | +| Philips | 3417711P6 | | Standard ZCL | +| Philips | 3417831P6 | | Standard ZCL | +| Philips | 3417931P6 | | Standard ZCL | +| Philips | 3418031P6 | | Standard ZCL | +| Philips | 3418131P6 | | Standard ZCL | +| Philips | 3418331P6 | | Standard ZCL | +| Philips | 3418411P6 | | Standard ZCL | +| Philips | 3418631P6 | | Standard ZCL | +| Philips | 3418931P6 | | Standard ZCL | +| Philips | 3435011P7 | | Standard ZCL | +| Philips | 3435731P7 | | Standard ZCL | +| Philips | 4023330P6 | | Standard ZCL | +| Philips | 4023330P7 | | Standard ZCL | +| Philips | 4023331P6 | | Standard ZCL | +| Philips | 4033930P6 | | Standard ZCL | +| Philips | 4033930P7 | | Standard ZCL | +| Philips | 4033931P6 | | Standard ZCL | +| Philips | 4034030P6 | | Standard ZCL | +| Philips | 4034031P6 | | Standard ZCL | +| Philips | 4034031P7 | | Standard ZCL | +| Philips | 4076130P6 | | Standard ZCL | +| Philips | 4076131P6 | | Standard ZCL | +| Philips | 4080148P7 | | Standard ZCL | +| Philips | 4080148P9 | | Standard ZCL | +| Philips | 4080148U9 | | Standard ZCL | +| Philips | 4080248P7 | | Standard ZCL | +| Philips | 4080248P9 | | Standard ZCL | +| Philips | 4080248U9 | | Standard ZCL | +| Philips | 4090130P7 | | Standard ZCL | +| Philips | 4090130P9 | | Standard ZCL | +| Philips | 4090230P9 | | Standard ZCL | +| Philips | 4090231P9 | | Standard ZCL | +| Philips | 4090330P9 | | Standard ZCL | +| Philips | 4090331P9 | | Standard ZCL | +| Philips | 4090431P9 | | Standard ZCL | +| Philips | 4090531P7 | | Standard ZCL | +| Philips | 4090531P9 | | Standard ZCL | +| Philips | 4090631P7 | | Standard ZCL | +| Philips | 4090631P9 | | Standard ZCL | +| Philips | 4090631U9 | | Standard ZCL | +| Philips | 4096730P6 | | Standard ZCL | +| Philips | 4096730U7 | | Standard ZCL | +| Philips | 4098430P7 | | Standard ZCL | +| Philips | 4100448U9 | | Standard ZCL | +| Philips | 433714 | | Standard ZCL | +| Philips | 442296118491 | | Standard ZCL | +| Philips | 4503748C6 | | Standard ZCL | +| Philips | 4503848C5 | | Standard ZCL | +| Philips | 4505748C5 | | Standard ZCL | +| Philips | 4505848C5 | | Standard ZCL | +| Philips | 4507748C5 | | Standard ZCL | +| Philips | 464800 | | Standard ZCL | +| Philips | 5041131P9 | | Standard ZCL | +| Philips | 5042131P9 | | Standard ZCL | +| Philips | 5042148P9 | | Standard ZCL | +| Philips | 5045131P7 | | Standard ZCL | +| Philips | 5045148P7 | | Standard ZCL | +| Philips | 5047130P6 | | Standard ZCL | +| Philips | 5047130P9 | | Standard ZCL | +| Philips | 5047131P8 | | Standard ZCL | +| Philips | 5047131P9 | | Standard ZCL | +| Philips | 5047230P6 | | Standard ZCL | +| Philips | 5047231P6 | | Standard ZCL | +| Philips | 5047330P6 | | Standard ZCL | +| Philips | 5047331P6 | | Standard ZCL | +| Philips | 5047430P6 | | Standard ZCL | +| Philips | 5055131P7 | | Standard ZCL | +| Philips | 5055148P7 | | Standard ZCL | +| Philips | 5060730P7 | | Standard ZCL | +| Philips | 5060731P7 | | Standard ZCL | +| Philips | 5060830P7 | | Standard ZCL | +| Philips | 5060831P7 | | Standard ZCL | +| Philips | 5060930P7 | | Standard ZCL | +| Philips | 5060931P7 | | Standard ZCL | +| Philips | 5061030P7 | | Standard ZCL | +| Philips | 5061031P7 | | Standard ZCL | +| Philips | 5062131P7 | | Standard ZCL | +| Philips | 5062148P7 | | Standard ZCL | +| Philips | 5062231P7 | | Standard ZCL | +| Philips | 5062248P7 | | Standard ZCL | +| Philips | 5062331P7 | | Standard ZCL | +| Philips | 5062348P7 | | Standard ZCL | +| Philips | 5062431P7 | | Standard ZCL | +| Philips | 5062448P7 | | Standard ZCL | +| Philips | 5063130P7 | | Standard ZCL | +| Philips | 5063131P7 | | Standard ZCL | +| Philips | 5063230P7 | | Standard ZCL | +| Philips | 5063231P7 | | Standard ZCL | +| Philips | 5063330P7 | | Standard ZCL | +| Philips | 5063331P7 | | Standard ZCL | +| Philips | 5063430P7 | | Standard ZCL | +| Philips | 5063431P7 | | Standard ZCL | +| Philips | 5110131H5 | | Standard ZCL | +| Philips | 5110731H5 | | Standard ZCL | +| Philips | 5111531H5 | | Standard ZCL | +| Philips | 5309030P9 | | Standard ZCL | +| Philips | 5309031P8 | | Standard ZCL | +| Philips | 5309230P6 | | Standard ZCL | +| Philips | 5309331P6 | | Standard ZCL | +| Philips | 548727 | | Standard ZCL | +| Philips | 5633030P6 | | Standard ZCL | +| Philips | 5633031P9 | | Standard ZCL | +| Philips | 578526 | | Standard ZCL | +| Philips | 579573 | | Standard ZCL | +| Philips | 5900131C5 | | Standard ZCL | +| Philips | 5995111U5 | | Standard ZCL | +| Philips | 5996311U5 | | Standard ZCL | +| Philips | 5996411U5 | | Standard ZCL | +| Philips | 5996511U5 | | Standard ZCL | +| Philips | 5996611U5 | | Standard ZCL | +| Philips | 6109231C5 | | Standard ZCL | +| Philips | 6109331C5 | | Standard ZCL | +| Philips | 7099860PH | | Standard ZCL | +| Philips | 7099930PH | | Standard ZCL | +| Philips | 7121131PU/7120031PH/7120131PH/7120231PU | | Standard ZCL | +| Philips | 7146060PH | | Standard ZCL | +| Philips | 7199960PH | | Standard ZCL | +| Philips | 7299355PH | | Standard ZCL | +| Philips | 7299760PH | | Standard ZCL | +| Philips | 7531609 | | Standard ZCL | +| Philips | 7602031K6 | | Standard ZCL | +| Philips | 7602031N6 | | Standard ZCL | +| Philips | 7602031P7 | | Standard ZCL | +| Philips | 800094 | | Standard ZCL | +| Philips | 801480 | | Standard ZCL | +| Philips | 8718696126523 | | Standard ZCL | +| Philips | 8718696153055 | | Standard ZCL | +| Philips | 8718696153062 | | Standard ZCL | +| Philips | 8718696166079 | | Standard ZCL | +| Philips | 8718696167991 | | Standard ZCL | +| Philips | 8718696170557 | | Standard ZCL | +| Philips | 8718696170625 | | Standard ZCL | +| Philips | 8718696170656 | | Standard ZCL | +| Philips | 8718696174548 | | Standard ZCL | +| Philips | 8718696175798 | | Standard ZCL | +| Philips | 8718696485880 | | Standard ZCL | +| Philips | 8718696548738 | | Standard ZCL | +| Philips | 8718696598283 | | Standard ZCL | +| Philips | 8718696695203 | | Standard ZCL | +| Philips | 8718699673147 | | Standard ZCL | +| Philips | 8718699688820 | | Standard ZCL | +| Philips | 8718699688882 | | Standard ZCL | +| Philips | 8718699689308 | | Standard ZCL | +| Philips | 8718699693985 | Battery | Standard ZCL | +| Philips | 8718699703424 | | Standard ZCL | +| Philips | 8719514279131 | | Standard ZCL | +| Philips | 8719514279155 | | Standard ZCL | +| Philips | 8719514279193 | | Standard ZCL | +| Philips | 8719514301443 | | Standard ZCL | +| Philips | 8719514301481 | | Standard ZCL | +| Philips | 8719514301528 | | Standard ZCL | +| Philips | 8719514301542 | | Standard ZCL | +| Philips | 8719514302235 | | Standard ZCL | +| Philips | 8719514328242 | | Standard ZCL | +| Philips | 8719514329843 | | Standard ZCL | +| Philips | 8719514338142 | | Standard ZCL | +| Philips | 8719514338487 | | Standard ZCL | +| Philips | 8719514338524 | | Standard ZCL | +| Philips | 871951433908 | | Standard ZCL | +| Philips | 8719514339125 | | Standard ZCL | +| Philips | 8719514339163 | | Standard ZCL | +| Philips | 8719514342361 | | Standard ZCL | +| Philips | 8719514343320 | | Standard ZCL | +| Philips | 8719514344723 | | Standard ZCL | +| Philips | 8719514382350 | | Standard ZCL | +| Philips | 8719514392830 | | Standard ZCL | +| Philips | 8719514419155 | | Standard ZCL | +| Philips | 8719514419278 | | Standard ZCL | +| Philips | 8719514434479 | | Standard ZCL | +| Philips | 8719514434530 | | Standard ZCL | +| Philips | 8719514434592 | | Standard ZCL | +| Philips | 8719514491106 | | Standard ZCL | +| Philips | 8719514491229 | | Standard ZCL | +| Philips | 8719514491342 | | Standard ZCL | +| Philips | 8720169264151 | | Standard ZCL | +| Philips | 8720169277243 | | Standard ZCL | +| Philips | 8720169363649 | | Standard ZCL | +| Philips | 8720169364066 | | Standard ZCL | +| Philips | 8720169392182 | | Standard ZCL | +| Philips | 8720169392540 | | Standard ZCL | +| Philips | 912401483126 | | Standard ZCL | +| Philips | 915005106701 | | Standard ZCL | +| Philips | 915005587401 | | Standard ZCL | +| Philips | 915005732902 | | Standard ZCL | +| Philips | 915005733701 | | Standard ZCL | +| Philips | 915005821901 | | Standard ZCL | +| Philips | 915005914501 | | Standard ZCL | +| Philips | 915005914601 | | Standard ZCL | +| Philips | 915005916901 | | Standard ZCL | +| Philips | 915005986901 | | Standard ZCL | +| Philips | 915005987001 | | Standard ZCL | +| Philips | 915005987101 | | Standard ZCL | +| Philips | 915005987301 | | Standard ZCL | +| Philips | 915005987401 | | Standard ZCL | +| Philips | 915005987501 | | Standard ZCL | +| Philips | 915005987601 | | Standard ZCL | +| Philips | 915005987701 | | Standard ZCL | +| Philips | 915005987801 | | Standard ZCL | +| Philips | 915005987901 | | Standard ZCL | +| Philips | 915005988001 | | Standard ZCL | +| Philips | 915005988101 | | Standard ZCL | +| Philips | 915005988201 | | Standard ZCL | +| Philips | 915005988401 | | Standard ZCL | +| Philips | 915005988501 | | Standard ZCL | +| Philips | 915005988502 | | Standard ZCL | +| Philips | 915005988602 | | Standard ZCL | +| Philips | 915005996401 | | Standard ZCL | +| Philips | 915005996601 | | Standard ZCL | +| Philips | 915005996701 | | Standard ZCL | +| Philips | 915005996901 | | Standard ZCL | +| Philips | 915005997001 | | Standard ZCL | +| Philips | 915005997301 | | Standard ZCL | +| Philips | 915005997501 | | Standard ZCL | +| Philips | 915005997601 | | Standard ZCL | +| Philips | 915005997701 | | Standard ZCL | +| Philips | 915005997801 | | Standard ZCL | +| Philips | 915005997901 | | Standard ZCL | +| Philips | 915005998001 | | Standard ZCL | +| Philips | 915005998101 | | Standard ZCL | +| Philips | 915005998201 | | Standard ZCL | +| Philips | 9290002269A | | Standard ZCL | +| Philips | 9290002579A | | Standard ZCL | +| Philips | 9290011370 | | Standard ZCL | +| Philips | 9290011998B | | Standard ZCL | +| Philips | 9290012573A | | Standard ZCL | +| Philips | 9290012607 | Motion, Temperature, Battery, Illuminance | Standard ZCL | +| Philips | 9290018187B | | Standard ZCL | +| Philips | 9290018189 | | Standard ZCL | +| Philips | 9290018194 | | Standard ZCL | +| Philips | 9290018195 | | Standard ZCL | +| Philips | 9290018215 | | Standard ZCL | +| Philips | 9290018216 | | Standard ZCL | +| Philips | 929001821618 | | Standard ZCL | +| Philips | 9290018216A | | Standard ZCL | +| Philips | 9290018217 | | Standard ZCL | +| Philips | 9290018609 | | Standard ZCL | +| Philips | 929001953101 | | Standard ZCL | +| Philips | 9290019532 | | Standard ZCL | +| Philips | 9290019533 | | Standard ZCL | +| Philips | 929001953301 | | Standard ZCL | +| Philips | 9290019534 | | Standard ZCL | +| Philips | 9290019536 | | Standard ZCL | +| Philips | 9290019758 | Motion, Temperature, Battery, Illuminance | Standard ZCL | +| Philips | 929002039801 | | Standard ZCL | +| Philips | 9290020399 | | Standard ZCL | +| Philips | 9290020400 | | Standard ZCL | +| Philips | 9290022166 | | Standard ZCL | +| Philips | 9290022167 | | Standard ZCL | +| Philips | 9290022169 | | Standard ZCL | +| Philips | 9290022266A | | Standard ZCL | +| Philips | 9290022267 | | Standard ZCL | +| Philips | 9290022267A | | Standard ZCL | +| Philips | 9290022268 | | Standard ZCL | +| Philips | 929002240401 | | Standard ZCL | +| Philips | 9290022407 | | Standard ZCL | +| Philips | 9290022408 | | Standard ZCL | +| Philips | 9290022411 | | Standard ZCL | +| Philips | 929002241201 | | Standard ZCL | +| Philips | 9290022415 | | Standard ZCL | +| Philips | 929002277501 | | Standard ZCL | +| Philips | 9290022890 | | Standard ZCL | +| Philips | 9290022891 | | Standard ZCL | +| Philips | 929002294101 | | Standard ZCL | +| Philips | 929002294102 | | Standard ZCL | +| Philips | 929002294203 | | Standard ZCL | +| Philips | 9290022943 | | Standard ZCL | +| Philips | 9290022944 | | Standard ZCL | +| Philips | 9290022975 | | Standard ZCL | +| Philips | 929002297503 | | Standard ZCL | +| Philips | 9290023349 | | Standard ZCL | +| Philips | 929002335001 | | Standard ZCL | +| Philips | 9290023351 | | Standard ZCL | +| Philips | 929002335105 | | Standard ZCL | +| Philips | 9290023351B | | Standard ZCL | +| Philips | 929002375901 | | Standard ZCL | +| Philips | 929002376001 | | Standard ZCL | +| Philips | 929002376101 | | Standard ZCL | +| Philips | 929002376201 | | Standard ZCL | +| Philips | 929002376301 | | Standard ZCL | +| Philips | 929002376401 | | Standard ZCL | +| Philips | 929002376501 | | Standard ZCL | +| Philips | 929002376701 | | Standard ZCL | +| Philips | 929002376703 | | Standard ZCL | +| Philips | 929002376801 | | Standard ZCL | +| Philips | 929002376803 | | Standard ZCL | +| Philips | 929002376901 | | Standard ZCL | +| Philips | 929002398602 | Battery | Standard ZCL | +| Philips | 929002401001 | | Standard ZCL | +| Philips | 929002401101 | | Standard ZCL | +| Philips | 929002401201 | | Standard ZCL | +| Philips | 929002422702 | | Standard ZCL | +| Philips | 929002422801 | | Standard ZCL | +| Philips | 929002422901 | | Standard ZCL | +| Philips | 9290024406 | | Standard ZCL | +| Philips | 9290024406A | | Standard ZCL | +| Philips | 9290024426 | | Standard ZCL | +| Philips | 92900244777 | | Standard ZCL | +| Philips | 929002459201 | | Standard ZCL | +| Philips | 9290024683 | | Standard ZCL | +| Philips | 9290024684 | | Standard ZCL | +| Philips | 9290024687 | | Standard ZCL | +| Philips | 9290024688 | | Standard ZCL | +| Philips | 9290024691 | | Standard ZCL | +| Philips | 9290024691A | | Standard ZCL | +| Philips | 929002469202 | | Standard ZCL | +| Philips | 929002469216 | | Standard ZCL | +| Philips | 9290024693 | | Standard ZCL | +| Philips | 929002471601 | | Standard ZCL | +| Philips | 9290024717 | | Standard ZCL | +| Philips | 929002471901 | | Standard ZCL | +| Philips | 929002477901 | | Standard ZCL | +| Philips | 9290024782 | | Standard ZCL | +| Philips | 9290024783 | | Standard ZCL | +| Philips | 929002478401 | | Standard ZCL | +| Philips | 9290024785 | | Standard ZCL | +| Philips | 9290024796 | | Standard ZCL | +| Philips | 9290024896 | | Standard ZCL | +| Philips | 929002966501 | | Standard ZCL | +| Philips | 9290029808 | | Standard ZCL | +| Philips | 929002980901 | | Standard ZCL | +| Philips | 929002994901 | | Standard ZCL | +| Philips | 929003017102 | Battery | Standard ZCL | +| Philips | 9290030211 | | Standard ZCL | +| Philips | 929003021301 | | Standard ZCL | +| Philips | 929003045201 | | Standard ZCL | +| Philips | 929003045301 | | Standard ZCL | +| Philips | 929003045401 | | Standard ZCL | +| Philips | 929003045501 | | Standard ZCL | +| Philips | 929003045901 | | Standard ZCL | +| Philips | 929003046201 | | Standard ZCL | +| Philips | 929003046601 | | Standard ZCL | +| Philips | 929003047001 | | Standard ZCL | +| Philips | 929003047101 | | Standard ZCL | +| Philips | 929003047401 | | Standard ZCL | +| Philips | 929003047501 | | Standard ZCL | +| Philips | 929003047601 | | Standard ZCL | +| Philips | 929003047801 | | Standard ZCL | +| Philips | 929003048201 | | Standard ZCL | +| Philips | 929003050601 | | Standard ZCL | +| Philips | 9290030509 | | Standard ZCL | +| Philips | 9290030514 | | Standard ZCL | +| Philips | 9290030516 | | Standard ZCL | +| Philips | 9290030517 | | Standard ZCL | +| Philips | 9290030518 | | Standard ZCL | +| Philips | 9290030519 | | Standard ZCL | +| Philips | 9290030520 | | Standard ZCL | +| Philips | 9290030521 | | Standard ZCL | +| Philips | 9290030523 | | Standard ZCL | +| Philips | 929003052601 | | Standard ZCL | +| Philips | 929003052701 | | Standard ZCL | +| Philips | 929003052901 | | Standard ZCL | +| Philips | 929003053001 | | Standard ZCL | +| Philips | 929003053201 | | Standard ZCL | +| Philips | 929003053401 | | Standard ZCL | +| Philips | 929003054001 | | Standard ZCL | +| Philips | 929003054101 | | Standard ZCL | +| Philips | 929003054201 | | Standard ZCL | +| Philips | 929003054301 | | Standard ZCL | +| Philips | 929003054401 | | Standard ZCL | +| Philips | 929003054501 | | Standard ZCL | +| Philips | 929003054601 | | Standard ZCL | +| Philips | 929003054701 | | Standard ZCL | +| Philips | 929003054801 | | Standard ZCL | +| Philips | 929003055201 | | Standard ZCL | +| Philips | 929003055401 | | Standard ZCL | +| Philips | 929003055501 | | Standard ZCL | +| Philips | 929003055701 | | Standard ZCL | +| Philips | 929003055801 | | Standard ZCL | +| Philips | 929003055901 | | Standard ZCL | +| Philips | 929003056001 | | Standard ZCL | +| Philips | 929003056701 | | Standard ZCL | +| Philips | 929003056801 | | Standard ZCL | +| Philips | 929003056901 | | Standard ZCL | +| Philips | 9290030674 | Motion, Temperature, Battery, Illuminance | Standard ZCL | +| Philips | 9290030675 | Motion, Temperature, Battery, Illuminance | Standard ZCL | +| Philips | 929003074701 | | Standard ZCL | +| Philips | 929003074801 | | Standard ZCL | +| Philips | 929003089301 | | Standard ZCL | +| Philips | 929003098601 | | Standard ZCL | +| Philips | 929003098901 | | Standard ZCL | +| Philips | 929003099001 | | Standard ZCL | +| Philips | 929003099101 | | Standard ZCL | +| Philips | 929003099301 | | Standard ZCL | +| Philips | 929003103601 | | Standard ZCL | +| Philips | 929003115701 | | Standard ZCL | +| Philips | 929003116001 | | Standard ZCL | +| Philips | 929003116101 | | Standard ZCL | +| Philips | 929003116401 | | Standard ZCL | +| Philips | 929003116601 | | Standard ZCL | +| Philips | 929003117201 | | Standard ZCL | +| Philips | 929003117401 | | Standard ZCL | +| Philips | 929003117801 | | Standard ZCL | +| Philips | 929003128401 | | Standard ZCL | +| Philips | 929003128501 | | Standard ZCL | +| Philips | 929003128601 | | Standard ZCL | +| Philips | 929003128701 | | Standard ZCL | +| Philips | 929003128801 | | Standard ZCL | +| Philips | 929003128901 | | Standard ZCL | +| Philips | 929003129001 | | Standard ZCL | +| Philips | 9290031345 | | Standard ZCL | +| Philips | 9290031346 | | Standard ZCL | +| Philips | 9290031347 | | Standard ZCL | +| Philips | 929003134801 | | Standard ZCL | +| Philips | 9290031451 | | Standard ZCL | +| Philips | 9290031452 | | Standard ZCL | +| Philips | 9290031508 | | Standard ZCL | +| Philips | 9290031509 | | Standard ZCL | +| Philips | 9290031512 | | Standard ZCL | +| Philips | 929003151501 | | Standard ZCL | +| Philips | 929003151601 | | Standard ZCL | +| Philips | 929003151701 | | Standard ZCL | +| Philips | 92900336667 | | Standard ZCL | +| Philips | 929003479901 | | Standard ZCL | +| Philips | 929003498601 | | Standard ZCL | +| Philips | 929003516101 | | Standard ZCL | +| Philips | 929003521401 | | Standard ZCL | +| Philips | 929003521501 | | Standard ZCL | +| Philips | 929003521601 | | Standard ZCL | +| Philips | 929003521701 | | Standard ZCL | +| Philips | 929003526301 | | Standard ZCL | +| Philips | 929003531502 | | Standard ZCL | +| Philips | 929003531702 | | Standard ZCL | +| Philips | 929003535301 | | Standard ZCL | +| Philips | 929003536001 | | Standard ZCL | +| Philips | 929003553001 | | Standard ZCL | +| Philips | 929003555701 | | Standard ZCL | +| Philips | 9290035639 | Contact, Battery | Standard ZCL | +| Philips | 9290035753 | | Standard ZCL | +| Philips | 929003575501 | | Standard ZCL | +| Philips | 929003575701 | | Standard ZCL | +| Philips | 9290035842 | | Standard ZCL | +| Philips | 929003596001 | | Standard ZCL | +| Philips | 929003596101 | | Standard ZCL | +| Philips | 929003597601 | | Standard ZCL | +| Philips | 929003597701 | | Standard ZCL | +| Philips | 929003597702 | | Standard ZCL | +| Philips | 929003597802 | | Standard ZCL | +| Philips | 929003597901 | | Standard ZCL | +| Philips | 929003621101 | | Standard ZCL | +| Philips | 929003621301 | | Standard ZCL | +| Philips | 929003666501 | | Standard ZCL | +| Philips | 929003666701 | | Standard ZCL | +| Philips | 929003666901 | | Standard ZCL | +| Philips | 929003667001 | | Standard ZCL | +| Philips | 9290036744 | | Standard ZCL | +| Philips | 9290036745 | | Standard ZCL | +| Philips | 929003674601 | | Standard ZCL | +| Philips | 929003711201 | | Standard ZCL | +| Philips | 9290037121 | | Standard ZCL | +| Philips | 929003736101 | | Standard ZCL | +| Philips | 929003736201 | | Standard ZCL | +| Philips | 929003736301 | | Standard ZCL | +| Philips | 929003736401 | | Standard ZCL | +| Philips | 929003736501 | | Standard ZCL | +| Philips | 929003736601 | | Standard ZCL | +| Philips | 929003736701 | | Standard ZCL | +| Philips | 929003777301 | | Standard ZCL | +| Philips | 929003802101 | | Standard ZCL | +| Philips | 9290038022 | | Standard ZCL | +| Philips | 929003808401 | | Standard ZCL | +| Philips | 929003808501 | | Standard ZCL | +| Philips | 929003808601 | | Standard ZCL | +| Philips | 929003808701 | | Standard ZCL | +| Philips | 929003808801 | | Standard ZCL | +| Philips | 929003808901 | | Standard ZCL | +| Philips | 929003809001 | | Standard ZCL | +| Philips | 929003809101 | | Standard ZCL | +| Philips | 929003809301 | | Standard ZCL | +| Philips | 929003809401 | | Standard ZCL | +| Philips | 929003809501 | | Standard ZCL | +| Philips | 929003809601 | | Standard ZCL | +| Philips | 929003809701 | | Standard ZCL | +| Philips | 929003810901 | | Standard ZCL | +| Philips | 929003812701 | | Standard ZCL | +| Philips | 929003812901 | | Standard ZCL | +| Philips | 929003816901 | | Standard ZCL | +| Philips | 929003817002 | | Standard ZCL | +| Philips | 929003822701 | | Standard ZCL | +| Philips | 929003822901 | | Standard ZCL | +| Philips | 929003823501 | | Standard ZCL | +| Philips | 929003853404 | | Standard ZCL | +| Philips | 9290038536H | | Standard ZCL | +| Philips | 9290038539 | | Standard ZCL | +| Philips | 929003853901 | | Standard ZCL | +| Philips | 9290038548H | | Standard ZCL | +| Philips | 9290038549H | | Standard ZCL | +| Philips | 9290038550H | | Standard ZCL | +| Philips | 9290038551 | | Standard ZCL | +| Philips | 9290038552 | | Standard ZCL | +| Philips | 9290038561 | | Standard ZCL | +| Philips | 929003856201 | | Standard ZCL | +| Philips | 929003856303 | | Standard ZCL | +| Philips | 929003856401 | | Standard ZCL | +| Philips | 929003856501 | | Standard ZCL | +| Philips | 929004276602 | | Standard ZCL | +| Philips | 929004276902 | | Standard ZCL | +| Philips | 929004284702 | | Standard ZCL | +| Philips | 929004291601 | | Standard ZCL | +| Philips | 929004294901 | | Standard ZCL | +| Philips | 929004294903 | | Standard ZCL | +| Philips | 9290042970A | | Standard ZCL | +| Philips | 929004297401 | | Standard ZCL | +| Philips | 929004308301 | | Standard ZCL | +| Philips | 929004308401 | | Standard ZCL | +| Philips | 929004321001 | | Standard ZCL | +| Philips | 929004581801 | | Standard ZCL | +| Philips | 929004581901 | | Standard ZCL | +| Philips | 929004582001 | | Standard ZCL | +| Philips | 929004608001 | | Standard ZCL | +| Philips | 929004610402 | | Standard ZCL | +| Philips | 929004611002 | | Standard ZCL | +| Philips | 929004611201 | | Standard ZCL | +| Philips | 929004611301 | | Standard ZCL | +| Philips | LP_CF_7904008_EU | | Standard ZCL | +| Philips | LWG004 | | Standard ZCL | +| Philips | RDM005 | Battery | Standard ZCL | +| Phoscon | Hive | Battery | Standard ZCL | +| Plugwise | 160-01 | | Standard ZCL | +| Plugwise | 170-01 | Temperature, Humidity, Battery | Standard ZCL | +| Powernity / Xanlite | PO-BOCO-ELEC | Humidity | Tuya | +| Profalux | MAI-ZTP20F | Battery | Standard ZCL | +| Prolight | 5412748727364 | | Standard ZCL | +| Prolight | 5412748727371 | | Standard ZCL | +| Prolight | 5412748727388 | Battery | Standard ZCL | +| Prolight | 5412748727395 | | Standard ZCL | +| Prolight | 5412748727401 | | Standard ZCL | +| Prolight | 5412748727432 | | Standard ZCL | +| Pulsar LLC | LPC-V1 | | Standard ZCL | +| PushOk Hardware | POK001 | Battery | Standard ZCL | +| PushOk Hardware | POK002_POK007 | Humidity, Temperature, Battery | Standard ZCL | +| PushOk Hardware | POK003 | Contact, Temperature, Battery | Standard ZCL | +| PushOk Hardware | POK004 | Illuminance, Battery | Standard ZCL | +| PushOk Hardware | POK005 | Humidity, Temperature, Battery | Standard ZCL | +| PushOk Hardware | POK006 | Battery | Standard ZCL | +| PushOk Hardware | POK008 | Battery, Temperature | Standard ZCL | +| PushOk Hardware | POK010 | Contact, Temperature, Humidity, Battery | Standard ZCL | +| PushOk Hardware | POK011 | Illuminance, Battery | Standard ZCL | +| PushOk Hardware | POK014 | Temperature, Battery | Standard ZCL | +| PushOk Hardware | POK015 | Temperature, Battery | Standard ZCL | +| PushOk Hardware | POK019 | Contact, Battery | Standard ZCL | +| PushOk Hardware | POK020 | Battery | Standard ZCL | +| QA | QADZ1 | | Standard ZCL | +| QA | QADZ2 | | Standard ZCL | +| QA | QADZ4DIN | | Standard ZCL | +| QA | QAFZ200 | | Standard ZCL | +| QA | QARZ1DC | | Standard ZCL | +| QA | QARZ2LR | | Standard ZCL | +| QA | QARZ3LR | | Standard ZCL | +| QA | QARZ4LR | | Standard ZCL | +| QA | QARZDC1LR | | Standard ZCL | +| QA | QASZP | | Tuya | +| QA | QAT42Z1 | | Standard ZCL | +| QA | QAT42Z1B | | Standard ZCL | +| QA | QAT42Z1H | | Standard ZCL | +| QA | QAT42Z2 | | Standard ZCL | +| QA | QAT42Z2B | | Standard ZCL | +| QA | QAT42Z2H | | Standard ZCL | +| QA | QAT42Z3 | | Standard ZCL | +| QA | QAT42Z3B | | Standard ZCL | +| QA | QAT42Z3H | | Standard ZCL | +| QA | QAT44Z4H | | Standard ZCL | +| QA | QAT44Z6 | | Standard ZCL | +| QA | QAT44Z6H | | Standard ZCL | +| Qingping | CGDK2 | Temperature, Humidity, Battery | Standard ZCL | +| Qingping | CGG1 | Temperature, Humidity, Battery | Standard ZCL | +| Quirky | POFLW-WH02 | Water | Standard ZCL | +| Quotra | B07CVL9SZF | | Standard ZCL | +| Quotra | B07JHL6DRV | | Standard ZCL | +| RGB Genie | ZB-1026 | | Standard ZCL | +| RGB Genie | ZB-3008 | | Standard ZCL | +| RGB Genie | ZB-3009 | | Standard ZCL | +| RGB Genie | ZB-5001 | Battery | Standard ZCL | +| RGB Genie | ZB-5004 | Battery | Standard ZCL | +| RGB Genie | ZB-5028 | Battery | Standard ZCL | +| RGB Genie | ZB-5121 | Battery | Standard ZCL | +| RGB Genie | ZB-5122 | Battery | Standard ZCL | +| ROBB | ROB_200-001-0 | Contact, Battery | Standard ZCL | +| ROBB | ROB_200-003-0 | | Standard ZCL | +| ROBB | ROB_200-003-1 | | Standard ZCL | +| ROBB | ROB_200-004-0 | | Standard ZCL | +| ROBB | ROB_200-004-1 | | Standard ZCL | +| ROBB | ROB_200-006-0 | | Standard ZCL | +| ROBB | ROB_200-007-0 | Battery | Standard ZCL | +| ROBB | ROB_200-008-0 | Battery | Standard ZCL | +| ROBB | ROB_200-009-0 | Battery | Standard ZCL | +| ROBB | ROB_200-011-0 | | Standard ZCL | +| ROBB | ROB_200-011-1 | | Standard ZCL | +| ROBB | ROB_200-014-0 | | Standard ZCL | +| ROBB | ROB_200-016-0 | Battery | Standard ZCL | +| ROBB | ROB_200-017-0 | Temperature | Standard ZCL | +| ROBB | ROB_200-017-1 | Temperature | Standard ZCL | +| ROBB | ROB_200-018-0 | Battery | Standard ZCL | +| ROBB | ROB_200-024-0 | Battery | Standard ZCL | +| ROBB | ROB_200-025-0 | Battery | Standard ZCL | +| ROBB | ROB_200-026-0 | | Standard ZCL | +| ROBB | ROB_200-030-0 | | Standard ZCL | +| ROBB | ROB_200-030-1 | | Standard ZCL | +| ROBB | ROB_200-035-0 | | Standard ZCL | +| ROBB | ROB_200-050-0 | | Standard ZCL | +| ROBB | ROB_200-060-0 | | Standard ZCL | +| ROBB | ROB_200-061-0 | | Standard ZCL | +| ROBB | ROB_200-063-0 | | Standard ZCL | +| ROBB | ROB_200-070-0 | Motion, Battery, Temperature, Humidity, Illuminance | Standard ZCL | +| ROBB | ROB_200-081-0 | Battery | Standard ZCL | +| ROBB | ROB_200-084-0 | Battery | Standard ZCL | +| ROBB smarrt | ROB_200-026-1 | | Standard ZCL | +| ROOME | HSC1-WD-0 | Contact | Standard ZCL | +| RTX | ZMS4 | Motion | Standard ZCL | +| RTX | ZVG1 | Battery | Standard ZCL | +| Rademacher | 35104001 | | Standard ZCL | +| Rademacher | 35144001 | | Standard ZCL | +| Rademacher | RDM-35274001 | | Standard ZCL | +| Radium | LMZA4376 | | Standard ZCL | +| Repenic Ltd. | RD-250ZG | | Standard ZCL | +| SIMON | SM0501 | | Standard ZCL | +| SIMON | SM0502 | | Standard ZCL | +| SLC | S32052 | | Standard ZCL | +| SLV | 1001248 | | Standard ZCL | +| SLV | 1001923 | | Standard ZCL | +| SLV | 1005314 | | Standard ZCL | +| SLV | 1005318 | | Standard ZCL | +| SMARTERCURRY | TZE284_aaeasoll | Illuminance, Battery | Tuya | +| SMLIGHT | SLZB-06M | | Standard ZCL | +| SMaBiT (Bitron Video) | AV2010/14 | Motion | Standard ZCL | +| SMaBiT (Bitron Video) | AV2010/16 | | Standard ZCL | +| SMaBiT (Bitron Video) | AV2010/18 | | Standard ZCL | +| SMaBiT (Bitron Video) | AV2010/21A | Contact | Standard ZCL | +| SMaBiT (Bitron Video) | AV2010/21B | Contact | Standard ZCL | +| SMaBiT (Bitron Video) | AV2010/21C | Contact | Standard ZCL | +| SMaBiT (Bitron Video) | AV2010/22 | Motion | Standard ZCL | +| SMaBiT (Bitron Video) | AV2010/22A | Motion | Standard ZCL | +| SMaBiT (Bitron Video) | AV2010/22B | Motion | Standard ZCL | +| SMaBiT (Bitron Video) | AV2010/23 | | Standard ZCL | +| SMaBiT (Bitron Video) | AV2010/24 | Smoke | Standard ZCL | +| SMaBiT (Bitron Video) | AV2010/24A | Smoke | Standard ZCL | +| SMaBiT (Bitron Video) | AV2010/25 | | Standard ZCL | +| SMaBiT (Bitron Video) | AV2010/26 | | Standard ZCL | +| SMaBiT (Bitron Video) | AV2010/28 | | Standard ZCL | +| SMaBiT (Bitron Video) | AV2010/33 | Motion | Standard ZCL | +| SMaBiT (Bitron Video) | AV2010/34 | | Standard ZCL | +| SMaBiT (Bitron Video) | AV2010/37 | Water | Standard ZCL | +| SODA | S8 | Battery, Temperature, Humidity | Tuya | +| SOHAN Electric | RDCBC/Z | | Standard ZCL | +| SONOFF | BASIC-ZB1GSP | | Standard ZCL | +| SONOFF | BASICZBR3 | | Standard ZCL | +| SONOFF | MG1_5RZ | Motion | Standard ZCL | +| SONOFF | MINI-ZB1GP | | Standard ZCL | +| SONOFF | MINI-ZB1GS | | Standard ZCL | +| SONOFF | MINI-ZB1GSP | | Standard ZCL | +| SONOFF | MINI-ZB2GS | | Standard ZCL | +| SONOFF | MINI-ZB2GS-L | | Standard ZCL | +| SONOFF | MINI-ZBDIM | | Standard ZCL | +| SONOFF | S26R2ZB | | Standard ZCL | +| SONOFF | S31ZB | | Standard ZCL | +| SONOFF | S40ZBTPB | | Standard ZCL | +| SONOFF | S60ZBTPF | | Standard ZCL | +| SONOFF | S60ZBTPG | | Standard ZCL | +| SONOFF | S61SZBTPB | | Standard ZCL | +| SONOFF | SA-028/SA-029 | | Standard ZCL | +| SONOFF | SNZB-01 | Battery | Standard ZCL | +| SONOFF | SNZB-01P | Battery | Standard ZCL | +| SONOFF | SNZB-02 | Battery, Temperature, Humidity | Standard ZCL | +| SONOFF | SNZB-02B | Battery, Temperature, Humidity | Standard ZCL | +| SONOFF | SNZB-02D | Battery, Temperature, Humidity | Standard ZCL | +| SONOFF | SNZB-02DR2 | Battery, Temperature, Humidity | Standard ZCL | +| SONOFF | SNZB-02LD | Battery, Temperature | Standard ZCL | +| SONOFF | SNZB-02M | Battery, Temperature, Humidity, Pressure | Standard ZCL | +| SONOFF | SNZB-02P | Battery, Temperature, Humidity | Standard ZCL | +| SONOFF | SNZB-02UL | Battery, Temperature, Humidity | Standard ZCL | +| SONOFF | SNZB-02WD | Battery, Temperature, Humidity | Standard ZCL | +| SONOFF | SNZB-03 | Motion, Battery | Standard ZCL | +| SONOFF | SNZB-03P | Motion, Battery | Standard ZCL | +| SONOFF | SNZB-03PR2 | Motion, Illuminance, Battery | Standard ZCL | +| SONOFF | SNZB-04 | Contact, Battery | Standard ZCL | +| SONOFF | SNZB-04P | Contact, Battery | Standard ZCL | +| SONOFF | SNZB-04PR2 | Contact, Battery | Standard ZCL | +| SONOFF | SNZB-05P | Water, Battery | Standard ZCL | +| SONOFF | SNZB-06P | Motion | Standard ZCL | +| SONOFF | SNZB-06P24 | Motion, Illuminance | Standard ZCL | +| SONOFF | SWV | Battery | Standard ZCL | +| SONOFF | SWV-ZF2 | Battery | Standard ZCL | +| SONOFF | SWV-ZFE | Battery | Standard ZCL | +| SONOFF | SWV-ZNE | Battery | Standard ZCL | +| SONOFF | Z111PL0H-1JX | | Standard ZCL | +| SONOFF | ZBM5-1C-120 | | Standard ZCL | +| SONOFF | ZBM5-2C-120 | | Standard ZCL | +| SONOFF | ZBM5-3C-120 | | Standard ZCL | +| SONOFF | ZBMINI | | Standard ZCL | +| SONOFF | ZBMINI-L | | Standard ZCL | +| SONOFF | ZBMINIL2 | | Standard ZCL | +| SONOFF | ZBMINIR2 | | Standard ZCL | +| SONOFF | ZBMicro | | Standard ZCL | +| SUTON | STB3L-125-ZJ | Temperature | Tuya | +| Salus Controls | OS600 | Contact | Standard ZCL | +| Salus Controls | PS600 | Battery, Temperature | Standard ZCL | +| Salus Controls | SP600 | | Standard ZCL | +| Salus Controls | SPE600 | | Standard ZCL | +| Salus Controls | SR600 | | Standard ZCL | +| Salus Controls | SW600 | Contact | Standard ZCL | +| Salus Controls | SX885ZB | | Standard ZCL | +| Salus Controls | WLS600 | Water | Standard ZCL | +| Samotech | SM308 | | Standard ZCL | +| Samotech | SM308-2CH | | Standard ZCL | +| Samotech | SM308-S | | Standard ZCL | +| Samotech | SM309 | | Standard ZCL | +| Samotech | SM309-S | | Standard ZCL | +| Samotech | SM309-S-2CH | | Standard ZCL | +| Samotech | SM315 | | Standard ZCL | +| Samotech | SM323_v1 | | Standard ZCL | +| Samotech | SM323_v2 | | Standard ZCL | +| Samotech | SM324 | | Standard ZCL | +| Samotech | SM325-ZG | | Standard ZCL | +| Saswell | SEA801-Zigbee/SEA802-Zigbee | | Standard ZCL | +| Savolar | SAV-DL6IN-24V-12W | | Standard ZCL | +| Sber | SBDV-00029 | Motion, Battery | Standard ZCL | +| Sber | SBDV-00030 | Contact, Battery | Standard ZCL | +| Sber | SBDV-00079 | Temperature, Humidity, Battery | Standard ZCL | +| Sber | SBDV-00154 | Water, Battery | Standard ZCL | +| Sber | SBDV-00196 | | Standard ZCL | +| Sber | SBDV-00197 | | Standard ZCL | +| Sber | SBDV-00199 | | Standard ZCL | +| Sber | SBDV-00200 | | Standard ZCL | +| Sber | SBDV-00202 | Device Temp | Standard ZCL | +| Sber | SBDV-00205 | Device Temp, Temperature | Standard ZCL | +| Scan Products | 12501 | | Standard ZCL | +| Scan Products | 12502 | | Standard ZCL | +| Schlage | BE468 | Battery | Standard ZCL | +| Schneider Electric | 3025CSGZ | | Standard ZCL | +| Schneider Electric | 41E10PBSWMZ-VW | | Standard ZCL | +| Schneider Electric | 41E2PBSWMZ/356PB2MBTZ | | Standard ZCL | +| Schneider Electric | 41EPBDWCLMZ/354PBDMBTZ | | Standard ZCL | +| Schneider Electric | 545D6102 | | Standard ZCL | +| Schneider Electric | 545D6115 | | Standard ZCL | +| Schneider Electric | 545D6514 | | Standard ZCL | +| Schneider Electric | 550B1024 | Battery, Temperature, Humidity | Standard ZCL | +| Schneider Electric | 550D6001 | Battery | Standard ZCL | +| Schneider Electric | A9MEM1570 | | Standard ZCL | +| Schneider Electric | CCT5010-0001 | | Standard ZCL | +| Schneider Electric | CCT5010-0003 | | Standard ZCL | +| Schneider Electric | CCT5011-0001/CCT5011-0002/MEG5011-0001 | | Standard ZCL | +| Schneider Electric | CCT591011_AS | Contact | Standard ZCL | +| Schneider Electric | CCT592011 | Water | Standard ZCL | +| Schneider Electric | CCT595011 | Motion, Battery, Illuminance | Standard ZCL | +| Schneider Electric | CCT711119 | | Standard ZCL | +| Schneider Electric | CCTFR6000 | | Standard ZCL | +| Schneider Electric | CCTFR6400 | Humidity, Battery | Standard ZCL | +| Schneider Electric | CCTFR6700 | | Standard ZCL | +| Schneider Electric | CCTFR6730 | | Standard ZCL | +| Schneider Electric | E8331DST300ZB | | Standard ZCL | +| Schneider Electric | E8331SRY800ZB | | Standard ZCL | +| Schneider Electric | E8331SRY800ZB_NEW | | Standard ZCL | +| Schneider Electric | E8332DST350ZB | | Standard ZCL | +| Schneider Electric | E8332SRY800ZB | | Standard ZCL | +| Schneider Electric | E8332SRY800ZB_NEW | | Standard ZCL | +| Schneider Electric | E8333SRY800ZB | | Standard ZCL | +| Schneider Electric | E8333SRY800ZB_NEW | | Standard ZCL | +| Schneider Electric | EER40030 | | Standard ZCL | +| Schneider Electric | EER42000 | | Standard ZCL | +| Schneider Electric | EER50000 | | Standard ZCL | +| Schneider Electric | EKO07259 | | Standard ZCL | +| Schneider Electric | EKO09716 | | Standard ZCL | +| Schneider Electric | EKO09738 | | Standard ZCL | +| Schneider Electric | MEG5116-0300/MEG5171-0000 | | Standard ZCL | +| Schneider Electric | MEG5116-0300_MEG5151-0000 | | Standard ZCL | +| Schneider Electric | MEG5116-0300_MEG5162-0000 | | Standard ZCL | +| Schneider Electric | MEG5126-0300 | | Standard ZCL | +| Schneider Electric | MEG5126-0300/MEG5171-0000 | | Standard ZCL | +| Schneider Electric | MEG5126-0300/MEG5172-0000 | | Standard ZCL | +| Schneider Electric | MEG5126-0300_MEG5152-0000 | | Standard ZCL | +| Schneider Electric | MEG5161-0000 | | Standard ZCL | +| Schneider Electric | MUR36014 | | Standard ZCL | +| Schneider Electric | NH3516A | | Standard ZCL | +| Schneider Electric | NH3526 | Motion, Illuminance | Standard ZCL | +| Schneider Electric | NH3527A | Motion, Illuminance | Standard ZCL | +| Schneider Electric | NHMOTION/UNIDIM/1 | Motion, Illuminance | Standard ZCL | +| Schneider Electric | S520530W | | Standard ZCL | +| Schneider Electric | S520619 | Motion, Temperature | Standard ZCL | +| Schneider Electric | U201DST600ZB | | Standard ZCL | +| Schneider Electric | U201SRY2KWZB | | Standard ZCL | +| Schneider Electric | U202DST600ZB | | Standard ZCL | +| Schneider Electric | U202SRY2KWZB | | Standard ZCL | +| Schneider Electric | W564100 | Motion, Illuminance, Temperature | Standard ZCL | +| Schneider Electric | W599001 | Smoke, Battery, Temperature | Standard ZCL | +| Schneider Electric | WDE002334 | | Standard ZCL | +| Schneider Electric | WDE002386 | | Standard ZCL | +| Schneider Electric | WDE002497 | | Standard ZCL | +| Schneider Electric | WDE002906/MEG5001-0300 | Battery | Standard ZCL | +| Schneider Electric | WDE002960 | | Standard ZCL | +| Schneider Electric | WDE011680 | Temperature | Standard ZCL | +| Schwaiger | HAL300 | | Standard ZCL | +| Schwaiger | HAL400 | | Standard ZCL | +| Schwaiger | HAL500 | | Standard ZCL | +| Schwaiger | HAL550 | | Standard ZCL | +| Schwaiger | HAL600 | | Standard ZCL | +| Schwaiger | HAL800 | | Standard ZCL | +| Schwaiger | ZHS-15 | | Standard ZCL | +| Scimagic | 1-ZB-WSD | Temperature | Tuya | +| Securifi | PP-WHT-US | | Standard ZCL | +| Sengled | E11-G13 | | Standard ZCL | +| Sengled | E11-G23/E11-G33 | | Standard ZCL | +| Sengled | E11-N13/E11-N13A/E11-N14/E11-N14A | | Standard ZCL | +| Sengled | E11-N1EA | | Standard ZCL | +| Sengled | E11-N1G | | Standard ZCL | +| Sengled | E11-U21U31 | | Standard ZCL | +| Sengled | E11-U2E | | Standard ZCL | +| Sengled | E11-U3E | | Standard ZCL | +| Sengled | E12-N14 | | Standard ZCL | +| Sengled | E12-N1E | | Standard ZCL | +| Sengled | E13-A21 | | Standard ZCL | +| Sengled | E13-N11 | Motion | Standard ZCL | +| Sengled | E1ACA4ABE38A | | Standard ZCL | +| Sengled | E1C-NB6 | | Standard ZCL | +| Sengled | E1C-NB7 | | Standard ZCL | +| Sengled | E1D-G73WNA | Contact, Battery | Standard ZCL | +| Sengled | E1F-N5E | | Standard ZCL | +| Sengled | E1F-N9G | | Standard ZCL | +| Sengled | E1G-G8E | | Standard ZCL | +| Sengled | E1M-G7H | Motion, Battery | Standard ZCL | +| Sengled | E21-N13A | | Standard ZCL | +| Sengled | E21-N14A | | Standard ZCL | +| Sengled | E21-N1EA | | Standard ZCL | +| Sengled | E22-N1E | | Standard ZCL | +| Sengled | E2D-G73 | Contact, Battery | Standard ZCL | +| Sengled | Z01-A19NAE26 | | Standard ZCL | +| Sengled | Z01-A60EAE27 | | Standard ZCL | +| Sengled | Z01-CIA19NAE26 | | Standard ZCL | +| Sercomm | AL-PIR02 | Motion, Battery | Standard ZCL | +| Sercomm | SE-RZ11 | | Standard ZCL | +| Sercomm | SZ-DWS04 | Contact, Temperature, Battery | Standard ZCL | +| Sercomm | SZ-DWS08 | Contact, Temperature, Battery | Standard ZCL | +| Sercomm | SZ-ESW01 | | Standard ZCL | +| Sercomm | SZ-ESW01-AU | | Standard ZCL | +| Sercomm | SZ-ESW02 | | Standard ZCL | +| Sercomm | SZ-ESW02N-CZ3 | | Standard ZCL | +| Sercomm | SZ-PIR04N | Motion, Temperature, Battery, Illuminance | Standard ZCL | +| Sercomm | SZ-WTD03 | Water | Standard ZCL | +| Sercomm | XHS2-SE | Contact, Temperature, Battery | Standard ZCL | +| Shada | 0190015 | | Standard ZCL | +| Shelly | S4DM-0010WW | | Standard ZCL | +| Shelly | S4DM-0A101WWL | | Standard ZCL | +| Shelly | S4EM-001PXCEU16 | | Standard ZCL | +| Shelly | S4EM-002CXCEU | | Standard ZCL | +| Shelly | S4PL-00116US | | Standard ZCL | +| Shelly | S4PL-00416EU | | Standard ZCL | +| Shelly | S4SN-0071A | Water, Battery | Standard ZCL | +| Shelly | S4SN-0U61X | Motion | Standard ZCL | +| Shelly | S4SW-001P8EU | | Standard ZCL | +| Shelly | S4SW-001X8EU | | Standard ZCL | +| Shelly | S4SW-002P16EU-COVER | | Standard ZCL | +| Shelly | S4SW-002P16EU-SWITCH | | Standard ZCL | +| Shelly | SBBT-102C | Battery | Standard ZCL | +| Shelly | SBBT-104CUS | Battery | Standard ZCL | +| Shelly | SBDW-103C | Contact, Battery | Standard ZCL | +| Shelly | SBHT-103C | Battery, Temperature, Humidity | Standard ZCL | +| Shelly | SBHT-203C | Battery, Temperature, Humidity | Standard ZCL | +| Shelly | SBMO-103Z | Motion, Battery | Standard ZCL | +| Shelly | SBRC-005B-B | Battery | Standard ZCL | +| Shelly | WS90 | Battery, Illuminance, Temperature, Pressure, Humidity | Standard ZCL | +| Shenzhen Homa | HLC610-Z | | Standard ZCL | +| Shenzhen Homa | HLC614-ZLL | | Standard ZCL | +| Shenzhen Homa | HLC821-Z-SC | | Standard ZCL | +| Shenzhen Homa | HLC833-Z-SC | | Standard ZCL | +| Shenzhen Homa | HLD503-Z-CT | | Standard ZCL | +| Shenzhen Homa | HLD812-Z-SC | | Standard ZCL | +| Shenzhen Homa | HOMA1001_CT | | Standard ZCL | +| Shenzhen Homa | HOMA1001_RGB | | Standard ZCL | +| Shenzhen Homa | HOMA1001_RGBW | | Standard ZCL | +| Shenzhen Homa | HOMA1001_SC | | Standard ZCL | +| ShinaSystem | BSM-300ZB | Battery | Standard ZCL | +| ShinaSystem | DIO-300Z | | Standard ZCL | +| ShinaSystem | DLM-300Z | Battery | Standard ZCL | +| ShinaSystem | DSM-300ZB | Contact, Battery | Standard ZCL | +| ShinaSystem | FAM-300Z | Smoke, Battery | Standard ZCL | +| ShinaSystem | HQM-300Z | Humidity, Battery | Standard ZCL | +| ShinaSystem | ISM300Z3 | | Standard ZCL | +| ShinaSystem | MSM-300ZB | Battery | Standard ZCL | +| ShinaSystem | OSM-300ZB | Motion, Battery | Standard ZCL | +| ShinaSystem | PMM-300Z1 | | Standard ZCL | +| ShinaSystem | PMM-300Z2 | Temperature | Standard ZCL | +| ShinaSystem | PMM-300Z3 | Temperature | Standard ZCL | +| ShinaSystem | SBM300Z1 | | Standard ZCL | +| ShinaSystem | SBM300Z2 | | Standard ZCL | +| ShinaSystem | SBM300Z3 | | Standard ZCL | +| ShinaSystem | SBM300Z4 | | Standard ZCL | +| ShinaSystem | SBM300Z5 | | Standard ZCL | +| ShinaSystem | SBM300Z6 | | Standard ZCL | +| ShinaSystem | SBM300ZB1 | Battery | Standard ZCL | +| ShinaSystem | SBM300ZB2 | Battery | Standard ZCL | +| ShinaSystem | SBM300ZB3 | Battery | Standard ZCL | +| ShinaSystem | SBM300ZB4 | Battery | Standard ZCL | +| ShinaSystem | SBM300ZC1 | Battery | Standard ZCL | +| ShinaSystem | SBM300ZC2 | Battery | Standard ZCL | +| ShinaSystem | SBM300ZC3 | Battery | Standard ZCL | +| ShinaSystem | SBM300ZC4 | Battery | Standard ZCL | +| ShinaSystem | SQM300Z1 | | Standard ZCL | +| ShinaSystem | SQM300Z2 | | Standard ZCL | +| ShinaSystem | SQM300Z3 | | Standard ZCL | +| ShinaSystem | SQM300Z4 | | Standard ZCL | +| ShinaSystem | SQM300Z6 | | Standard ZCL | +| ShinaSystem | SQM300ZC4 | Battery | Standard ZCL | +| ShinaSystem | TQM-300ZB | Temperature, Humidity, Battery | Standard ZCL | +| ShinaSystem | TSM-300ZB | Temperature, Humidity, Battery | Standard ZCL | +| ShinaSystem | USM-300ZB | Motion, Battery, Temperature, Humidity, Illuminance | Standard ZCL | +| ShinaSystem | WCM-300Z | | Standard ZCL | +| Silicon Labs | RB-ElectricityDsp-061-3 | | Standard ZCL | +| Simpla Home | Soil Pro | Temperature, Soil Moisture, Battery, Illuminance | Standard ZCL | +| Sinopé | DM2500ZB | | Standard ZCL | +| Sinopé | DM2550ZB | | Standard ZCL | +| Sinopé | LM4110ZB | Battery, Temperature | Standard ZCL | +| Sinopé | RM3250ZB | | Standard ZCL | +| Sinopé | RM3500ZB | Water, Temperature | Standard ZCL | +| Sinopé | SP2600ZB | | Standard ZCL | +| Sinopé | SP2610ZB | | Standard ZCL | +| Sinopé | SW2500ZB | | Standard ZCL | +| Sinopé | TH1123ZB | | Standard ZCL | +| Sinopé | TH1123ZB-G2 | | Standard ZCL | +| Sinopé | TH1124ZB | | Standard ZCL | +| Sinopé | TH1124ZB-G2 | | Standard ZCL | +| Sinopé | TH1300ZB | | Standard ZCL | +| Sinopé | WL4200 | Water, Temperature, Battery | Standard ZCL | +| Sinopé | WL4200S | Water, Temperature, Battery | Standard ZCL | +| Sinopé | WL4210 | Water, Temperature, Battery | Standard ZCL | +| Siterwell | GS361A-H04 | Battery | Standard ZCL | +| Skydance | WZ5_cct | | Standard ZCL | +| Skydance | WZ5_dim_1 | | Standard ZCL | +| Skydance | WZ5_rgb | | Standard ZCL | +| Skydance | WZ5_rgbcct | | Standard ZCL | +| Skydance | WZ5_rgbw | | Standard ZCL | +| Slacky-DIY | AirQ_Monitor_S01 | Temperature, Humidity, Pressure, Illuminance | Standard ZCL | +| Slacky-DIY | Electricity Meter TLSR8258 | Device Temp | Standard ZCL | +| Slacky-DIY | ElectricityMeter-ABC-DIY | Device Temp | Standard ZCL | +| Slacky-DIY | FreePad-08K-SlD | Battery | Standard ZCL | +| Slacky-DIY | FreePad-12K-SlD | Battery | Standard ZCL | +| Slacky-DIY | FreePad-20K-SlD | Battery | Standard ZCL | +| Slacky-DIY | RCS-ST16-z-SlD | | Standard ZCL | +| Slacky-DIY | SLACKY_DIY_CO2_SENSOR_R01 | | Standard ZCL | +| Slacky-DIY | SLACKY_DIY_CO2_SENSOR_R02 | Temperature, Humidity | Standard ZCL | +| Slacky-DIY | Smoke Sensor TLSR8258 | Smoke, Battery | Standard ZCL | +| Slacky-DIY | THERM_SLACKY_DIY_R0C | Humidity | Standard ZCL | +| Slacky-DIY | TS0001_power-SlD | | Standard ZCL | +| Slacky-DIY | TS0041-M001-SlD | Battery | Standard ZCL | +| Slacky-DIY | TS0042-z-SlD | Battery | Standard ZCL | +| Slacky-DIY | TS0043-z-SlD | Battery | Standard ZCL | +| Slacky-DIY | TS0044-z-SlD | Battery | Standard ZCL | +| Slacky-DIY | TS0046-z-SlD | Battery | Standard ZCL | +| Slacky-DIY | TS011F_plug-SlD | | Standard ZCL | +| Slacky-DIY | TS0201-LCD-SlD | Battery, Temperature, Humidity | Standard ZCL | +| Slacky-DIY | TS0201-z-SlD | Battery, Temperature, Humidity | Standard ZCL | +| Slacky-DIY | TS0203-z-Sld | Contact, Battery | Standard ZCL | +| Slacky-DIY | TSM1-SlD | | Standard ZCL | +| Slacky-DIY | Watermeter_TLSR8258 | Water, Battery | Standard ZCL | +| Slacky-DIY | ZG-222ZA-z-SlD | Water, Battery | Standard ZCL | +| Smart Home Pty | HGZB-07A | | Standard ZCL | +| Smart Home Pty | HGZB-20-DE | | Standard ZCL | +| SmartThings | 3300-S | Contact, Temperature, Battery | Standard ZCL | +| SmartThings | 3305-S | Motion, Temperature, Battery | Standard ZCL | +| SmartThings | 3310-S | Temperature, Humidity, Battery | Standard ZCL | +| SmartThings | 3315-G | Water, Temperature, Battery | Standard ZCL | +| SmartThings | 3315-S | Water, Temperature, Battery | Standard ZCL | +| SmartThings | 3321-S | Motion, Temperature, Contact, Battery | Standard ZCL | +| SmartThings | 3325-S | Motion, Temperature, Battery | Standard ZCL | +| SmartThings | 7ZA-A806ST-Q1R | | Standard ZCL | +| SmartThings | F-ADT-WTR-1 | Water, Temperature, Battery | Standard ZCL | +| SmartThings | F-APP-UK-V2 | | Standard ZCL | +| SmartThings | F-MLT-US-2 | Motion, Temperature, Contact, Battery | Standard ZCL | +| SmartThings | GP-LBU019BBAWU | | Standard ZCL | +| SmartThings | GP-WOU019BBDWG | | Standard ZCL | +| SmartThings | IM6001-BTP01 | Battery, Temperature | Standard ZCL | +| SmartThings | IM6001-MPP01 | Motion, Temperature, Contact, Battery | Standard ZCL | +| SmartThings | IM6001-MTP01 | Motion, Temperature, Battery | Standard ZCL | +| SmartThings | IM6001-OTP05 | | Standard ZCL | +| SmartThings | IM6001-WLP01 | Water, Temperature, Battery | Standard ZCL | +| SmartThings | STS-IRM-250 | Motion, Temperature, Battery | Standard ZCL | +| SmartThings | STS-IRM-251 | Motion, Temperature, Battery | Standard ZCL | +| SmartThings | STS-OUT-US-2 | | Standard ZCL | +| SmartThings | STS-PRS-251 | Motion, Battery | Standard ZCL | +| SmartThings | STS-WTR-250 | Water, Battery, Temperature | Standard ZCL | +| SmartThings | STSS-IRM-001 | Motion | Standard ZCL | +| SmartThings | STSS-MULT-001 | Contact | Standard ZCL | +| SmartThings | STSS-PRES-001 | Motion, Battery | Standard ZCL | +| SmartThings | WTR-UK-V2 | Water, Temperature, Battery | Standard ZCL | +| Smartenit | 4040B | | Standard ZCL | +| Smartenit | ZBHT-1 | Battery, Temperature, Humidity | Standard ZCL | +| Soanalarm | SNT858Z | Temperature, Soil Moisture, Battery | Tuya | +| SolarEdge | SEHAZB-DR-SWITCH-2 | | Standard ZCL | +| Somfy | 1811681 | Motion, Battery | Standard ZCL | +| Somfy | 1822647A | | Standard ZCL | +| Somfy | 1871154 | Battery | Standard ZCL | +| Somfy | 1871215B | | Standard ZCL | +| Somgoms | ZSTY-SM-11ZG-US-W | | Standard ZCL | +| Somgoms | ZSTY-SM-1DMZG-US-W | | Standard ZCL | +| Sowilo DS | L258 | | Standard ZCL | +| Spacetronik | ZB-DG02 | Gas | Tuya | +| Spacetronik | ZB-DG03 | Gas | Tuya | +| Spotmau | SP-PS1-02 | | Standard ZCL | +| Spotmau | SP-PS2-02 | | Standard ZCL | +| Spotmau | SP-PS3-02 | | Standard ZCL | +| Spotmau | SP-WS-02 | | Standard ZCL | +| Sprut.device | Bed.box | | Standard ZCL | +| Stello | STLO-23 | | Standard ZCL | +| Stello | STLO-34 | | Standard ZCL | +| Stelpro | HT402 | | Standard ZCL | +| Stelpro | SMT402 | Humidity | Standard ZCL | +| Stelpro | SMT402AD | Humidity | Standard ZCL | +| Stelpro | STZB402 | Humidity | Standard ZCL | +| Sunricher | 50208693 | Battery | Standard ZCL | +| Sunricher | 50208702 | | Standard ZCL | +| Sunricher | HK-SENSOR-4IN1-A | Motion, Battery, Temperature, Humidity, Illuminance | Standard ZCL | +| Sunricher | HK-SL-DIM-AU-R-A | | Standard ZCL | +| Sunricher | HK-SL-DIM-US-A | | Standard ZCL | +| Sunricher | HK-ZD-CCT-A | | Standard ZCL | +| Sunricher | SR-ZG2803-G4-5C | Battery | Standard ZCL | +| Sunricher | SR-ZG2819S-DIM | Battery | Standard ZCL | +| Sunricher | SR-ZG2835PAC-AU | | Standard ZCL | +| Sunricher | SR-ZG2835RAC-NK4 | | Standard ZCL | +| Sunricher | SR-ZG2835RAC-UK | | Standard ZCL | +| Sunricher | SR-ZG2836D5 | Battery | Standard ZCL | +| Sunricher | SR-ZG2836D5-G4 | Battery | Standard ZCL | +| Sunricher | SR-ZG2868EK7-CCT | Battery | Standard ZCL | +| Sunricher | SR-ZG2868EK7-DIM | Battery | Standard ZCL | +| Sunricher | SR-ZG2868K12-DIM | Battery | Standard ZCL | +| Sunricher | SR-ZG9001K12-DIM-Z4 | Battery | Standard ZCL | +| Sunricher | SR-ZG9001K12-DIM-Z5 | Battery | Standard ZCL | +| Sunricher | SR-ZG9001K2-DIM | Battery | Standard ZCL | +| Sunricher | SR-ZG9001K2-DIM2 | Battery | Standard ZCL | +| Sunricher | SR-ZG9001K8-DIM | Battery | Standard ZCL | +| Sunricher | SR-ZG9001T2-SW | | Standard ZCL | +| Sunricher | SR-ZG9001T4-DIM-EU | | Standard ZCL | +| Sunricher | SR-ZG9010A | Contact, Battery | Standard ZCL | +| Sunricher | SR-ZG9011A-DS | Contact, Battery | Standard ZCL | +| Sunricher | SR-ZG9023A-EU | | Standard ZCL | +| Sunricher | SR-ZG9030A-MW | Motion, Illuminance | Standard ZCL | +| Sunricher | SR-ZG9030F-PS | Motion, Illuminance | Standard ZCL | +| Sunricher | SR-ZG9032A-MW | Motion, Illuminance | Standard ZCL | +| Sunricher | SR-ZG9032A-PIR | Motion, Illuminance | Standard ZCL | +| Sunricher | SR-ZG9033TH | Battery, Temperature, Humidity | Standard ZCL | +| Sunricher | SR-ZG9040A-S | | Standard ZCL | +| Sunricher | SR-ZG9040A/ZG9041A-D | | Standard ZCL | +| Sunricher | SR-ZG9041A-2R | | Standard ZCL | +| Sunricher | SR-ZG9041A-R | | Standard ZCL | +| Sunricher | SR-ZG9042MP | | Standard ZCL | +| Sunricher | SR-ZG9050B-WS | Battery, Temperature | Standard ZCL | +| Sunricher | SR-ZG9081A | | Standard ZCL | +| Sunricher | SR-ZG9092A | | Standard ZCL | +| Sunricher | SR-ZG9098A-Light | | Standard ZCL | +| Sunricher | SR-ZG9098A-Win | | Standard ZCL | +| Sunricher | SR-ZG9100A-S | | Standard ZCL | +| Sunricher | SR-ZG9101CS | | Standard ZCL | +| Sunricher | SR-ZG9101SAC-HP-CLN | | Standard ZCL | +| Sunricher | SR-ZG9101SAC-HP-SWITCH-2CH | | Standard ZCL | +| Sunricher | SR-ZG9101SAC-HP2 | | Standard ZCL | +| Sunricher | SRP-ZG9105-CC | | Standard ZCL | +| Sunricher | SRP-ZG9105-CV | | Standard ZCL | +| Sunricher | ZG192910-4 | | Standard ZCL | +| Sunricher | ZG2819S-CCT | Battery | Standard ZCL | +| Sunricher | ZG2819S-RGBW | Battery | Standard ZCL | +| Sunricher | ZG2835 | | Standard ZCL | +| Sunricher | ZG2835RAC | | Standard ZCL | +| Sunricher | ZG2855-RGB | Battery | Standard ZCL | +| Sunricher | ZG2858A | Battery | Standard ZCL | +| Sunricher | ZG9101SAC-HP | | Standard ZCL | +| Sunricher | ZG9101SAC-HP-Switch | | Standard ZCL | +| Sunricher | ZG9101SAC-HP-Switch-B | | Standard ZCL | +| Sunricher | ZGRC-KEY-017 | Battery | Standard ZCL | +| SuperLED | 70012 | | Standard ZCL | +| Svetomaniya | LDR-GU10-Mod | | Standard ZCL | +| Svetomaniya | QS-Zigbee-SEC01-Mod | | Standard ZCL | +| Svetomaniya | QS-Zigbee-SEC02-Mod | | Standard ZCL | +| Swann | SWO-MOS1PA | Motion | Standard ZCL | +| Swann | SWO-WDS1PA | Contact | Standard ZCL | +| Sylvania | 484719 | | Standard ZCL | +| Sylvania | 70552 | | Standard ZCL | +| Sylvania | 71831 | | Standard ZCL | +| Sylvania | 72567 | | Standard ZCL | +| Sylvania | 72569 | | Standard ZCL | +| Sylvania | 72922-A | | Standard ZCL | +| Sylvania | 73693 | | Standard ZCL | +| Sylvania | 73739 | | Standard ZCL | +| Sylvania | 73740 | | Standard ZCL | +| Sylvania | 73741 | | Standard ZCL | +| Sylvania | 73742 | | Standard ZCL | +| Sylvania | 73743 | Battery | Standard ZCL | +| Sylvania | 73773 | | Standard ZCL | +| Sylvania | 73807 | | Standard ZCL | +| Sylvania | 74282 | | Standard ZCL | +| Sylvania | 74283 | | Standard ZCL | +| Sylvania | 74388 | Contact, Battery, Temperature | Standard ZCL | +| Sylvania | 74453 | | Standard ZCL | +| Sylvania | 74580 | | Standard ZCL | +| Sylvania | 74696 | | Standard ZCL | +| Sylvania | 75541 | | Standard ZCL | +| Sylvania | 75564 | | Standard ZCL | +| Sylvania | LTFY004 | | Standard ZCL | +| TCI | 122576 | | Standard ZCL | +| TCI | 151570 | | Standard ZCL | +| TCI | 676-00301024955Z | | Standard ZCL | +| TCI | TCI - Mini ZLL I | | Standard ZCL | +| TCL | P2-WT | Water, Battery | Standard ZCL | +| TECH | VNTH-T2_v1 | Battery | Tuya | +| TECH | VNTH-T2_v2 | Battery | Tuya | +| TERNCY | CL001 | | Standard ZCL | +| TERNCY | DIM003 | | Standard ZCL | +| TERNCY | DL001 | | Standard ZCL | +| TERNCY | TERNCY-DC01 | Contact, Temperature, Battery | Standard ZCL | +| TERNCY | TERNCY-LS01 | | Standard ZCL | +| TERNCY | TERNCY-PP01 | Motion, Temperature, Illuminance | Standard ZCL | +| TERNCY | TERNCY-WS01 | | Standard ZCL | +| TERNCY | TERNCY-WS07-D3 | | Standard ZCL | +| THALEOS | TWC-R01 | | Tuya | +| TIS Control | BEE PIR 1 | Motion, Battery | Standard ZCL | +| TLW Global | K10-1220Z | | Standard ZCL | +| TLW Global | K10-1230Z | | Standard ZCL | +| TLW Global | K10-1250Z | | Standard ZCL | +| TNCE | RMDZB-1PNL63 | Temperature | Tuya | +| TNCE | TNCE_CLIMATE | Temperature, Humidity, Battery | Standard ZCL | +| TOMZN | DDS238-1-Z1 | | Tuya | +| TP-Link | CS100 | Contact, Battery | Standard ZCL | +| TP-Link | MS100 | Motion, Battery, Illuminance | Standard ZCL | +| Tapestry | THPZ1 | Motion, Temperature, Humidity | Standard ZCL | +| Task Lighting | T-TWAV-60W-PSR | | Standard ZCL | +| Technicolor | XHK1-TC | Motion, Battery, Contact, Temperature | Standard ZCL | +| Tervix | \_TZE284_6kijc7nd | Humidity | Tuya | +| The Light Group | S24013 | | Standard ZCL | +| The Light Group | S24019 | | Standard ZCL | +| The Light Group | S32053 | | Standard ZCL | +| The Light Group | S32055 | | Standard ZCL | +| The Light Group | S57003 | Battery | Standard ZCL | +| The Light Group | S57007 | Battery | Standard ZCL | +| Third Reality | 3RAQ1096Z | Temperature, Humidity | Standard ZCL | +| Third Reality | 3RCB01057Z | | Standard ZCL | +| Third Reality | 3RDP01072Z | | Standard ZCL | +| Third Reality | 3RDS17BZ | Contact, Battery | Standard ZCL | +| Third Reality | 3RDTS01056Z | Contact, Battery | Standard ZCL | +| Third Reality | 3RMS16BZ | Motion, Battery | Standard ZCL | +| Third Reality | 3RPL01084Z | Motion, Illuminance | Standard ZCL | +| Third Reality | 3RPS01083Z | Motion, Battery | Standard ZCL | +| Third Reality | 3RSL011Z | | Standard ZCL | +| Third Reality | 3RSL012Z | | Standard ZCL | +| Third Reality | 3RSM0147Z | Temperature, Soil Moisture, Battery | Standard ZCL | +| Third Reality | 3RSM0347Z | Battery, Temperature, Soil Moisture | Standard ZCL | +| Third Reality | 3RSMR01067Z | Motion, Battery | Standard ZCL | +| Third Reality | 3RSNL02043Z | Motion, Illuminance | Standard ZCL | +| Third Reality | 3RSP019BZ | | Standard ZCL | +| Third Reality | 3RSP02028BZ | | Standard ZCL | +| Third Reality | 3RSP02064Z | | Standard ZCL | +| Third Reality | 3RSPE01044BZ | | Standard ZCL | +| Third Reality | 3RSS007Z | | Standard ZCL | +| Third Reality | 3RSS008Z | Battery | Standard ZCL | +| Third Reality | 3RSS009Z | Battery | Standard ZCL | +| Third Reality | 3RTHS0224Z | Temperature, Humidity, Battery | Standard ZCL | +| Third Reality | 3RTHS0324Z | Battery, Temperature, Humidity | Standard ZCL | +| Third Reality | 3RTHS24BZ | Temperature, Humidity, Battery | Standard ZCL | +| Third Reality | 3RVS01031Z | Vibration, Battery | Standard ZCL | +| Third Reality | 3RWK0148Z | Battery | Standard ZCL | +| Third Reality | 3RWS0218Z | Water, Battery | Standard ZCL | +| Third Reality | 3RWS18BZ | Water, Battery | Standard ZCL | +| Titan Products | TPZRCO2HT-Z3 | Humidity, Temperature | Standard ZCL | +| Tongou | TO-Q-SA1 | Temperature | Tuya | +| Tongou | TO-Q-SYS-JZT | Temperature | Tuya | +| Tongou | TOQCB2-80 | Temperature | Tuya | +| Tongou | TOWSMR1 | Temperature | Tuya | +| Trust | ZCM-300 | | Standard ZCL | +| Trust | ZCTS-808 | Contact, Battery | Standard ZCL | +| Trust | ZLED-2709 | | Standard ZCL | +| Trust | ZLED-RGB9 | | Standard ZCL | +| Trust | ZLED-TUNE9 | | Standard ZCL | +| Trust | ZPIR-8000 | Motion, Battery | Standard ZCL | +| Trust | ZSDR-850 | Smoke, Battery | Standard ZCL | +| Trust | ZWLD-100 | Water, Battery | Standard ZCL | +| Trust | ZYCT-202 | | Standard ZCL | +| Tuya | 228WZH | Smoke, Temperature, Humidity | Tuya | +| Tuya | 2CT | | Tuya | +| Tuya | AETZ01_AC | | Tuya | +| Tuya | ATMS1601Z | | Standard ZCL | +| Tuya | BAB-1413_Pro | Battery | Tuya | +| Tuya | BLE-YL01 | Temperature, Battery | Tuya | +| Tuya | CK-BL702-AL-01 | | Standard ZCL | +| Tuya | CK-BL702-AL-01(7008_Z102LG01-1) | | Standard ZCL | +| Tuya | CTL-R1-TY-Zigbee | Motion, Illuminance | Tuya | +| Tuya | DCR-CO | Carbon Monoxide | Standard ZCL | +| Tuya | DCR-RQJ | Carbon Monoxide, Gas | Tuya | +| Tuya | DS-1450WN | | Tuya | +| Tuya | E220-KR4N0Z0-HA | | Standard ZCL | +| Tuya | EA4161C-BI | | Tuya | +| Tuya | ERS-10TZBVK-AA | Battery | Standard ZCL | +| Tuya | F3-Pro | | Standard ZCL | +| Tuya | IH-K009 | Temperature, Humidity, Battery | Standard ZCL | +| Tuya | IH012-RT01 | Motion, Battery | Standard ZCL | +| Tuya | IH012-RT02 | Motion, Battery | Standard ZCL | +| Tuya | JKD-816COM-Z | Carbon Monoxide, Gas | Tuya | +| Tuya | JM-TRH-ZGB-V1 | Temperature, Humidity, Battery | Standard ZCL | +| Tuya | KCTW1Z | Temperature, Humidity, Battery | Standard ZCL | +| Tuya | LCZ030 | Temperature, Humidity, Battery, Illuminance | Standard ZCL | +| Tuya | LKTMZL02-z | Temperature, Humidity, Battery | Standard ZCL | +| Tuya | LYAI-14 | Battery | Standard ZCL | +| Tuya | M8Pro | | Standard ZCL | +| Tuya | M9-zigbee-SL | Motion | Tuya | +| Tuya | M9-zigbee-SL-2 | Motion | Tuya | +| Tuya | M9Pro | | Standard ZCL | +| Tuya | ME201WZ | | Tuya | +| Tuya | MG-GPO04ZSLP | | Tuya | +| Tuya | MG-ZG01W | | Tuya | +| Tuya | MG-ZG02W | | Standard ZCL | +| Tuya | MG-ZG03W | | Standard ZCL | +| Tuya | MIR-HE200-TY | Motion, Illuminance | Tuya | +| Tuya | MTG075-ZB-RL | Motion, Illuminance | Tuya | +| Tuya | PA-44Z | Smoke, Battery | Tuya | +| Tuya | PC311-Z-TY | | Tuya | +| Tuya | PJ-1203A | | Tuya | +| Tuya | PJ-MGW1203 | | Tuya | +| Tuya | PM2.5_airbox | Temperature, Humidity | Tuya | +| Tuya | QS-Zigbee-SEC01-DC | | Standard ZCL | +| Tuya | QS-Zigbee-SEC01-U | | Standard ZCL | +| Tuya | QS-Zigbee-SEC02-U | | Standard ZCL | +| Tuya | R3 Smart Switch | | Standard ZCL | +| Tuya | RH3040 | Motion, Battery | Standard ZCL | +| Tuya | RSH-HS06 | Temperature, Humidity, Battery | Tuya | +| Tuya | RT_ZCZ03Z | Motion, Illuminance | Tuya | +| Tuya | S-LUX-ZB | Battery, Illuminance | Standard ZCL | +| Tuya | SA12IZL | Smoke, Battery | Standard ZCL | +| Tuya | SDM01 | | Tuya | +| Tuya | SDM01V1-GT | | Tuya | +| Tuya | SDM01V1.5 | | Tuya | +| Tuya | SDM02V1 | | Tuya | +| Tuya | SDM02V1-GT | | Tuya | +| Tuya | SGS02Z | Temperature, Soil Moisture, Battery | Tuya | +| Tuya | SM0001 | | Standard ZCL | +| Tuya | SM0201 | Battery, Temperature, Humidity | Standard ZCL | +| Tuya | SM0202 | Motion, Battery | Standard ZCL | +| Tuya | SMKG-2KNL-SD | Temperature | Tuya | +| Tuya | SNTZ007 | Contact, Battery | Standard ZCL | +| Tuya | SNTZ009 | Water | Standard ZCL | +| Tuya | SPM01 | | Tuya | +| Tuya | SPM01V1-GT | | Tuya | +| Tuya | SPM01V2 | | Tuya | +| Tuya | SPM01V2.5 | | Tuya | +| Tuya | SPM02 | | Tuya | +| Tuya | SPM02V1-GT | | Tuya | +| Tuya | SPM02V2 | | Tuya | +| Tuya | SPM02V2.5 | | Tuya | +| Tuya | SPM02V3 | | Tuya | +| Tuya | SWS6TZ-WHITE | | Tuya | +| Tuya | SZR07U | Motion | Tuya | +| Tuya | SZT06 V2.0 | Temperature, Humidity, Battery | Standard ZCL | +| Tuya | THE01860A | Battery, Temperature, Humidity, Illuminance | Standard ZCL | +| Tuya | THS317-ET-TY | Temperature, Battery | Tuya | +| Tuya | TM001-ZA/TM081 | Contact, Battery | Standard ZCL | +| Tuya | TRV601 | Battery | Tuya | +| Tuya | TRV602 | Battery | Tuya | +| Tuya | TRV602Z | Battery | Tuya | +| Tuya | TS0001 | | Standard ZCL | +| Tuya | TS0001_1_gang_switch | | Standard ZCL | +| Tuya | TS0001_fingerbot | Battery | Tuya | +| Tuya | TS0001_power | | Standard ZCL | +| Tuya | TS0001_switch_1_gang | | Standard ZCL | +| Tuya | TS0001_switch_module | | Standard ZCL | +| Tuya | TS0001_switch_module_1 | | Standard ZCL | +| Tuya | TS0001_switch_module_2 | | Standard ZCL | +| Tuya | TS0002 | | Standard ZCL | +| Tuya | TS0002_basic | | Standard ZCL | +| Tuya | TS0002_limited | | Standard ZCL | +| Tuya | TS0002_power | | Standard ZCL | +| Tuya | TS0003 | | Standard ZCL | +| Tuya | TS0003_3_gang_switch | | Standard ZCL | +| Tuya | TS0003_switch_3_gang | | Standard ZCL | +| Tuya | TS0003_switch_3_gang_with_backlight | | Standard ZCL | +| Tuya | TS0003_switch_module_1 | | Standard ZCL | +| Tuya | TS0003_switch_module_2 | | Standard ZCL | +| Tuya | TS0003_switch_module_3 | | Standard ZCL | +| Tuya | TS0004 | | Standard ZCL | +| Tuya | TS0004_fan_light_switch | | Standard ZCL | +| Tuya | TS0004_switch_module | | Standard ZCL | +| Tuya | TS0004_switch_module_2 | | Standard ZCL | +| Tuya | TS0006 | | Standard ZCL | +| Tuya | TS000F_power | | Standard ZCL | +| Tuya | TS0011 | | Standard ZCL | +| Tuya | TS0011_switch_module | | Standard ZCL | +| Tuya | TS0012 | | Standard ZCL | +| Tuya | TS0012_switch_module | | Standard ZCL | +| Tuya | TS0013 | | Standard ZCL | +| Tuya | TS0013_switch_module | | Standard ZCL | +| Tuya | TS0014 | | Standard ZCL | +| Tuya | TS0026 | | Standard ZCL | +| Tuya | TS0049 | | Standard ZCL | +| Tuya | TS004F | Battery | Standard ZCL | +| Tuya | TS004F_6_button | Battery | Standard ZCL | +| Tuya | TS0052 | | Standard ZCL | +| Tuya | TS0052_2 | | Standard ZCL | +| Tuya | TS0101 | | Standard ZCL | +| Tuya | TS0105 | | Standard ZCL | +| Tuya | TS0108 | | Standard ZCL | +| Tuya | TS0111 | | Standard ZCL | +| Tuya | TS0111_valve | | Standard ZCL | +| Tuya | TS0115 | | Standard ZCL | +| Tuya | TS011F_1 | | Standard ZCL | +| Tuya | TS011F_2_gang_2_usb_wall | | Standard ZCL | +| Tuya | TS011F_2_gang_power | | Standard ZCL | +| Tuya | TS011F_2_gang_wall | | Standard ZCL | +| Tuya | TS011F_3_gang | | Standard ZCL | +| Tuya | TS011F_4 | | Standard ZCL | +| Tuya | TS011F_5 | | Standard ZCL | +| Tuya | TS011F_din_smart_relay | | Standard ZCL | +| Tuya | TS011F_din_smart_relay_polling | | Standard ZCL | +| Tuya | TS011F_plug_1 | | Standard ZCL | +| Tuya | TS011F_plug_2 | | Standard ZCL | +| Tuya | TS011F_plug_3 | | Standard ZCL | +| Tuya | TS011F_quad_power1 | | Standard ZCL | +| Tuya | TS011F_socket_module | | Standard ZCL | +| Tuya | TS011F_switch_5_gang | | Standard ZCL | +| Tuya | TS011F_wall_outlet | | Standard ZCL | +| Tuya | TS011F_with_threshold | Temperature | Standard ZCL | +| Tuya | TS0121_plug | | Standard ZCL | +| Tuya | TS0201 | Battery, Temperature, Humidity | Standard ZCL | +| Tuya | TS0201-z | Temperature, Humidity, Battery | Standard ZCL | +| Tuya | TS0202 | Motion, Battery | Standard ZCL | +| Tuya | TS0202_1 | Motion, Battery | Standard ZCL | +| Tuya | TS0202_2 | Motion, Battery | Standard ZCL | +| Tuya | TS0202_3 | Motion, Battery, Illuminance | Standard ZCL | +| Tuya | TS0203 | Contact, Battery | Standard ZCL | +| Tuya | TS0203_1 | Contact, Battery | Standard ZCL | +| Tuya | TS0204 | Gas | Standard ZCL | +| Tuya | TS0205 | Smoke, Battery | Standard ZCL | +| Tuya | TS0207_water_leak_detector | Water, Battery | Standard ZCL | +| Tuya | TS020C | Motion, Battery, Illuminance | Tuya | +| Tuya | TS0210 | Vibration, Battery | Standard ZCL | +| Tuya | TS0222 | Battery, Illuminance | Standard ZCL | +| Tuya | TS0222_light | Battery, Illuminance | Standard ZCL | +| Tuya | TS0222_solar_light | Illuminance, Battery | Standard ZCL | +| Tuya | TS0222_temperature_humidity | Battery, Temperature, Humidity, Illuminance | Standard ZCL | +| Tuya | TS0501A | | Standard ZCL | +| Tuya | TS0501B | | Standard ZCL | +| Tuya | TS0501B_dimmer | | Standard ZCL | +| Tuya | TS0501B_dimmer_2 | | Standard ZCL | +| Tuya | TS0502A | | Standard ZCL | +| Tuya | TS0502B | | Standard ZCL | +| Tuya | TS0503A | | Standard ZCL | +| Tuya | TS0503B | | Standard ZCL | +| Tuya | TS0504A | | Standard ZCL | +| Tuya | TS0504B | | Standard ZCL | +| Tuya | TS0505 | | Standard ZCL | +| Tuya | TS0505A | | Standard ZCL | +| Tuya | TS0505A_led | | Standard ZCL | +| Tuya | TS0505B_1 | | Standard ZCL | +| Tuya | TS0505B_2 | | Standard ZCL | +| Tuya | TS0505B_3 | | Standard ZCL | +| Tuya | TS0601-PIR-Sensor | Motion, Illuminance, Battery | Tuya | +| Tuya | TS0601_1gang_switch | | Standard ZCL | +| Tuya | TS0601_2gang_switch | | Standard ZCL | +| Tuya | TS0601_3_phase_clamp_meter | Temperature | Tuya | +| Tuya | TS0601_3_phase_clamp_meter_relay | | Tuya | +| Tuya | TS0601_3gang_rkbxtclc | | Standard ZCL | +| Tuya | TS0601_3gang_switch | | Standard ZCL | +| Tuya | TS0601_4gang_7ytnacie | | Standard ZCL | +| Tuya | TS0601_6gang_switch | | Standard ZCL | +| Tuya | TS0601_GTZ10 | Battery | Tuya | +| Tuya | TS0601_TZE284_gnpflcoq | Motion, Illuminance, Temperature, Humidity, Battery | Tuya | +| Tuya | TS0601_air_quality_sensor | Temperature, Humidity | Standard ZCL | +| Tuya | TS0601_airbox | Temperature, Humidity | Tuya | +| Tuya | TS0601_bed_presence_sensor | Motion, Battery, Illuminance | Tuya | +| Tuya | TS0601_bidirectional_energy meter | | Tuya | +| Tuya | TS0601_co2_sensor | | Standard ZCL | +| Tuya | TS0601_contact_temperature_humidity_sensor | Contact, Temperature, Humidity, Battery | Tuya | +| Tuya | TS0601_cover_6 | Battery, Illuminance | Tuya | +| Tuya | TS0601_cover_switch_2 | | Standard ZCL | +| Tuya | TS0601_cover_with_1_switch | | Standard ZCL | +| Tuya | TS0601_cover_with_2_switch | | Standard ZCL | +| Tuya | TS0601_dimmer_1_gang_1 | | Standard ZCL | +| Tuya | TS0601_dimmer_1_gang_2 | | Standard ZCL | +| Tuya | TS0601_dimmer_1_gang_3 | | Tuya | +| Tuya | TS0601_dimmer_2 | | Standard ZCL | +| Tuya | TS0601_dimmer_3 | | Standard ZCL | +| Tuya | TS0601_dimmer_4 | | Standard ZCL | +| Tuya | TS0601_dimmer_5 | | Standard ZCL | +| Tuya | TS0601_dimmer_knob | | Standard ZCL | +| Tuya | TS0601_din | | Standard ZCL | +| Tuya | TS0601_din_1 | | Tuya | +| Tuya | TS0601_din_2 | | Tuya | +| Tuya | TS0601_din_3 | | Tuya | +| Tuya | TS0601_din_4 | Temperature | Tuya | +| Tuya | TS0601_fan_5_levels_and_light_5_levels | | Standard ZCL | +| Tuya | TS0601_fan_5_levels_and_light_switch | | Standard ZCL | +| Tuya | TS0601_fan_and_light_switch | | Standard ZCL | +| Tuya | TS0601_fan_switch | | Standard ZCL | +| Tuya | TS0601_gas_sensor_1 | Gas | Tuya | +| Tuya | TS0601_gas_sensor_2 | Gas | Tuya | +| Tuya | TS0601_gas_sensor_3 | Gas | Tuya | +| Tuya | TS0601_gas_sensor_4 | Gas | Tuya | +| Tuya | TS0601_human_presence_sensor | Motion | Standard ZCL | +| Tuya | TS0601_illuminance_temperature_humidity_sensor_1 | Temperature, Humidity, Illuminance, Battery | Standard ZCL | +| Tuya | TS0601_illuminance_temperature_humidity_sensor_2 | Illuminance, Temperature, Humidity | Tuya | +| Tuya | TS0601_knob_dimmer_switch | | Standard ZCL | +| Tuya | TS0601_light | | Standard ZCL | +| Tuya | TS0601_motion_sensor | Motion | Standard ZCL | +| Tuya | TS0601_multifunction_switch | | Standard ZCL | +| Tuya | TS0601_pir | Motion, Illuminance, Battery | Tuya | +| Tuya | TS0601_pir_solar | Motion, Battery | Tuya | +| Tuya | TS0601_power_monitoring_switch | | Tuya | +| Tuya | TS0601_rcbo | Temperature | Standard ZCL | +| Tuya | TS0601_smart_air_house_keeper | Temperature, Humidity | Standard ZCL | +| Tuya | TS0601_smart_human_presence_sensor_1 | Motion, Illuminance | Standard ZCL | +| Tuya | TS0601_smart_temperature_switch | | Standard ZCL | +| Tuya | TS0601_smoke_1 | Smoke | Tuya | +| Tuya | TS0601_smoke_3 | Smoke | Tuya | +| Tuya | TS0601_smoke_4 | Smoke, Battery | Tuya | +| Tuya | TS0601_smoke_5 | Smoke, Battery | Tuya | +| Tuya | TS0601_smoke_6 | Smoke | Tuya | +| Tuya | TS0601_smoke_co | Smoke, Battery, Carbon Monoxide | Tuya | +| Tuya | TS0601_soil | Temperature, Soil Moisture, Battery | Tuya | +| Tuya | TS0601_soil_2 | Soil Moisture, Temperature, Battery | Tuya | +| Tuya | TS0601_soil_3 | Temperature, Soil Moisture, Battery | Tuya | +| Tuya | TS0601_stairwell_switch | | Standard ZCL | +| Tuya | TS0601_switch | | Standard ZCL | +| Tuya | TS0601_switch_10 | | Standard ZCL | +| Tuya | TS0601_switch_1_gang | | Standard ZCL | +| Tuya | TS0601_switch_2_gang | | Standard ZCL | +| Tuya | TS0601_switch_3_gang | | Standard ZCL | +| Tuya | TS0601_switch_4_gang_1 | | Standard ZCL | +| Tuya | TS0601_switch_4_gang_2 | | Standard ZCL | +| Tuya | TS0601_switch_5_gang | | Standard ZCL | +| Tuya | TS0601_switch_6_gang | | Standard ZCL | +| Tuya | TS0601_switch_8_2 | | Standard ZCL | +| Tuya | TS0601_temperature_humidity_co2_sensor | Temperature, Humidity | Standard ZCL | +| Tuya | TS0601_temperature_humidity_sensor_1 | Temperature, Humidity, Battery | Standard ZCL | +| Tuya | TS0601_temperature_humidity_sensor_2 | Temperature, Humidity | Tuya | +| Tuya | TS0601_temperature_humidity_sensor_3 | Temperature, Humidity, Battery | Tuya | +| Tuya | TS0601_temperature_humidity_sensor_4 | Temperature, Humidity, Battery | Tuya | +| Tuya | TS0601_thermostat | | Standard ZCL | +| Tuya | TS0601_thermostat_1 | Battery | Tuya | +| Tuya | TS0601_thermostat_6 | Battery | Tuya | +| Tuya | TS0601_vibration_sensor | Contact, Battery, Vibration | Standard ZCL | +| Tuya | TS0601_water_meter | Temperature | Tuya | +| Tuya | TS0601_water_sensor | Water | Standard ZCL | +| Tuya | TS0601_water_switch | Battery | Tuya | +| Tuya | TS0601_water_valve | Temperature | Tuya | +| Tuya | TS0601_water_valve_1 | | Standard ZCL | +| Tuya | TS0726_1_gang | | Standard ZCL | +| Tuya | TS0726_1_gang_scene_switch | | Standard ZCL | +| Tuya | TS0726_2_gang | | Standard ZCL | +| Tuya | TS0726_2_gang_scene_switch | | Standard ZCL | +| Tuya | TS0726_3_gang | | Standard ZCL | +| Tuya | TS0726_3_gang_scene_switch | | Standard ZCL | +| Tuya | TS0726_4_gang | | Standard ZCL | +| Tuya | TS0726_4_gang_scene_switch | | Standard ZCL | +| Tuya | TS0726_4_gang_switch_and_2_scene | | Standard ZCL | +| Tuya | TS0726_4_gang_switch_and_4_scene | | Standard ZCL | +| Tuya | TS0726_multi_1_gang | | Standard ZCL | +| Tuya | TS0726_multi_3_gang | | Standard ZCL | +| Tuya | TS0726_multi_4_gang | | Standard ZCL | +| Tuya | TS0726_switch_4g_2s | | Standard ZCL | +| Tuya | TS0901 | Battery | Standard ZCL | +| Tuya | TS1101_dimmer_module_1ch | | Standard ZCL | +| Tuya | TS1101_dimmer_module_2ch | | Standard ZCL | +| Tuya | TS110E_1gang_1 | | Standard ZCL | +| Tuya | TS110E_1gang_2 | | Standard ZCL | +| Tuya | TS110E_2gang_1 | | Standard ZCL | +| Tuya | TS110E_2gang_2 | | Standard ZCL | +| Tuya | TT001ZAV20 | Humidity, Temperature, Battery | Standard ZCL | +| Tuya | TW-03 | | Standard ZCL | +| Tuya | TYZS1L | | Standard ZCL | +| Tuya | TZ-ZT01_GA4 | Temperature, Humidity | Tuya | +| Tuya | WHD02 | | Standard ZCL | +| Tuya | WLS-100z | Water, Battery | Standard ZCL | +| Tuya | WSD500A | Battery, Temperature, Humidity | Standard ZCL | +| Tuya | WZ5_rgb_1 | | Standard ZCL | +| Tuya | XFY-CGQ-ZIGB | Illuminance | Standard ZCL | +| Tuya | Y1_IN | Motion, Illuminance | Tuya | +| Tuya | YSR-MINI-Z | Battery | Standard ZCL | +| Tuya | YXZBRB58 | Motion, Illuminance | Tuya | +| Tuya | ZBN-DJ-63 | Temperature | Tuya | +| Tuya | ZBN-JT-63 | | Tuya | +| Tuya | ZD24_Presence_Sensor | Motion, Illuminance, Battery | Tuya | +| Tuya | ZF24 | Motion, Illuminance | Tuya | +| Tuya | ZF24Pro | Motion, Illuminance, Temperature, Humidity | Tuya | +| Tuya | ZG-102Z | Contact, Battery | Tuya | +| Tuya | ZG-102ZL | Contact, Illuminance, Battery | Tuya | +| Tuya | ZG-103Z | Vibration, Battery | Tuya | +| Tuya | ZG-204ZL | Motion, Illuminance, Battery | Tuya | +| Tuya | ZG-204ZM | Motion, Battery, Illuminance | Tuya | +| Tuya | ZG-205Z | Motion, Illuminance | Tuya | +| Tuya | ZG-205Z/A | Motion, Illuminance | Tuya | +| Tuya | ZG-205ZL | Motion, Illuminance | Tuya | +| Tuya | ZG-225Z | Gas | Tuya | +| Tuya | ZG-227Z-z | Temperature, Humidity, Battery | Standard ZCL | +| Tuya | ZG-227ZL | Temperature, Humidity, Battery | Tuya | +| Tuya | ZG-WK-DA-Wh-Zigbee | Humidity | Standard ZCL | +| Tuya | ZM-35H-Q | Motion, Battery | Standard ZCL | +| Tuya | ZN231392 | | Standard ZCL | +| Tuya | ZN2S-RS02E | | Standard ZCL | +| Tuya | ZPIR-10 | Motion, Battery, Illuminance | Tuya | +| Tuya | ZS-TYG3-SM-21Z | | Standard ZCL | +| Tuya | ZS-TYG3-SM-31Z | | Standard ZCL | +| Tuya | ZS-TYG3-SM-41Z | | Standard ZCL | +| Tuya | ZS-TYG3-SM-61Z | | Standard ZCL | +| Tuya | ZSS-QY-SSD-A-EN | Smoke, Battery | Tuya | +| Tuya | ZT08 | Temperature, Humidity | Tuya | +| Tuya | ZTH05Z | Temperature, Humidity, Battery | Tuya | +| Tuya | ZY-M100-24G | Motion, Illuminance | Tuya | +| Tuya | ZY-M100-24GV2 | Motion, Illuminance | Tuya | +| Tuya | ZY-M100-24GV3 | Motion, Illuminance | Tuya | +| Tuya | ZY-M100-S_1 | Motion, Illuminance | Tuya | +| Tuya | ZY-M100-S_2 | Motion, Illuminance | Tuya | +| Tuya | ZY-M100-S_3 | Motion, Illuminance | Tuya | +| Tuya | ZY-ZHPS01-24G | Motion, Illuminance | Tuya | +| Tuya | ZY_HPS01 | Motion, Illuminance | Tuya | +| Tuya | \_TZ3000_h1ipgkwn | | Standard ZCL | +| Tuya | \_TZ3000_mw1pqqqt | | Standard ZCL | +| Tuya | \_TZE200_rgeapp2c | | Standard ZCL | +| Tuya | \_TZE204_3regm3h6 | | Tuya | +| Tuya | \_TZE204_w2vunxzm | Pressure, Temperature | Tuya | +| Tuya | \_TZE28C1000000_jlbsptkl | | Standard ZCL | +| Tuya | gq8b1uv | | Standard ZCL | +| Tuya | rtsc11r | Motion, Illuminance | Tuya | +| UHome | TWV | Battery | Standard ZCL | +| Ubisys | C4 | | Standard ZCL | +| Ubisys | D1 | | Standard ZCL | +| Ubisys | H10 | | Standard ZCL | +| Ubisys | J1 | | Standard ZCL | +| Ubisys | S1 | | Standard ZCL | +| Ubisys | S1-R | | Standard ZCL | +| Ubisys | S2 | | Standard ZCL | +| Universal Electronics Inc | UEHK2AZ0 | Motion, Battery, Contact, Temperature | Standard ZCL | +| Universal Electronics Inc | XHK1-UE | Motion, Battery, Contact, Temperature | Standard ZCL | +| Universal Electronics Inc | XHS1-UE | Motion, Temperature, Battery | Standard ZCL | +| Universal Electronics Inc | XHS2-UE | Contact, Temperature, Battery | Standard ZCL | +| VAV | VAV-256215-MOD1 | | Standard ZCL | +| VAV | VAV-256215-MOD2 | | Standard ZCL | +| VBLED | 43023 | | Standard ZCL | +| VSmart | HS-SEDR00ZB-VNM | Contact | Standard ZCL | +| VSmart | HS-SEOC00ZB-VNM | Motion, Battery | Standard ZCL | +| VSmart | HS-SW100ZB-VNM | | Standard ZCL | +| VSmart | HS-SW200ZB-VNM | | Standard ZCL | +| VSmart | HS-SW300ZB-VNM | | Standard ZCL | +| VSmart | HS-SW400ZB-VNM | | Standard ZCL | +| Vesternet | VES-ZB-DIM-004 | | Standard ZCL | +| Vesternet | VES-ZB-HLD-017 | | Standard ZCL | +| Vesternet | VES-ZB-REM-013 | Battery | Standard ZCL | +| Vesternet | VES-ZB-SWI-005 | | Standard ZCL | +| Vesternet | VES-ZB-SWI-015 | | Standard ZCL | +| Vesternet | VES-ZB-WAL-006 | Battery | Standard ZCL | +| Vesternet | VES-ZB-WAL-011 | Battery | Standard ZCL | +| Vesternet | VES-ZB-WAL-012 | Battery | Standard ZCL | +| Videosec | KRC-103 | | Standard ZCL | +| Viessmann | 7377019 | Battery, Temperature, Humidity | Standard ZCL | +| Viessmann | 7963223 | Battery, Temperature, Humidity | Standard ZCL | +| Viessmann | ZK03839 | Battery, Temperature, Humidity | Standard ZCL | +| Villeroy & Boch | C0040000 | | Standard ZCL | +| Villeroy & Boch | C5850000 | | Standard ZCL | +| Villeroy & Boch | EC1366 | | Standard ZCL | +| Vimar | 03981 | | Standard ZCL | +| Vimar | 14592.0 | | Standard ZCL | +| Vimar | 14593 | | Standard ZCL | +| Vimar | 14595.0 | | Standard ZCL | +| Vimar | RemoteControl_v1.0 | | Standard ZCL | +| Visonic | GB-540 | Vibration | Standard ZCL | +| Visonic | MCT-302 SMA | Contact, Temperature, Battery | Standard ZCL | +| Visonic | MCT-340 E | Contact, Temperature, Battery | Standard ZCL | +| Visonic | MCT-340 SMA | Contact, Temperature, Battery | Standard ZCL | +| Visonic | MCT-350 SMA | Contact, Temperature | Standard ZCL | +| Visonic | MCT-370 SMA | Contact | Standard ZCL | +| Visonic | MP-840 | Motion, Temperature, Battery | Standard ZCL | +| Visonic | MP-841 | Motion | Standard ZCL | +| Vrey | VR-X701U | | Standard ZCL | +| WETEN | 1GNNTS | | Standard ZCL | +| WETEN | PCI E | | Standard ZCL | +| Wally | U02I007C.01 | Contact, Battery, Temperature, Humidity, Water | Standard ZCL | +| Waxman | 8850100 | Battery | Standard ZCL | +| Weiser | 9GED18000-009 | Battery | Standard ZCL | +| Weiser | 9GED21500-005 | Battery | Standard ZCL | +| Wenzhi | MTD285-ZB | Motion, Illuminance | Tuya | +| Wenzhi | WZ-M100 | Motion, Illuminance | Tuya | +| Wiren Board | WB-MSW-ZIGBEE_v.4_official | Motion, Illuminance, Temperature, Humidity | Standard ZCL | +| Wirenboard | WB-MSW-ZIGBEE v.3 | Motion, Temperature, Humidity, Illuminance | Standard ZCL | +| Wirenboard | WB-MSW-ZIGBEE v.4 | Motion, Temperature, Humidity, Illuminance | Standard ZCL | +| Wisdom | DMZ250 | | Standard ZCL | +| Woolley | BSD29/BSD59 | | Standard ZCL | +| Woox | R7048 | Battery, Temperature, Humidity | Standard ZCL | +| Woox | R7049 | Smoke | Standard ZCL | +| Woox | R7060 | Battery | Standard ZCL | +| Woox | R7067 | | Standard ZCL | +| Woox | R9077 | | Standard ZCL | +| Wyze | WLCKG1 | Battery | Standard ZCL | +| XAL | 050-0131558M | | Standard ZCL | +| XAL | 050-0511558F | | Standard ZCL | +| XAL | 050-1212558H | | Standard ZCL | +| Xenon Smart | X7726 | Temperature | Tuya | +| Xiaomi | GZCGQ01LM | Battery, Illuminance | Aqara/LUMI | +| Xiaomi | JTQJ-BF-01LM/BW | Gas | Aqara/LUMI | +| Xiaomi | JTYJ-GD-01LM/BW | Smoke, Battery, Device Temp | Aqara/LUMI | +| Xiaomi | LYWSD03MMC-z | Temperature, Humidity, Battery | Aqara/LUMI | +| Xiaomi | MCCGQ01LM | Contact, Battery | Aqara/LUMI | +| Xiaomi | MJWSD06MMC | Temperature, Humidity, Battery | Aqara/LUMI | +| Xiaomi | RTCGQ01LM | Motion, Battery | Aqara/LUMI | +| Xiaomi | WSDCGQ01LM | Battery, Temperature, Humidity | Aqara/LUMI | +| Xiaomi | ZNCZ02LM | Device Temp | Aqara/LUMI | +| Xiaomi | ZNCZ03LM | Device Temp | Aqara/LUMI | +| Xiaomi | ZNCZ04LM | Device Temp | Aqara/LUMI | +| XingHuoYuan | X2SK11 | | Standard ZCL | +| YOKIS | E2BP-UP | | Standard ZCL | +| YOKIS | E2BPA-UP | | Standard ZCL | +| YOKIS | E4BP-UP | | Standard ZCL | +| YOKIS | E4BPX-UP | | Standard ZCL | +| YOKIS | GALET4-UP | Temperature | Standard ZCL | +| YOKIS | MFP-UP | | Standard ZCL | +| YOKIS | MTR1300E-UP | | Standard ZCL | +| YOKIS | MTR2000E-UP | | Standard ZCL | +| YOKIS | MTR500E-UP | | Standard ZCL | +| YOKIS | MTV300E-UP | | Standard ZCL | +| YOKIS | TLC1-UP | Temperature | Standard ZCL | +| YOKIS | TLC2-UP | | Standard ZCL | +| YOKIS | TLC4-UP | | Standard ZCL | +| YOKIS | TLC8-UP | | Standard ZCL | +| YOKIS | TLM1-UP | Temperature | Standard ZCL | +| YOKIS | TLM2-UP | Temperature | Standard ZCL | +| YOKIS | TLM4-UP | Temperature | Standard ZCL | +| YSRSAI | YSR-MINI-01_dimmer | | Standard ZCL | +| YSRSAI | YSR-MINI-01_rgbcct | | Standard ZCL | +| YSRSAI | YSR-MINI-01_wwcw | | Standard ZCL | +| Yale | LIA | Battery | Standard ZCL | +| Yale | SOLIS01 | Battery | Standard ZCL | +| Yale | YAYRD256HA2619 | Battery | Standard ZCL | +| Yale | YDD-D4F0-TSDB | Battery | Standard ZCL | +| Yale | YDF40 | Battery | Standard ZCL | +| Yale | YDM60 | Battery | Standard ZCL | +| Yale | YMC420-W | Battery | Standard ZCL | +| Yale | YMF30 | Battery | Standard ZCL | +| Yale | YMF40/YDM4109+/YDF40 | Battery | Standard ZCL | +| Yale | YMF40A RL | Battery | Standard ZCL | +| Yale | YMI70A | Battery | Standard ZCL | +| Yale | YRD210-HA-605 | Battery | Standard ZCL | +| Yale | YRD216-HA2-619 | Battery | Standard ZCL | +| Yale | YRD220/YRD221 | Battery | Standard ZCL | +| Yale | YRD226/246 TSDB | Battery | Standard ZCL | +| Yale | YRD226HA2619 | Battery | Standard ZCL | +| Yale | YRD246HA20BP | Battery | Standard ZCL | +| Yale | YRD256HA20BP | Battery | Standard ZCL | +| Yale | YRD410-BLE | Battery | Standard ZCL | +| Yale | YRD420-BLE | Battery | Standard ZCL | +| Yale | YRD426NRSC | Battery | Standard ZCL | +| Yale | YRD430-BLE | Battery | Standard ZCL | +| Yale | YRD450-BLE | Battery | Standard ZCL | +| Yale | YRD652HA20BP | Battery | Standard ZCL | +| Yale | YRL-220L | Battery | Standard ZCL | +| Yale | YRL226 TS | Battery | Standard ZCL | +| Yale | YRL226L TS | Battery | Standard ZCL | +| Yale | YRL256 TS | Battery | Standard ZCL | +| Yale | YRM476 | Battery | Standard ZCL | +| Yale | ZYA-C4-MOD-S | Battery | Standard ZCL | +| Yandex | YNDX-00518 | Battery | Standard ZCL | +| Yandex | YNDX_00526 | Contact, Battery | Standard ZCL | +| Yandex | YNDX_00527 | Water, Battery | Standard ZCL | +| Yandex | YNDX_00528 | Motion, Illuminance, Battery | Standard ZCL | +| Yandex | YNDX_00529 | Temperature, Humidity, Pressure, Battery | Standard ZCL | +| Yandex | YNDX_00530 | | Standard ZCL | +| Yandex | YNDX_00531 | | Standard ZCL | +| Yandex | YNDX_00532 | | Standard ZCL | +| Yandex | YNDX_00537 | | Standard ZCL | +| Yandex | YNDX_00538 | | Standard ZCL | +| Ynoa | 8718801528204 | | Standard ZCL | +| Ynoa | 8718801528273 | | Standard ZCL | +| Ynoa | 8718801528334 | Battery | Standard ZCL | +| Ynoa | LA-5KEY-RGBW | Battery | Standard ZCL | +| Ynoa | LA-A60-CCT | | Standard ZCL | +| Ynoa | LA-GU10-RGBW | | Standard ZCL | +| Ynoa | LA-PLUG-10Amp | | Standard ZCL | +| ZSVIOT | PN16 | | Standard ZCL | +| ZSVIOT | PN6 | | Standard ZCL | +| ZYXH | TS0601_switch_12 | | Standard ZCL | +| ZYXH | TS0601_switch_8 | | Standard ZCL | +| ZYXH | ZYXH_switch_24 | | Standard ZCL | +| Zbeacon | MC-z | Temperature, Humidity, Battery | Standard ZCL | +| Zbeacon | TS0721 | | Standard ZCL | +| Zemismart | HGZB-DLC4-N15B | | Standard ZCL | +| Zemismart | KES-606US-L4 | | Standard ZCL | +| Zemismart | LXN56-SS27LX1.1 | | Standard ZCL | +| Zemismart | LXZB-12A | | Standard ZCL | +| Zemismart | TB25 | | Standard ZCL | +| Zemismart | TB26-4 | | Standard ZCL | +| Zemismart | TB26-6 | | Standard ZCL | +| Zemismart | ZIGBEE-B09-UK | | Standard ZCL | +| Zemismart | ZMO-606-20A | | Standard ZCL | +| Zemismart | ZMO-606-P2 | | Standard ZCL | +| Zemismart | ZMS-206EU-2 | | Standard ZCL | +| Zemismart | ZMS-206EU-3 | | Standard ZCL | +| Zemismart | ZMS-206US-1 | | Standard ZCL | +| Zemismart | ZMS-206US-4 | | Standard ZCL | +| Zemismart | ZMS-208US-2 | | Standard ZCL | +| Zemismart | ZMS-208US-3 | | Standard ZCL | +| Zipato | rgbw2.zbee27 | | Standard ZCL | +| Zorro Alert | ZR360CDB | Humidity, Temperature | Tuya | +| databyte.ch | ED2004-012 | | Standard ZCL | +| eWeLink | CK-BL702-AL-01_1 | | Standard ZCL | +| eWeLink | CK-BL702-MSW-01(7010) | | Standard ZCL | +| eWeLink | CK-TLSR8656-SS5-02(7014) | Temperature, Humidity, Battery | Standard ZCL | +| eWeLink | MG3-5RZ | Motion | Standard ZCL | +| eWeLink | SA-003-Zigbee | | Standard ZCL | +| eWeLink | SA-030-1 | | Standard ZCL | +| eWeLink | SNZB-05 | Water, Battery | Standard ZCL | +| eWeLink | SWITCH-ZR02 | | Standard ZCL | +| eWeLink | SWITCH-ZR03-1 | | Standard ZCL | +| eWeLink | ZB-SW01 | | Standard ZCL | +| eWeLink | ZB-SW02 | | Standard ZCL | +| eWeLink | ZB-SW03 | | Standard ZCL | +| eWeLink | ZB-SW04 | | Standard ZCL | +| eWeLink | ZB-SW05 | | Standard ZCL | +| eZEX | ECW-100-A03 | | Standard ZCL | +| easyiot | ZB-LTH01 | Temperature, Humidity, Illuminance, Battery | Standard ZCL | +| easyiot | ZB-PM01 | | Standard ZCL | +| easyiot | ZB-PSW04 | | Standard ZCL | +| easyiot | ZB-SW08 | | Standard ZCL | +| easyiot | ZB-WB01 | Battery | Standard ZCL | +| easyiot | ZB-WB02 | Battery | Standard ZCL | +| easyiot | ZB-WB03 | Battery | Standard ZCL | +| easyiot | ZB-WB08 | Battery | Standard ZCL | +| iAlarm | SP02-ZB001 | Motion, Battery | Tuya | +| iCasa | ICZB-B1FC60/B3FC64/B2FC95/B2FC125 | | Standard ZCL | +| iCasa | ICZB-DC11 | | Standard ZCL | +| iCasa | ICZB-IW11D | | Standard ZCL | +| iCasa | ICZB-IW11SW | | Standard ZCL | +| iCasa | ICZB-IW21D | | Standard ZCL | +| iCasa | ICZB-KPD12 | Battery | Standard ZCL | +| iCasa | ICZB-KPD14S | Battery | Standard ZCL | +| iCasa | ICZB-KPD18S | Battery | Standard ZCL | +| iCasa | ICZB-R11D | | Standard ZCL | +| iCasa | ICZB-R12D | | Standard ZCL | +| iCasa | ICZB-RM11S | Battery | Standard ZCL | +| iHORN | HO-09ZB | Contact, Battery | Standard ZCL | +| iHORN | LH-32ZB | Humidity, Temperature, Battery | Standard ZCL | +| iHORN | LH-990F | Motion | Standard ZCL | +| iHORN | LH-990ZB | Motion | Standard ZCL | +| iHORN | LH-992ZB | Motion | Standard ZCL | +| iHORN | LH03121 | Contact, Battery | Standard ZCL | +| iHseno | TS0601_human_presence | Motion, Battery | Tuya | +| iHseno | ZC-W1 | Temperature, Humidity, Battery | Standard ZCL | +| iHseno | \_TZ3000_pgq7ormg | | Standard ZCL | +| iLightsIn | HLC610 | | Standard ZCL | +| iLightsIn | HSSA18-Z-MID | Motion, Illuminance | Standard ZCL | +| iStar | SCCV2401-1 | | Standard ZCL | +| iStar | SCCV2401-4 | | Standard ZCL | +| iStar | SCCV2403-2 | | Standard ZCL | +| ilux | 900008-WW | | Standard ZCL | +| smarli. | S-ZB-1RE1-R251 | | Standard ZCL | +| smarli. | S-ZB-COV1-R251 | | Standard ZCL | +| smarli. | S-ZB-PDM1-R251 | | Standard ZCL | +| xyzroe | ZigDC | Temperature, Humidity | Standard ZCL | +| xyzroe | ZigUSB | | Standard ZCL | +| xyzroe | ZigUSB_C6 | Temperature | Standard ZCL | +| zunzunbee | SSWZ8T | Battery, Temperature | Standard ZCL | + +## Not yet supported + +These devices are recognized by the upstream database but their **primary +sensor** reports over Tuya's `0xEF00` cluster in a form we can't yet decode +(typically an enum presence datapoint rather than a simple on/off). The driver +deliberately does **not** claim them - binding would leave them silent. Support +is a data refresh away as the mapping improves. + +| Vendor | Model | Sensor | +| ------ | ----- | ------ | +| ONENUO | 288WZ | Smoke | diff --git a/drivers/zigbee3_device/driver.c4zproj b/drivers/zigbee3_device/driver.c4zproj new file mode 100644 index 0000000..7b1c8b2 --- /dev/null +++ b/drivers/zigbee3_device/driver.c4zproj @@ -0,0 +1,7 @@ + + + + + + + diff --git a/drivers/zigbee3_device/driver.lua b/drivers/zigbee3_device/driver.lua new file mode 100644 index 0000000..bc513df --- /dev/null +++ b/drivers/zigbee3_device/driver.lua @@ -0,0 +1,401 @@ +--- Zigbee 3 Device - generic per-device driver entry point. +--- Wires the DriverWorks lifecycle + Zigbee callbacks to the device runtime +--- (src/zigbee3). One instance per joined device; no static proxy - proxies, +--- companion connections, and variables are created dynamically on discovery. + +--#ifdef DRIVERCENTRAL +DC_PID = 0 -- TODO: assign DriverCentral product id (shared by the whole suite) +DC_X = nil +DC_FILENAME = "zigbee3_device.c4z" +--#else +DRIVER_GITHUB_REPO = "finitelabs/control4-zigbee3" +-- One driver, but one instance per joined device. The leader (lowest device id) +-- updates them all - including the two companion packages, which carry no updater +-- of their own - and settings sync across every instance (see getHubInstanceIds / +-- syncPropertyToOtherInstances). +DRIVER_FILENAMES = { + "zigbee3_device.c4z", + "zigbee3_light.c4z", + "zigbee3_lock.c4z", +} +--#endif + +require("lib.utils") +-- Paved-path common runtime: global.handlers provides the RFP/OBC binding +-- dispatch tables + UpdateProperty/SendToProxy that lib.values/lib.bindings use; +-- global.lib sets the JSON global; global.timer backs any driver timers. +require("drivers-common-public.global.handlers") +require("drivers-common-public.global.lib") +require("drivers-common-public.global.timer") +JSON = require("JSON") + +local log = require("lib.logging") +local values = require("lib.values") +local bindings = require("lib.bindings") +local events = require("lib.events") +--#ifndef DRIVERCENTRAL +local githubUpdater = require("lib.github-updater") +--#endif +local Device = require("zigbee3.device") + +local UPDATE_CHECK_INTERVAL_MS = 30 * ONE_MINUTE -- leader checks GitHub every 30 min + +-- The static ZIGBEE transport connection declared in driver.xml. +local ZIGBEE_BINDING_ID = 6001 + +gInitialized = false +local device = nil + +--#ifndef DRIVERCENTRAL +-- Automatic updates (leader-elected, suite-wide) + +--- Device IDs of THIS driver's instances (the hub), sorted ascending. Election +--- and property sync are among hub instances only: the companions carry no +--- updater, so they are in DRIVER_FILENAMES for the hub to update, not to vote. +local function getHubInstanceIds() + local ids = {} + -- C4:GetDriverFileName is absent on some controller OS versions (see utils.lua). + local fileName = C4.GetDriverFileName and C4:GetDriverFileName() + if not fileName then + log:warn("C4:GetDriverFileName unavailable; skipping leader election / auto-update this cycle") + return ids + end + for id in pairs(C4:GetDevicesByC4iName(fileName) or {}) do + ids[#ids + 1] = tonumber(id) + end + table.sort(ids) + return ids +end + +--- Push a property to every OTHER hub instance, so Automatic Updates / +--- Update Channel stay aligned across all instances of this driver. +local function syncPropertyToOtherInstances(property, value) + local myId = C4:GetDeviceID() + for _, id in ipairs(getHubInstanceIds()) do + if id ~= myId then + SetDeviceProperties(id, { [property] = value }, true) + end + end +end + +--- Pull + install any newer suite drivers from GitHub. +function UpdateDrivers(forceUpdate) + log:info("checking for driver updates%s", forceUpdate and " (forced)" or "") + githubUpdater + :updateAll(DRIVER_GITHUB_REPO, DRIVER_FILENAMES, Properties["Update Channel"] == "Prerelease", forceUpdate) + :next(function(updated) + if not IsEmpty(updated) then + log:info("updated driver(s): %s", table.concat(updated, ", ")) + else + log:info("no driver updates available") + end + end, function(err) + log:warn("update check failed: %s", tostring(err)) + end) +end + +--- Only the leader (lowest device ID in the suite) checks GitHub, so N per-device +--- instances don't all hit it. Recomputed each tick (the previous leader may be +--- gone). Runs on a repeating timer. +local function startUpdateChecks() + SetTimer("UpdateCheck", UPDATE_CHECK_INTERVAL_MS, function() + local isLeader = Select(getHubInstanceIds(), 1) == C4:GetDeviceID() + if isLeader and toboolean(Properties["Automatic Updates"]) then + UpdateDrivers(false) + end + end, true) +end + +-- Action: update the suite now (any instance). +function EC.Update_Drivers() + UpdateDrivers(true) +end +--#endif + +function OnDriverInit() + --#ifdef DRIVERCENTRAL + require("cloud-client-byte") + C4:AllowExecute(false) + --#else + C4:AllowExecute(true) + --#endif + gInitialized = false + log:setLogName(C4:GetDeviceData(C4:GetDeviceID(), "name")) + log:setLogLevel(Properties["Log Level"]) + log:setLogMode(Properties["Log Mode"]) + log:trace("OnDriverInit()") + -- Restore dynamic variables + bindings early so Director reconnects them. Events + -- are restored in OnDriverLateInit: C4:AddEvent is unavailable this early. + values:restoreValues() + bindings:restoreBindings() + C4:UpdateProperty("Driver Version", C4:GetDriverConfigInfo("version") or "") +end + +function OnDriverLateInit() + log:trace("OnDriverLateInit()") + if not CheckMinimumVersion("Driver Status") then + return -- OS too old; CheckMinimumVersion disables + reports via Driver Status + end + events:restoreEvents() -- C4:AddEvent is unavailable in OnDriverInit + device = Device:new() + -- Push a fresh snapshot to the Settings web UI whenever device state changes. + device:onUIChange(function() + pushUIState() + end) + for p in pairs(Properties) do + local ok, err = pcall(OnPropertyChanged, p) + if not ok then + log:error("OnPropertyChanged('%s'): %s", p, tostring(err)) + end + end + device:restoreModel() -- re-resolve from persist so a reload doesn't sit in "Waiting for device" + device:replay() -- replay last known readings + settings through the normal pipeline + device:updateStatus() + gInitialized = true -- replay done; now safe to start the outside world + device:start() + --#ifndef DRIVERCENTRAL + startUpdateChecks() + --#endif + log:info("zigbee3_device initialized") +end + +-- Property handlers, dispatched by the global OnPropertyChanged router in +-- drivers-common-public.global.handlers - do NOT define a raw OnPropertyChanged, +-- which would override that router (libraries.md section 5). + +--- A driver/cloud property changed - mirror it in the Settings UI's Driver tab. +--- (Device settings are edited in the UI over UIR._SET_SETTING, not as properties.) +local function notifyDriverUI() + if gInitialized and device ~= nil then + device:notifyUI() + end +end + +function OPC.Log_Level(value) + log:setLogLevel(value) + notifyDriverUI() +end + +function OPC.Log_Mode(value) + log:setLogMode(value) + CancelTimer("LogMode") + if not log:isEnabled() then + UpdateProperty("Log Level", "3 - Info", true) + else + log:warn("Log mode '%s' will expire in 3 hours", value) + SetTimer("LogMode", 3 * ONE_HOUR, function() + log:warn("Setting log mode to 'Off' (timer expired)") + UpdateProperty("Log Mode", "Off", true) + end) + end + notifyDriverUI() +end + +--- Re-stamp from the c4z metadata so the shown version follows an auto-update. +function OPC.Driver_Version() + C4:UpdateProperty("Driver Version", C4:GetDriverConfigInfo("version") or "") +end + +--#ifndef DRIVERCENTRAL +function OPC.Automatic_Updates(value) + -- Keep the update settings aligned across every hub instance in the project. + if gInitialized then + syncPropertyToOtherInstances("Automatic Updates", value) + end + notifyDriverUI() +end + +function OPC.Update_Channel(value) + if gInitialized then + syncPropertyToOtherInstances("Update Channel", value) + end + notifyDriverUI() +end +--#endif + +-- Programming: "Set Configuration" command. Its Setting/Value dropdowns are +-- populated dynamically (GetCommandParamList -> GCPL) so only settings this +-- device actually supports appear; execution routes to Device:writeConfig. +function GCPL.Set_Configuration(paramName) + if device == nil or paramName ~= "Setting" then + return {} + end + return device:configChoices() +end + +function EC.Set_Configuration(params) + if device == nil then + return + end + device:setConfigChoice(Select(params, "Setting")) +end + +-- Programming: "Execute Action" - the same per-device list the Action property +-- offers, so a Selftest can be scheduled rather than only clicked. +function GCPL.Execute_Action(paramName) + if device == nil or paramName ~= "Action" then + return {} + end + return device:actionChoices() +end + +function EC.Execute_Action(params) + if device == nil then + return + end + device:runAction(Select(params, "Action")) +end + +-- Action: blink the device's LED so the installer can find it. Universal (ZCL +-- Identify 0x0003), so it's a static action; per-device actions like Selftest go +-- through the Execute Action programming command. +function EC.Identify() + if device ~= nil then + device:runAction("Identify") + end +end + +-- Action: forget and re-establish the real-time binds. The escape hatch for when +-- the Bindings tab looks wrong; the normal reload path trusts the persisted binds. +function EC.Rebind() + if device ~= nil then + device:rebind() + end +end + +-- Settings web UI (www/html/index.html) +-- The page talks to the driver over UIRequest: POST /api/v1/items//commands +-- with the args base64-encoded in tParams.DATA. State is returned synchronously +-- AND pushed over the socket (C4:SendDataToUI) whenever the device changes. + +--- Decode the base64 JSON payload the web UI sends as tParams.DATA ("e30=" = {}). +local function uiParams(tParams) + local ok, decoded = pcall(function() + return JSON:decode(C4:Base64Decode((tParams or {}).DATA or "e30=")) + end) + return (ok and type(decoded) == "table") and decoded or {} +end + +--- Push the current device state to the UI. The whole state goes as ONE JSON +--- string param, which sidesteps C4:SendDataToUI's inability to serialize +--- booleans and nested tables (it throws on a bare boolean). +function pushUIState() + if device == nil then + return + end + C4:SendDataToUI("STATE", { data = JSON:encode(device:uiState()) }) +end + +--- Full refresh - the page calls this on load and after a socket reconnect. +function UIR._GET_STATE() + pushUIState() + return device and JSON:encode(device:uiState()) or "{}" +end + +--- Change one device setting: { key, value }. +function UIR._SET_SETTING(tParams) + local p = uiParams(tParams) + if device ~= nil and p.key ~= nil then + device:setSetting(p.key, p.value) + end +end + +--- Discard changes: stop enforcing the integrator's settings and revert the +--- shown values to what the device itself reports (Device:clearDesiredConfig). +function UIR._DISCARD_CHANGES() + if device ~= nil then + device:clearDesiredConfig() + end +end + +--- Tune one reading's reporting cadence: { channel, min, max, change }. min/max in +--- seconds, change in the reading's display units. +function UIR._SET_REPORTING(tParams) + local p = uiParams(tParams) + if device ~= nil and p.channel ~= nil then + device:setReporting(tostring(p.channel), p.min, p.max, p.change) + end +end + +--- Revert one reading's reporting cadence to the driver default: { channel }. +function UIR._RESET_REPORTING(tParams) + local p = uiParams(tParams) + if device ~= nil and p.channel ~= nil then + device:resetReporting(tostring(p.channel)) + end +end + +--- Change a driver/cloud property from the UI's Driver tab: { property, value }. +function UIR._SET_DRIVER(tParams) + local p = uiParams(tParams) + if p.property ~= nil then + -- The wrapper fires OnPropertyChanged itself when the value changes. + UpdateProperty(tostring(p.property), tostring(p.value), true) + end +end + +function OnZigbeePacketIn(packet, profileId, clusterId, groupId, srcEndpoint, dstEndpoint) + if not gInitialized or device == nil then + return + end + local ok, err = pcall(function() + device:onPacket(packet, profileId, clusterId, groupId, srcEndpoint, dstEndpoint) + end) + if not ok then + log:error("OnZigbeePacketIn: %s", tostring(err)) + end +end + +function OnZigbeePacketSuccess() end + +function OnZigbeePacketFailed(packet, profileId, clusterId) + -- Expected for sleepy sensors until they're awake (see the config retry + -- window); keep it at debug so a normal install isn't noisy. + log:debug("Zigbee send failed on cluster 0x%04x", clusterId or 0) +end + +function OnNetworkBindingChanged(idBinding, bIsBound) + if device == nil then + return + end + if idBinding == ZIGBEE_BINDING_ID then + if bIsBound then + log:info("Zigbee transport bound; starting discovery") + device:start() + else + log:info("Zigbee transport UNBOUND; resetting device") + device:reset() + end + end +end + +function OnZigbeeOnlineStatusChanged(strStatus, strVersion, strSKU) + log:info("online status: status=%s version=%s SKU=%s", tostring(strStatus), tostring(strVersion), tostring(strSKU)) + if device == nil then + return + end + -- "ONLINE" / "OFFLINE" / "REBOOT" -> Driver Status + Offline Warning / Back + -- Online events (transitions only). + device:setOnlineStatus(strStatus) + -- The SKU may carry the device's ModelIdentifier - if so, resolve from it (no + -- Basic round-trip needed). Stashes the model so a shared one still resolves once + -- ManufacturerName arrives; no-ops for an unknown/empty value. + if type(strSKU) == "string" and strSKU ~= "" then + device:resolveFromModel(strSKU) + end + -- A device that has just come online - most importantly a fresh pair, whose + -- binding table is empty - will not transmit anything the driver receives until + -- it is bound, so the wake-driven establish can never start. Kick it here while + -- the device is provably awake. ensureRealtimeBinds()/sync() is idempotent: it + -- no-ops once the targets are confirmed, an attempt is in flight, or it is within + -- its backoff, so calling it on every online transition is safe. + if strStatus ~= "OFFLINE" then + device:ensureRealtimeBinds() + end +end + +function OnDriverDestroyed() + if device ~= nil then + device:close() + end +end diff --git a/drivers/zigbee3_device/driver.xml b/drivers/zigbee3_device/driver.xml new file mode 100644 index 0000000..8f2b44b --- /dev/null +++ b/drivers/zigbee3_device/driver.xml @@ -0,0 +1,223 @@ + + Copyright 2026 Finite Labs, LLC. All rights reserved. + Zigbee 3 Device + Finite Labs + Zigbee 3 Device + Derek Miller + icons/device_sm.png + icons/device_lg.png + lua_gen + zigbee + DriverWorks + + 08/25/2026 07:54:20 AM + + 4.2.0 + true + + Other + + + + + + + + + + + True + + + + + 6001 + 6 + ZIGBEE + 4 + True + False + False + True + + + ZIGBEE + + + + + + + + 1 + Battery Low + When NAME battery is low + + + 2 + Trouble + When NAME failure is imminent + + + 3 + Offline Warning + When NAME has failed to report and gone offline + + + 4 + Back Online + When NAME has reported again after going offline + + + + + + + + diff --git a/drivers/zigbee3_device/www/icons/device_lg.png b/drivers/zigbee3_device/www/icons/device_lg.png new file mode 100644 index 0000000..0d68ffc Binary files /dev/null and b/drivers/zigbee3_device/www/icons/device_lg.png differ diff --git a/drivers/zigbee3_device/www/icons/device_sm.png b/drivers/zigbee3_device/www/icons/device_sm.png new file mode 100644 index 0000000..8b7a07a Binary files /dev/null and b/drivers/zigbee3_device/www/icons/device_sm.png differ diff --git a/drivers/zigbee3_device/www/icons/experience_100.png b/drivers/zigbee3_device/www/icons/experience_100.png new file mode 100644 index 0000000..f7c750a Binary files /dev/null and b/drivers/zigbee3_device/www/icons/experience_100.png differ diff --git a/drivers/zigbee3_device/www/icons/experience_1024.png b/drivers/zigbee3_device/www/icons/experience_1024.png new file mode 100644 index 0000000..04a3f63 Binary files /dev/null and b/drivers/zigbee3_device/www/icons/experience_1024.png differ diff --git a/drivers/zigbee3_device/www/icons/experience_110.png b/drivers/zigbee3_device/www/icons/experience_110.png new file mode 100644 index 0000000..44e8755 Binary files /dev/null and b/drivers/zigbee3_device/www/icons/experience_110.png differ diff --git a/drivers/zigbee3_device/www/icons/experience_120.png b/drivers/zigbee3_device/www/icons/experience_120.png new file mode 100644 index 0000000..7f29be1 Binary files /dev/null and b/drivers/zigbee3_device/www/icons/experience_120.png differ diff --git a/drivers/zigbee3_device/www/icons/experience_130.png b/drivers/zigbee3_device/www/icons/experience_130.png new file mode 100644 index 0000000..1c369a6 Binary files /dev/null and b/drivers/zigbee3_device/www/icons/experience_130.png differ diff --git a/drivers/zigbee3_device/www/icons/experience_140.png b/drivers/zigbee3_device/www/icons/experience_140.png new file mode 100644 index 0000000..56fd848 Binary files /dev/null and b/drivers/zigbee3_device/www/icons/experience_140.png differ diff --git a/drivers/zigbee3_device/www/icons/experience_20.png b/drivers/zigbee3_device/www/icons/experience_20.png new file mode 100644 index 0000000..5ab4300 Binary files /dev/null and b/drivers/zigbee3_device/www/icons/experience_20.png differ diff --git a/drivers/zigbee3_device/www/icons/experience_30.png b/drivers/zigbee3_device/www/icons/experience_30.png new file mode 100644 index 0000000..2df9dbc Binary files /dev/null and b/drivers/zigbee3_device/www/icons/experience_30.png differ diff --git a/drivers/zigbee3_device/www/icons/experience_300.png b/drivers/zigbee3_device/www/icons/experience_300.png new file mode 100644 index 0000000..995192e Binary files /dev/null and b/drivers/zigbee3_device/www/icons/experience_300.png differ diff --git a/drivers/zigbee3_device/www/icons/experience_40.png b/drivers/zigbee3_device/www/icons/experience_40.png new file mode 100644 index 0000000..77f9825 Binary files /dev/null and b/drivers/zigbee3_device/www/icons/experience_40.png differ diff --git a/drivers/zigbee3_device/www/icons/experience_50.png b/drivers/zigbee3_device/www/icons/experience_50.png new file mode 100644 index 0000000..2563690 Binary files /dev/null and b/drivers/zigbee3_device/www/icons/experience_50.png differ diff --git a/drivers/zigbee3_device/www/icons/experience_512.png b/drivers/zigbee3_device/www/icons/experience_512.png new file mode 100644 index 0000000..95d38c0 Binary files /dev/null and b/drivers/zigbee3_device/www/icons/experience_512.png differ diff --git a/drivers/zigbee3_device/www/icons/experience_60.png b/drivers/zigbee3_device/www/icons/experience_60.png new file mode 100644 index 0000000..47e821f Binary files /dev/null and b/drivers/zigbee3_device/www/icons/experience_60.png differ diff --git a/drivers/zigbee3_device/www/icons/experience_70.png b/drivers/zigbee3_device/www/icons/experience_70.png new file mode 100644 index 0000000..0f6cb77 Binary files /dev/null and b/drivers/zigbee3_device/www/icons/experience_70.png differ diff --git a/drivers/zigbee3_device/www/icons/experience_80.png b/drivers/zigbee3_device/www/icons/experience_80.png new file mode 100644 index 0000000..3a1561e Binary files /dev/null and b/drivers/zigbee3_device/www/icons/experience_80.png differ diff --git a/drivers/zigbee3_device/www/icons/experience_90.png b/drivers/zigbee3_device/www/icons/experience_90.png new file mode 100644 index 0000000..cdd74c2 Binary files /dev/null and b/drivers/zigbee3_device/www/icons/experience_90.png differ diff --git a/drivers/zigbee3_light/driver.c4zproj b/drivers/zigbee3_light/driver.c4zproj new file mode 100644 index 0000000..2cb3160 --- /dev/null +++ b/drivers/zigbee3_light/driver.c4zproj @@ -0,0 +1,7 @@ + + + + + + + diff --git a/drivers/zigbee3_light/driver.lua b/drivers/zigbee3_light/driver.lua new file mode 100644 index 0000000..845c859 --- /dev/null +++ b/drivers/zigbee3_light/driver.lua @@ -0,0 +1,2454 @@ +--#ifdef DRIVERCENTRAL +DC_PID = 0 -- TODO: assign DriverCentral product id +DC_X = nil +DC_FILENAME = "zigbee3_light.c4z" +--#endif +require("lib.utils") +require("drivers-common-public.global.handlers") +require("drivers-common-public.global.lib") +require("drivers-common-public.global.timer") + +JSON = require("JSON") + +local log = require("lib.logging") +local persist = require("lib.persist") +local constants = require("constants") + +local LightProto = require("zigbee3.light_protocol") + +--------------------------------------------------------------------------- +-- Bindings +--------------------------------------------------------------------------- + +local ON_BINDING = 300 +local TOGGLE_BINDING = 301 +local OFF_BINDING = 302 +local PROXY_BINDING = 5001 +local DEVICE_BINDING = 5002 + +--------------------------------------------------------------------------- +-- the device color modes that include brightness control +--------------------------------------------------------------------------- + +--- @type table +local COLOR_MODES_SUPPORTING_BRIGHTNESS = { + [LightProto.ColorMode.COLOR_MODE_UNKNOWN] = false, + [LightProto.ColorMode.COLOR_MODE_ON_OFF] = false, + [LightProto.ColorMode.COLOR_MODE_LEGACY_BRIGHTNESS] = true, + [LightProto.ColorMode.COLOR_MODE_BRIGHTNESS] = true, + [LightProto.ColorMode.COLOR_MODE_WHITE] = true, + [LightProto.ColorMode.COLOR_MODE_COLOR_TEMPERATURE] = true, + [LightProto.ColorMode.COLOR_MODE_COLD_WARM_WHITE] = true, + [LightProto.ColorMode.COLOR_MODE_RGB] = true, + [LightProto.ColorMode.COLOR_MODE_RGB_WHITE] = true, + [LightProto.ColorMode.COLOR_MODE_RGB_COLOR_TEMPERATURE] = true, + [LightProto.ColorMode.COLOR_MODE_RGB_COLD_WARM_WHITE] = true, +} + +--- @type table +local COLOR_MODES_SUPPORTING_RGB = { + [LightProto.ColorMode.COLOR_MODE_RGB] = true, + [LightProto.ColorMode.COLOR_MODE_RGB_WHITE] = true, + [LightProto.ColorMode.COLOR_MODE_RGB_COLOR_TEMPERATURE] = true, + [LightProto.ColorMode.COLOR_MODE_RGB_COLD_WARM_WHITE] = true, +} + +--- @type table +local COLOR_MODES_SUPPORTING_CCT = { + [LightProto.ColorMode.COLOR_MODE_COLOR_TEMPERATURE] = true, + [LightProto.ColorMode.COLOR_MODE_COLD_WARM_WHITE] = true, + [LightProto.ColorMode.COLOR_MODE_RGB_COLOR_TEMPERATURE] = true, + [LightProto.ColorMode.COLOR_MODE_RGB_COLD_WARM_WHITE] = true, +} + +--------------------------------------------------------------------------- +-- Persist keys and defaults +--------------------------------------------------------------------------- + +local P_PRESET_LEVEL = "preset_level" +local P_CLICK_RATE_UP = "click_rate_up" +local P_CLICK_RATE_DOWN = "click_rate_down" +local P_HOLD_RATE_UP = "hold_rate_up" +local P_HOLD_RATE_DOWN = "hold_rate_down" +local P_RATE_DEFAULT = "brightness_rate_default" +local P_COLOR_RATE_DEFAULT = "color_rate_default" +local P_ON_MODE = "brightness_on_mode" +local P_BUTTON_COLORS = "button_colors" +local P_SCENES = "scenes" +local P_MAX_ON_LEVEL = "max_on_level" +local P_MIN_ON_LEVEL = "min_on_level" +local P_BRIGHTNESS_PRESETS = "brightness_presets" +local P_COLOR_PRESETS = "color_presets" +local P_COLOR_ON_MODE = "color_on_mode" +local P_PREVIOUS_COLOR = "previous_color" +local P_BRIGHTNESS_ON_MODE_PRESET = "brightness_on_mode_preset" +local P_COLOR_ON_MODE_PRESET = "color_on_mode_preset" + +-- Color on-mode kinds. The proxy assigns presets with these origins/IDs to +-- distinguish dim-to-warm pairs from previous-color tracking. +local COLOR_ON_MODE_NONE = 0 +local COLOR_ON_MODE_FADE = 1 -- Dim-To-Warm +local COLOR_ON_MODE_PREVIOUS = 2 +local COLOR_ON_MODE_PRESET = 3 + +local SCENE_TIMER_PREFIX = "Scene_" +local SCENE_RAMP_TIMER = "SceneRamp" + +local DEFAULT_PRESET_LEVEL = 100 +local DEFAULT_CLICK_RATE = 500 +local DEFAULT_HOLD_RATE = 3000 +local DEFAULT_RATE = 500 + +local LIGHT_COLOR_MODE_FULL = 0 +local LIGHT_COLOR_MODE_CCT = 1 + +-- D65 whitepoint, used as a sane chromaticity default before any state is known +local DEFAULT_COLOR_X = 0.3127 +local DEFAULT_COLOR_Y = 0.3290 + +--------------------------------------------------------------------------- +-- State +--------------------------------------------------------------------------- + +local ENTITY +local STATE +local currentBrightness = 0 +local ledState = false +local supportsDimming = false +local supportsColor = false +local supportsCCT = false +-- The bulb's supported_color_modes from ListEntitiesLightResponse. We pick +-- the most specific mode per cmd intent (CCT vs RGB) and set color_mode +-- explicitly so the device doesn't have to infer from which fields we populate. +local supportedColorModes = {} +local minMireds = 153 -- ~6500K (cool) +local maxMireds = 500 -- ~2000K (warm) +local currentColorX = DEFAULT_COLOR_X +local currentColorY = DEFAULT_COLOR_Y +local currentColorMode = LIGHT_COLOR_MODE_CCT +local dynamicCapsSent = false + +-- The driver owns brightness/color state during a ramp. the device echoes +-- intermediate brightness values during a transition (one echo per command +-- received - they confirm the target of each command). We delegate the +-- physical ramp to the device's native transition_length and track ramp metadata +-- locally for STOP-mid-ramp interpolation via C4:GetTime() (ms precision). +local rampingBrightness = false +local rampingColor = false + +-- Ramp metadata: { startTime, startLevel, targetLevel, durationMs }. Cleared +-- when no ramp is in flight. +local brightnessRamp = nil +local colorRamp = nil + +-- Snapshot of brightness captured when BUTTON_ACTION PRESS arrives. The proxy +-- sends PRESS on button-down and decides click vs hold ~110ms later. By the +-- time a RELEASE_CLICK arrives, our hold ramp may have stepped 1-2%; on click +-- we restore to this snapshot before running the click ramp so a brief hold +-- step never inverts the click outcome. +local prePressBrightness = nil + +-- Set to true once a SET_COLOR_TARGET arrives during a single on-cycle. While +-- true, color_on_mode_fade does not recompute color from the brightness +-- formula. Cleared whenever brightness reaches 0 (the next on cycle is fresh +-- and should follow the formula again). +local fadeOverride = false + +-- LIGHT_BRIGHTNESS_TARGET_PRESET_ID from the proxy (Daylight Agent integration, +-- spec _2.1). Echoed back as LIGHT_BRIGHTNESS_CURRENT_PRESET_ID on subsequent +-- LIGHT_BRIGHTNESS_CHANGED so the proxy knows the active preset still owns the +-- current level. Cleared by SET_LEVEL / button presses / scene steps that +-- aren't preset-driven. +local currentBrightnessPresetId = nil + +-- LIGHT_COLOR_TARGET_PRESET_ID counterpart (spec _3.1). +local currentColorPresetId = nil + +--------------------------------------------------------------------------- +-- Driver lifecycle +--------------------------------------------------------------------------- + +function OnDriverInit() + --#ifdef DRIVERCENTRAL + require("cloud-client-byte") + C4:AllowExecute(false) + --#else + C4:AllowExecute(true) + --#endif + gInitialized = false + log:setLogName(C4:GetDeviceData(C4:GetDeviceID(), "name")) + log:setLogLevel(Properties["Log Level"]) + log:setLogMode(Properties["Log Mode"]) + log:trace("OnDriverInit()") +end + +function OnDriverLateInit() + log:trace("OnDriverLateInit()") + if not CheckMinimumVersion("Driver Status") then + return + end + + -- Fire OnPropertyChanged to set the initial Headers and other Property + -- global sets, they'll change if Property is changed. + for p, _ in pairs(Properties) do + local status, err = pcall(OnPropertyChanged, p) + if not status and err then + log:error("Error in OnPropertyChanged for property '%s': %s", p, err or "unknown error") + end + end + + gInitialized = true + UpdateProperty("Driver Status", "Disconnected") + SendToProxy(PROXY_BINDING, "ONLINE_CHANGED", { STATE = false }, "NOTIFY") + SendToProxy(DEVICE_BINDING, "REFRESH_STATE", {}, "NOTIFY") +end + +--------------------------------------------------------------------------- +-- Property handlers +--------------------------------------------------------------------------- + +function OPC.Driver_Status(propertyValue) + log:trace("OPC.Driver_Status('%s')", propertyValue) + if not gInitialized then + UpdateProperty("Driver Status", "Initializing", false) + return + end +end + +function OPC.Driver_Version(propertyValue) + log:trace("OPC.Driver_Version('%s')", propertyValue) + C4:UpdateProperty("Driver Version", C4:GetDriverConfigInfo("version")) +end + +function OPC.Log_Mode(propertyValue) + log:trace("OPC.Log_Mode('%s')", propertyValue) + log:setLogMode(propertyValue) + CancelTimer("LogMode") + if not log:isEnabled() then + UpdateProperty("Log Level", "3 - Info", true) + return + end + log:warn("Log mode '%s' will expire in 3 hours", propertyValue) + SetTimer("LogMode", 3 * ONE_HOUR, function() + log:warn("Setting log mode to 'Off' (timer expired)") + UpdateProperty("Log Mode", "Off", true) + end) + OnPropertyChanged("Log Level") +end + +function OPC.Log_Level(propertyValue) + log:trace("OPC.Log_Level('%s')", propertyValue) + log:setLogLevel(propertyValue) + if log:getLogLevel() >= 6 and log:isPrintEnabled() then + DEBUGPRINT = true + DEBUG_TIMER = true + DEBUG_RFN = true + DEBUG_URL = true + DEBUG_WEBSOCKET = true + else + DEBUGPRINT = false + DEBUG_TIMER = false + DEBUG_RFN = false + DEBUG_URL = false + DEBUG_WEBSOCKET = false + end +end + +--------------------------------------------------------------------------- +-- Helpers: entity capabilities +--------------------------------------------------------------------------- + +local function entitySupportsAnyMode(entity, modeTable) + local modes = Select(entity, "supported_color_modes") + if not IsList(modes) then + return false + end + for _, mode in ipairs(modes) do + if modeTable[mode] then + return true + end + end + return false +end + +local function entitySupportsBrightness(entity) + return entitySupportsAnyMode(entity, COLOR_MODES_SUPPORTING_BRIGHTNESS) +end + +local function entitySupportsColor(entity) + return entitySupportsAnyMode(entity, COLOR_MODES_SUPPORTING_RGB) +end + +local function entitySupportsCCT(entity) + return entitySupportsAnyMode(entity, COLOR_MODES_SUPPORTING_CCT) +end + +local function miredsToKelvin(m) + if not m or m <= 0 then + return 0 + end + return math.floor(1e6 / m + 0.5) +end + +local function kelvinToMireds(k) + if not k or k <= 0 then + return 0 + end + return 1e6 / k +end + +local function updateDynamicCapabilities(entity) + if dynamicCapsSent then + return + end + supportsDimming = entitySupportsBrightness(entity) + supportsColor = entitySupportsColor(entity) + supportsCCT = entitySupportsCCT(entity) + supportedColorModes = {} + local modes = Select(entity, "supported_color_modes") + if IsList(modes) then + for _, m in ipairs(modes) do + supportedColorModes[m] = true + end + end + -- Some the device entities report 0/0 for mireds. Keep our XML defaults in that case + -- so Composer's dialog doesn't get broken bounds. + local entityMin = tonumber(Select(entity, "min_mireds")) + local entityMax = tonumber(Select(entity, "max_mireds")) + if entityMin and entityMin > 0 then + minMireds = entityMin + end + if entityMax and entityMax > 0 then + maxMireds = entityMax + end + + log:info( + "Entity caps: brightness=%s color=%s cct=%s mireds=[%.1f, %.1f]", + tostring(supportsDimming), + tostring(supportsColor), + tostring(supportsCCT), + minMireds, + maxMireds + ) + + -- Emit the FULL set of dynamic capabilities (everything spec'd as + -- "Dynamic Capability: Yes" in the LIGHT_V2 cap docs, plus dynamic-only + -- caps from DYNAMIC_CAPABILITIES_CHANGED). Composer reads these at + -- runtime to gate UI elements; the static driver.xml values are only + -- the design-time defaults. Emitting the full set ensures Navigators + -- and Composer test panels reflect the actual bulb's capabilities. + local caps = { + -- Brightness/dimmer + dimmer = supportsDimming, + set_level = supportsDimming, + supports_target = supportsDimming, + supports_brightness_stop = supportsDimming, + ramp_level = supportsDimming, -- legacy 3.2-era cap; still gates test panel Ramp button + has_fixed_ramp_rate = false, + fixed_ramp_rate = 0, + brightness_rate_min = 0, + brightness_rate_max = 65535, + -- Color + supports_color = supportsColor, + supports_color_correlated_temperature = supportsCCT, + -- Misc + has_extras = false, + cold_start = false, + color_trace_tolerance = 2, -- xy round-trip through HSV/RGB drifts ~1; use 2 for margin + } + if supportsCCT then + -- CIE mireds invert vs Kelvin, so swap min/max during conversion. + caps.color_correlated_temperature_min = miredsToKelvin(maxMireds) + caps.color_correlated_temperature_max = miredsToKelvin(minMireds) + end + if supportsColor or supportsCCT then + caps.color_rate_behavior = 1 -- the device's transition_length applies to all aspects equally + caps.color_rate_min = 0 + caps.color_rate_max = 65535 + caps.supports_color_stop = true + else + caps.supports_color_stop = false + end + SendToProxy(PROXY_BINDING, "DYNAMIC_CAPABILITIES_CHANGED", caps, "NOTIFY", true) + + -- Tell the proxy we have three virtual buttons (top/bottom/toggle). Sent as + -- a string per the LIGHT_V2 NUMBER_BUTTONS notify format. Then emit a + -- BUTTON_INFO for each so Composer's GET_SETUP can populate names. + SendToProxy(PROXY_BINDING, "NUMBER_BUTTONS", "3", "NOTIFY") + local buttonNames = { + [constants.ButtonIds.TOP] = "Top", + [constants.ButtonIds.BOTTOM] = "Bottom", + [constants.ButtonIds.TOGGLE] = "Toggle", + } + for buttonId, name in pairs(buttonNames) do + local colors = persist:get(P_BUTTON_COLORS) or {} + local saved = colors[tostring(buttonId)] or {} + SendToProxy(PROXY_BINDING, "BUTTON_INFO", { + BUTTON_ID = buttonId, + NAME = name, + ON_COLOR = saved.on_color or "", + OFF_COLOR = saved.off_color or "", + }, "NOTIFY") + end + + -- Re-emit the persisted preset level so the proxy is seeded after a reload. + local presetLevel = tointeger(persist:get(P_PRESET_LEVEL)) + if presetLevel and presetLevel > 0 then + SendToProxy(PROXY_BINDING, "PRESET_LEVEL", tostring(presetLevel), "NOTIFY") + end + + -- Set last so a mid-function error retries on the next UPDATE_STATE rather + -- than leaving the proxy with a half-applied capability set. + dynamicCapsSent = true +end + +--------------------------------------------------------------------------- +-- Helpers: color conversions +--------------------------------------------------------------------------- + +-- HSV (h: 0-360, s: 0-100, v: 0-100) -> normalized RGB (each 0-1) +local function hsvToRGB(h, s, v) + local sf, vf = (s or 0) / 100, (v or 0) / 100 + local c = vf * sf + local hh = ((h or 0) / 60) % 6 + local x = c * (1 - math.abs((hh % 2) - 1)) + local m = vf - c + local r, g, b = 0, 0, 0 + if hh < 1 then + r, g, b = c, x, 0 + elseif hh < 2 then + r, g, b = x, c, 0 + elseif hh < 3 then + r, g, b = 0, c, x + elseif hh < 4 then + r, g, b = 0, x, c + elseif hh < 5 then + r, g, b = x, 0, c + else + r, g, b = c, 0, x + end + return r + m, g + m, b + m +end + +-- normalized RGB (0-1) -> HSV (h: 0-360, s: 0-100, v: 0-100) +local function rgbToHSV(r, g, b) + r, g, b = r or 0, g or 0, b or 0 + local mx = math.max(r, g, b) + local mn = math.min(r, g, b) + local d = mx - mn + local h = 0 + if d > 0 then + if mx == r then + h = 60 * (((g - b) / d) % 6) + elseif mx == g then + h = 60 * ((b - r) / d + 2) + else + h = 60 * ((r - g) / d + 4) + end + end + if h < 0 then + h = h + 360 + end + local s = mx > 0 and (d / mx) * 100 or 0 + return h, s, mx * 100 +end + +-- CIE 1931 xy chromaticity -> normalized RGB at full intensity. +-- Brightness is handled separately via the LIGHT_V2 brightness path. +local function xyToRGB(x, y) + local h, s = C4:ColorXYtoHSV(x, y) + local r, g, b = hsvToRGB(h or 0, s or 100, 100) + return r, g, b +end + +--------------------------------------------------------------------------- +-- Helpers: persistence +--------------------------------------------------------------------------- + +-- Clamp the persisted preset to a usable on-level. The proxy may send 0 via +-- SET_PRESET_LEVEL during testing; treat anything < 1 as "use the default" so +-- a tap of On/Toggle doesn't end up turning the light off. +local function getPresetLevel() + local v = tointeger(persist:get(P_PRESET_LEVEL)) + if not v or v < 1 then + return DEFAULT_PRESET_LEVEL + end + return math.min(v, 100) +end + +local function getOnBrightness() + local onMode = persist:get(P_ON_MODE) + local level = onMode and tointeger(onMode.level) + if level and level >= 1 then + return math.min(level, 100) + end + return getPresetLevel() +end + +local function getDefaultRate() + return persist:get(P_RATE_DEFAULT, DEFAULT_RATE) +end + +-- the device's transition_length applies to all aspects of a light_command +-- (brightness, color, color temperature) at the same time, so we declare +-- color_rate_behavior=1 ("Device only supports one rate for brightness and +-- color"). Composer in turn shows a single "Default Brightness and Color +-- Rate" setting; the brightness and color defaults are the same value. If +-- nothing has been persisted yet for color we fall back to the brightness +-- default rather than the hard-coded constant so the two can never drift. +local function getDefaultColorRate() + local colorRate = persist:get(P_COLOR_RATE_DEFAULT) + if colorRate ~= nil then + return colorRate + end + return getDefaultRate() +end + +local function getClickRateUp() + return persist:get(P_CLICK_RATE_UP, DEFAULT_CLICK_RATE) +end + +local function getClickRateDown() + return persist:get(P_CLICK_RATE_DOWN, DEFAULT_CLICK_RATE) +end + +local function getHoldRateUp() + return persist:get(P_HOLD_RATE_UP, DEFAULT_HOLD_RATE) +end + +local function getHoldRateDown() + return persist:get(P_HOLD_RATE_DOWN, DEFAULT_HOLD_RATE) +end + +local function getButtonColors(buttonId) + local colors = persist:get(P_BUTTON_COLORS, {}) + local key = tostring(buttonId) + if colors[key] then + return colors[key].on_color or "0000ff", colors[key].off_color or "000000" + end + return "0000ff", "000000" +end + +local function setButtonColors(buttonId, onColor, offColor) + local colors = persist:get(P_BUTTON_COLORS, {}) + local key = tostring(buttonId) + local existing = colors[key] or {} + colors[key] = { + on_color = onColor or existing.on_color or "0000ff", + off_color = offColor or existing.off_color or "000000", + } + persist:set(P_BUTTON_COLORS, colors) +end + +--------------------------------------------------------------------------- +-- Helpers: the device light commands +--------------------------------------------------------------------------- + +local function sendLightCommand(opts) + log:debug("sendLightCommand(%s)", opts) + SendToProxy(DEVICE_BINDING, "ENTITY_COMMAND", { + body = SerializeSafe(opts), + }) +end + +-- Pick the most specific the device color mode the bulb supports for a given +-- intent ("cct" or "rgb"). Order matters: prefer single-purpose modes (RGB, +-- COLD_WARM_WHITE) over combined modes (RGB_COLOR_TEMPERATURE, +-- RGB_COLD_WARM_WHITE) because the bulb's behavior in single-purpose modes +-- is unambiguous. Returns nil if no compatible mode is supported. +local function pickColorMode(intent) + local CM = LightProto.ColorMode + local order + if intent == "cct" then + order = { + CM.COLOR_MODE_COLD_WARM_WHITE, + CM.COLOR_MODE_COLOR_TEMPERATURE, + CM.COLOR_MODE_RGB_COLD_WARM_WHITE, + CM.COLOR_MODE_RGB_COLOR_TEMPERATURE, + } + else + order = { + CM.COLOR_MODE_RGB, + CM.COLOR_MODE_RGB_WHITE, + CM.COLOR_MODE_RGB_COLOR_TEMPERATURE, + CM.COLOR_MODE_RGB_COLD_WARM_WHITE, + } + end + for _, m in ipairs(order) do + if supportedColorModes[m] then + return m + end + end + return nil +end + +-- Map a target Kelvin to a (cold_white, warm_white) channel split based on +-- the bulb's reported mireds range. Pure cold = (1, 0) at min_mireds; pure +-- warm = (0, 1) at max_mireds; linear blend between. Returned values are 0-1 +-- floats matching the device's per-channel scale. +local function kelvinToCoolWarmSplit(kelvin) + local mireds = kelvinToMireds(kelvin) + local span = maxMireds - minMireds + if span <= 0 then + return 0.5, 0.5 + end + local ratio = math.max(0, math.min(1, (mireds - minMireds) / span)) + return 1 - ratio, ratio +end + +-- Convert an XY/mode color into the right the device cmd fields. Returns the +-- partial cmd table or nil if the bulb doesn't support color/CCT or the +-- provided values can't be mapped. +local function buildColorCmdFields(x, y, mode) + if not (supportsColor or supportsCCT) or x == nil or y == nil then + return nil + end + if mode == LIGHT_COLOR_MODE_CCT and supportsCCT then + local k = tonumber(C4:ColorXYtoCCT(x, y)) + if not k or k <= 0 then + return nil + end + local fields = { + has_color_temperature = true, + color_temperature = kelvinToMireds(k), + } + -- Set color_mode explicitly so the device doesn't have to infer. + local pickedMode = pickColorMode("cct") + if pickedMode then + fields.has_color_mode = true + fields.color_mode = pickedMode + end + -- For RGBCW / cold-warm-white capable bulbs, also drive the cold/warm + -- channels directly. the device would compute these internally from + -- color_temperature, but sending them ourselves removes ambiguity in + -- min_mireds/max_mireds reading and keeps the channel split exactly + -- where we expect it. + local CM = LightProto.ColorMode + if supportedColorModes[CM.COLOR_MODE_COLD_WARM_WHITE] or supportedColorModes[CM.COLOR_MODE_RGB_COLD_WARM_WHITE] then + local cw, ww = kelvinToCoolWarmSplit(k) + fields.has_cold_white = true + fields.cold_white = cw + fields.has_warm_white = true + fields.warm_white = ww + end + return fields + end + if supportsColor then + local r, g, b = xyToRGB(x, y) + local fields = { has_rgb = true, red = r, green = g, blue = b } + local pickedMode = pickColorMode("rgb") + if pickedMode then + fields.has_color_mode = true + fields.color_mode = pickedMode + end + return fields + end + return nil +end + +-- Apply the dim-to-warm formula from spec _7.2: +-- colorFinal.x = colorDim.x + (colorOn.x - colorDim.x) * brightness*.01 +-- colorFinal.y = colorDim.y + (colorOn.y - colorDim.y) * brightness*.01 +-- The "On" color is the color at 100%, "Dim" is the color at 1%. We get +-- both via UPDATE_COLOR_ON_MODE (onPreset = on color, fadePreset = dim +-- color). Returns nil if either color is missing or fade mode isn't active. +local function computeFadeColor(brightness) + local mode = persist:get(P_COLOR_ON_MODE) + if not mode then + return nil + end + local onPreset = mode.onPreset + local dimPreset = mode.fadePreset + if not onPreset or not dimPreset then + return nil + end + if onPreset.x == nil or onPreset.y == nil or dimPreset.x == nil or dimPreset.y == nil then + return nil + end + local b = math.max(0, math.min(100, brightness)) * 0.01 + return { + x = dimPreset.x + (onPreset.x - dimPreset.x) * b, + y = dimPreset.y + (onPreset.y - dimPreset.y) * b, + mode = onPreset.mode or LIGHT_COLOR_MODE_FULL, + } +end + +-- Determine which color on-mode is currently active. Returns one of +-- COLOR_ON_MODE_* constants. +local function getColorOnModeKind() + if not (supportsColor or supportsCCT) then + return COLOR_ON_MODE_NONE + end + local mode = persist:get(P_COLOR_ON_MODE) + if not mode or not mode.fadePreset then + return COLOR_ON_MODE_NONE + end + local fadeOrigin = mode.fadePreset.origin + if fadeOrigin and fadeOrigin > 0 then + -- Origin > 0 indicates fade is enabled (spec _21: origin 1=device, 2=agent). + return COLOR_ON_MODE_FADE + end + -- If no fade is configured but we have a stored previous color, treat as + -- previous mode. + if persist:get(P_PREVIOUS_COLOR) then + return COLOR_ON_MODE_PREVIOUS + end + if mode.onPreset and mode.onPreset.x then + return COLOR_ON_MODE_PRESET + end + return COLOR_ON_MODE_NONE +end + +-- The bulb is "logically on" if either we already think it's on or a ramp +-- is in flight targeting an on-state. Used so a SET_COLOR_TARGET arriving +-- mid-ramp from off→on doesn't send state=false (which kills the brightness +-- fade by reverting the bulb to off). +local function isLogicallyOn() + if rampingBrightness and brightnessRamp and (brightnessRamp.targetLevel or 0) > 0 then + return true + end + return currentBrightness > 0 +end + +-- Determine the on-color to use when transitioning from off to on, based on +-- the active color on-mode. Returns {x, y, mode} or nil. +local function resolveOnColor(brightnessLevel) + if not (supportsColor or supportsCCT) then + return nil + end + local kind = getColorOnModeKind() + if kind == COLOR_ON_MODE_FADE and not fadeOverride then + return computeFadeColor(brightnessLevel) + end + if kind == COLOR_ON_MODE_PREVIOUS then + local prev = persist:get(P_PREVIOUS_COLOR) + if prev and prev.x and prev.y then + return { x = prev.x, y = prev.y, mode = prev.mode or LIGHT_COLOR_MODE_FULL } + end + end + if kind == COLOR_ON_MODE_PRESET then + local mode = persist:get(P_COLOR_ON_MODE) + local onPreset = mode and mode.onPreset + if onPreset and onPreset.x and onPreset.y then + return { x = onPreset.x, y = onPreset.y, mode = onPreset.mode or LIGHT_COLOR_MODE_FULL } + end + end + return nil +end + +-- Tracks a recent off→on cmd that already carried the on-color. The proxy +-- typically follows a SET_BRIGHTNESS_TARGET with a SET_COLOR_TARGET that +-- carries the same color it already set in our brightness cmd; we use this +-- timestamp to deduplicate and avoid sending a redundant the device cmd that +-- would otherwise restart the in-flight transition. +local mergedColorUntil = 0 + +--------------------------------------------------------------------------- +-- Helpers: brightness notifications +--------------------------------------------------------------------------- + +local function notifyBrightnessChanged(level) + -- Snapshot the current color before the light goes off so color_on_mode_ + -- previous can restore it on the next on. Spec _7.4: "the proxy tracks the + -- last color reported by a driver before a BRIGHTNESS_CHANGED notification + -- occurs with a level of 0." We mirror that locally for non-proxy paths. + if level == 0 and currentBrightness > 0 then + persist:set(P_PREVIOUS_COLOR, { + x = currentColorX, + y = currentColorY, + mode = currentColorMode, + }) + -- A new on cycle is fresh: clear any prior dim-to-warm override so the + -- formula is re-applied next time the light turns on. Also drop any + -- color preset id; whatever drove the previous on-cycle's color no + -- longer applies after the light returns to off. + fadeOverride = false + currentColorPresetId = nil + end + currentBrightness = level + log:debug("LIGHT_BRIGHTNESS_CHANGED: %s", level) + -- Echo back the preset id from the most recent SET_BRIGHTNESS_TARGET so the + -- proxy / Daylight Agent (spec _10.2 / _2.1) knows the active preset still + -- owns the current level. Nil keys are dropped from the table at construct + -- time, so this is equivalent to omitting the field when no preset is set. + SendToProxy(PROXY_BINDING, "LIGHT_BRIGHTNESS_CHANGED", { + LIGHT_BRIGHTNESS_CURRENT = level, + LIGHT_BRIGHTNESS_CURRENT_PRESET_ID = currentBrightnessPresetId, + }, "NOTIFY") + local newLedState = level > 0 + if newLedState ~= ledState then + ledState = newLedState + -- MATCH_LED_STATE goes to each BUTTON_LINK binding (the keypad button + -- LEDs), not to the LIGHT_V2 proxy binding. STATE is a Lua boolean per + -- spec. Bottom is inverted: its LED lights when the light is OFF. + SendToProxy(ON_BINDING, "MATCH_LED_STATE", { STATE = newLedState }, "NOTIFY", true) + SendToProxy(OFF_BINDING, "MATCH_LED_STATE", { STATE = not newLedState }, "NOTIFY", true) + SendToProxy(TOGGLE_BINDING, "MATCH_LED_STATE", { STATE = newLedState }, "NOTIFY", true) + end +end + +local function notifyBrightnessChanging(target, rate) + log:debug("LIGHT_BRIGHTNESS_CHANGING: target=%s rate=%s", target, rate) + SendToProxy(PROXY_BINDING, "LIGHT_BRIGHTNESS_CHANGING", { + LIGHT_BRIGHTNESS_CURRENT = currentBrightness, + LIGHT_BRIGHTNESS_TARGET = target, + RATE = rate, + LIGHT_BRIGHTNESS_TARGET_PRESET_ID = currentBrightnessPresetId, + }, "NOTIFY", true) +end + +--------------------------------------------------------------------------- +-- Helpers: color notifications +--------------------------------------------------------------------------- + +local function notifyColorChanged(x, y, mode) + currentColorX = x + currentColorY = y + currentColorMode = mode + log:debug("LIGHT_COLOR_CHANGED: x=%.4f y=%.4f mode=%s", x, y, mode) + SendToProxy(PROXY_BINDING, "LIGHT_COLOR_CHANGED", { + LIGHT_COLOR_CURRENT_X = x, + LIGHT_COLOR_CURRENT_Y = y, + LIGHT_COLOR_CURRENT_COLOR_MODE = mode, + LIGHT_COLOR_CURRENT_PRESET_ID = currentColorPresetId, + }, "NOTIFY") +end + +local function notifyColorChanging(targetX, targetY, mode, rate) + log:debug("LIGHT_COLOR_CHANGING: x=%.4f y=%.4f mode=%s rate=%s", targetX, targetY, mode, rate) + SendToProxy(PROXY_BINDING, "LIGHT_COLOR_CHANGING", { + LIGHT_COLOR_CURRENT_X = currentColorX, + LIGHT_COLOR_CURRENT_Y = currentColorY, + LIGHT_COLOR_CURRENT_COLOR_MODE = currentColorMode, + LIGHT_COLOR_TARGET_X = targetX, + LIGHT_COLOR_TARGET_Y = targetY, + LIGHT_COLOR_TARGET_COLOR_MODE = mode, + -- Spec _10.7 names this LIGHT_COLOR_TARGET_COLOR_RATE; some older docs + -- and helper code use LIGHT_COLOR_TARGET_RATE so we send both for safety. + LIGHT_COLOR_TARGET_COLOR_RATE = rate, + LIGHT_COLOR_TARGET_RATE = rate, + LIGHT_COLOR_TARGET_PRESET_ID = currentColorPresetId, + }, "NOTIFY", true) +end + +-- Caller contract: only invoked when supportsDimming is true (lightOn/Off, +-- rampToBrightness, scene apply, etc. all gate on it). On/off-only entities +-- get a different code path that doesn't touch brightness. +local function setDeviceBrightness(level, rateMs) + local hasRate = rateMs and rateMs > 0 + local goingOn = level > 0 and currentBrightness == 0 + + -- Two-phase fade-up workaround. the device's light_call short-circuits on + -- state=false: brightness=0 in the same command is dropped, so the bulb's + -- stored brightness stays at whatever it was last set to (often 1.0). + -- When we then send state=true brightness=target with transition_length, + -- the device sees no brightness diff and the LED snaps on instead of fading. + -- Pre-pushing a state=true brightness=ε with transition=0 sets the stored + -- brightness to ~0 so the real ramp has a real diff to interpolate across. + -- 0.0039 = 1/256 — the smallest 8-bit PWM step, visually indistinguishable + -- from off. Using literal 0 risks the device converting state=true brightness=0 + -- back into state=false. + if goingOn and hasRate then + sendLightCommand({ + has_state = true, + state = true, + has_brightness = true, + brightness = 0.0039, + has_transition_length = true, + transition_length = 0, + }) + end + + -- Always include both state AND brightness in the command. The brightness + -- field is dropped by the device when state=false (see workaround above), but + -- including it for state=true is essential for the transition. + local cmd = { + has_state = true, + state = level > 0, + has_brightness = true, + brightness = (level > 0) and (level / 100.0) or 0, + has_transition_length = true, + -- A rate of 0 still gets sent so it cancels any in-flight transition on + -- the device rather than falling back to its default_transition_length. + transition_length = hasRate and rateMs or 0, + } + + -- Merge color into the brightness cmd so brightness+color animate as one + -- the device transition. Two scenarios: + -- 1. Dim-to-warm during any brightness change while fade mode is active + -- and not overridden — recompute via the formula every step. + -- 2. Off→on with any color on-mode (fade/previous/preset) — apply the + -- configured on-color in the same cmd. The proxy will typically also + -- send a SET_COLOR_TARGET right after this; mergedColorUntil makes + -- the SET_COLOR_TARGET handler skip a redundant the device cmd that + -- would otherwise cancel and restart the in-flight transition. + local mergedColor = nil + if level > 0 and not fadeOverride and getColorOnModeKind() == COLOR_ON_MODE_FADE then + mergedColor = computeFadeColor(level) + elseif goingOn then + mergedColor = resolveOnColor(level) + end + local mergedColorApplied = false + if mergedColor then + local colorFields = buildColorCmdFields(mergedColor.x, mergedColor.y, mergedColor.mode) + if colorFields then + for k, v in pairs(colorFields) do + cmd[k] = v + end + currentColorX = mergedColor.x + currentColorY = mergedColor.y + currentColorMode = mergedColor.mode + mergedColorApplied = true + -- Window during which a follow-up SET_COLOR_TARGET targeting the same + -- color is treated as already applied. 250ms covers the proxy's + -- typical inter-cmd gap (~6-50ms) with a margin. + mergedColorUntil = C4:GetTime() + 250 + -- The merged color is computed from on-mode rules (fade/previous/ + -- on-preset), not from an explicit SET_COLOR_TARGET. Clear any + -- lingering target-preset id so we don't echo a stale value. If the + -- proxy follows up with a SET_COLOR_TARGET inside mergedColorUntil, + -- that handler will set the correct id before brightnessRampFinished + -- emits the terminal LIGHT_COLOR_CHANGED. + currentColorPresetId = nil + -- Stash on the ramp metadata so brightnessRampFinished can emit the + -- terminal LIGHT_COLOR_CHANGED when the bulb's combined transition + -- completes. The proxy needs CHANGING (now) + CHANGED (at finish) to + -- keep its color-picker animation in sync. + if brightnessRamp then + brightnessRamp.mergedColor = { + x = mergedColor.x, + y = mergedColor.y, + mode = mergedColor.mode, + } + end + end + end + sendLightCommand(cmd) + -- Emit color CHANGING/CHANGED to mirror the brightness side: the proxy + -- doesn't always issue a SET_COLOR_TARGET (e.g. fade mode drives color + -- from the formula, not from a separate proxy-initiated cmd), so the + -- driver has to push these notifies for the picker to track. + if mergedColorApplied then + if hasRate then + notifyColorChanging(currentColorX, currentColorY, currentColorMode, rateMs) + else + notifyColorChanged(currentColorX, currentColorY, currentColorMode) + end + end +end + +--------------------------------------------------------------------------- +-- Helpers: brightness ramping +--------------------------------------------------------------------------- +-- the device has native transition_length smoothing on the bulb itself. We send +-- a single light_command with the full rate, the device handles the physical +-- ramp, and we track elapsed time locally so SET_BRIGHTNESS_STOP can +-- interpolate the device's current level mid-ramp using C4:GetTime() (ms). +-- +-- the device echoes one UPDATE_STATE per command it receives confirming the +-- target. During a ramp we ignore those echoes (rampingBrightness=true). +-- After the ramp ends we ignore brightness echoes for an additional grace +-- window in case stale echoes from a prior cmd arrive late and would +-- otherwise re-mutate currentBrightness and bounce the UI. + +local function cancelBrightnessRampTimers() + CancelTimer("BrightnessRampFinish") +end + +local function interpolatedBrightness() + if not brightnessRamp or brightnessRamp.durationMs <= 0 then + return currentBrightness + end + local elapsed = C4:GetTime() - brightnessRamp.startTime + if elapsed <= 0 then + return brightnessRamp.startLevel + end + if elapsed >= brightnessRamp.durationMs then + return brightnessRamp.targetLevel + end + local progress = elapsed / brightnessRamp.durationMs + local span = brightnessRamp.targetLevel - brightnessRamp.startLevel + return math.floor(brightnessRamp.startLevel + span * progress + 0.5) +end + +local function brightnessRampFinished(targetLevel) + cancelBrightnessRampTimers() + -- Capture mergedColor before nilling brightnessRamp so we can emit a + -- terminal LIGHT_COLOR_CHANGED for the color that piggybacked on this + -- ramp's transition_length (off→on with a configured on-color). + local mergedColor = brightnessRamp and brightnessRamp.mergedColor + rampingBrightness = false + brightnessRamp = nil + notifyBrightnessChanged(targetLevel) + if mergedColor then + notifyColorChanged(mergedColor.x, mergedColor.y, mergedColor.mode) + end +end + +-- Halt the in-flight the device transition at our interpolated current level. +local function brightnessRampStopped() + cancelBrightnessRampTimers() + if not rampingBrightness then + return + end + local stoppedAt = interpolatedBrightness() + rampingBrightness = false + brightnessRamp = nil + -- Cancel the device's in-flight transition by sending a 0-transition cmd at + -- the interpolated level. The bulb halts here. + setDeviceBrightness(stoppedAt, 0) + currentBrightness = stoppedAt + notifyBrightnessChanged(stoppedAt) +end + +local function rampToBrightness(level, rate, presetId) + level = math.max(0, math.min(100, math.floor((level or 0) + 0.5))) + rate = math.max(0, tointeger(rate) or 0) + + log:debug("rampToBrightness(%s, %s) from %s", level, rate, currentBrightness) + + -- Single source of truth for the active brightness preset id. SET_BRIGHTNESS_ + -- TARGET passes the proxy's id through; everywhere else (buttons, scenes, + -- lightOn, etc.) omits it so the id clears and CHANGED notifies don't echo + -- a stale value to the Daylight Agent. + currentBrightnessPresetId = presetId + + -- If a ramp is already running, snapshot the interpolated current level + -- before starting the new ramp so CHANGING tracks correctly and a future + -- STOP would interpolate from the right starting point. + if rampingBrightness then + currentBrightness = interpolatedBrightness() + end + + cancelBrightnessRampTimers() + rampingBrightness = false + brightnessRamp = nil + + local startingLevel = currentBrightness + if level == startingLevel then + notifyBrightnessChanged(level) + return + end + + if rate == 0 then + setDeviceBrightness(level, 0) + notifyBrightnessChanged(level) + return + end + + rampingBrightness = true + brightnessRamp = { + startTime = C4:GetTime(), + startLevel = startingLevel, + targetLevel = level, + durationMs = rate, + } + -- Single the device command - the bulb handles the physical transition. + setDeviceBrightness(level, rate) + notifyBrightnessChanging(level, rate) + SetTimer("BrightnessRampFinish", rate, function() + -- Belt-and-suspenders: snap state with a 0-transition cmd at target so + -- our state matches the bulb's even if the transition completed slightly + -- before/after our timer. + setDeviceBrightness(level, 0) + currentBrightness = level + brightnessRampFinished(level) + end, false) +end + +--------------------------------------------------------------------------- +-- Helpers: color ramping +--------------------------------------------------------------------------- +-- Same shape as brightness ramping: send a single the device light_command with +-- transition_length = rateMs so the bulb interpolates the physical color, and +-- track the logical color locally via a startTime/duration ramp record. + +local function cancelColorRampTimers() + CancelTimer("ColorRampFinish") +end + +-- Build and send an the device light_command reflecting the given color state. +local function sendColor(x, y, mode, rateMs) + if not (supportsColor or supportsCCT) then + return + end + -- isLogicallyOn so that a SET_COLOR_TARGET arriving mid-ramp from off→on + -- doesn't send state=false (which would cancel the brightness transition). + local cmd = { has_state = true, state = isLogicallyOn() } + if mode == LIGHT_COLOR_MODE_CCT and supportsCCT then + local k = tonumber(C4:ColorXYtoCCT(x, y)) + if k and k > 0 then + cmd.has_color_temperature = true + cmd.color_temperature = kelvinToMireds(k) + end + elseif supportsColor then + local r, g, b = xyToRGB(x, y) + cmd.has_rgb = true + cmd.red = r + cmd.green = g + cmd.blue = b + end + cmd.has_transition_length = true + cmd.transition_length = (rateMs and rateMs > 0) and rateMs or 0 + sendLightCommand(cmd) +end + +local function interpolatedColor() + if not colorRamp or colorRamp.durationMs <= 0 then + return currentColorX, currentColorY, currentColorMode + end + local elapsed = C4:GetTime() - colorRamp.startTime + if elapsed <= 0 then + return colorRamp.startX, colorRamp.startY, colorRamp.targetMode + end + if elapsed >= colorRamp.durationMs then + return colorRamp.targetX, colorRamp.targetY, colorRamp.targetMode + end + local progress = elapsed / colorRamp.durationMs + local x = colorRamp.startX + (colorRamp.targetX - colorRamp.startX) * progress + local y = colorRamp.startY + (colorRamp.targetY - colorRamp.startY) * progress + return x, y, colorRamp.targetMode +end + +local function colorRampFinished(targetX, targetY, targetMode) + cancelColorRampTimers() + rampingColor = false + colorRamp = nil + notifyColorChanged(targetX, targetY, targetMode) +end + +local function colorRampStopped() + cancelColorRampTimers() + if not rampingColor then + return + end + local x, y, mode = interpolatedColor() + rampingColor = false + colorRamp = nil + sendColor(x, y, mode, 0) + currentColorX = x + currentColorY = y + currentColorMode = mode + notifyColorChanged(x, y, mode) +end + +local function rampToColor(targetX, targetY, targetMode, rate) + rate = math.max(0, tointeger(rate) or 0) + + if rampingColor then + local x, y, _ = interpolatedColor() + currentColorX = x + currentColorY = y + end + + cancelColorRampTimers() + rampingColor = false + colorRamp = nil + + if rate == 0 then + currentColorX = targetX + currentColorY = targetY + currentColorMode = targetMode + sendColor(targetX, targetY, targetMode, 0) + notifyColorChanged(targetX, targetY, targetMode) + return + end + + rampingColor = true + colorRamp = { + startTime = C4:GetTime(), + startX = currentColorX, + startY = currentColorY, + targetX = targetX, + targetY = targetY, + targetMode = targetMode, + durationMs = rate, + } + -- Mode change is logically instantaneous; mid-ramp we're interpolating XY. + currentColorMode = targetMode + sendColor(targetX, targetY, targetMode, rate) + notifyColorChanging(targetX, targetY, targetMode, rate) + SetTimer("ColorRampFinish", rate, function() + sendColor(targetX, targetY, targetMode, 0) + currentColorX = targetX + currentColorY = targetY + currentColorMode = targetMode + colorRampFinished(targetX, targetY, targetMode) + end, false) +end + +--------------------------------------------------------------------------- +-- Helpers: on / off / toggle +--------------------------------------------------------------------------- + +local function lightOn(rate) + local level = getOnBrightness() + if not supportsDimming then + sendLightCommand({ has_state = true, state = true }) + notifyBrightnessChanged(100) + return + end + -- color_on_mode_previous/preset/fade are all handled by the merged-color + -- path inside setDeviceBrightness (via resolveOnColor on goingOn) so the + -- color rides on the brightness transition as a single the device cmd. Don't + -- pre-send a separate color cmd here; that would queue two commands and + -- the second would cancel and restart the in-flight transition. + rampToBrightness(level, rate or 0) +end + +local function lightOff(rate) + if supportsDimming then + rampToBrightness(0, rate or 0) + else + sendLightCommand({ has_state = true, state = false }) + notifyBrightnessChanged(0) + end +end + +local function lightToggle(rate) + if currentBrightness > 0 then + lightOff(rate) + else + lightOn(rate) + end +end + +--------------------------------------------------------------------------- +-- RFP: LIGHT_V2 proxy commands +--------------------------------------------------------------------------- + +function RFP.SET_BRIGHTNESS_TARGET(idBinding, strCommand, tParams, args) + log:trace("RFP.SET_BRIGHTNESS_TARGET(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local level = tonumber(Select(tParams, "LIGHT_BRIGHTNESS_TARGET")) or 0 + local rate = tointeger(Select(tParams, "RATE")) or getDefaultRate() + -- spec _2.1: optional LIGHT_BRIGHTNESS_TARGET_PRESET_ID identifies the + -- preset (e.g. Daylight Agent) driving this target. Pass it through so + -- subsequent LIGHT_BRIGHTNESS_CHANGED notifies report it as the current + -- preset id; other rampToBrightness call sites omit it and clear the id. + local presetId = tointeger(Select(tParams, "LIGHT_BRIGHTNESS_TARGET_PRESET_ID")) + rampToBrightness(level, rate, presetId) +end + +function RFP.ON(idBinding, strCommand, tParams, args) + log:trace("RFP.ON(%s, %s)", idBinding, strCommand) + if idBinding ~= PROXY_BINDING then + return + end + lightOn() +end + +function RFP.OFF(idBinding, strCommand, tParams, args) + log:trace("RFP.OFF(%s, %s)", idBinding, strCommand) + if idBinding ~= PROXY_BINDING then + return + end + lightOff() +end + +function RFP.TOGGLE(idBinding, strCommand, tParams, args) + log:trace("RFP.TOGGLE(%s, %s)", idBinding, strCommand) + if idBinding ~= PROXY_BINDING then + return + end + lightToggle() +end + +-- DYNAMIC_ON / DYNAMIC_OFF (spec _1.3 / _1.2): O.S. 3.3.2+ Navigators send +-- these instead of plain ON/OFF for generic on/off interactions, allowing +-- the proxy to apply on-mode behavior (color fade, previous color, etc.). +-- We treat them identically to ON / OFF since lightOn/lightOff already +-- consult on-mode state. +function RFP.DYNAMIC_ON(idBinding, strCommand, tParams, args) + log:trace("RFP.DYNAMIC_ON(%s, %s)", idBinding, strCommand) + if idBinding ~= PROXY_BINDING then + return + end + lightOn() +end + +function RFP.DYNAMIC_OFF(idBinding, strCommand, tParams, args) + log:trace("RFP.DYNAMIC_OFF(%s, %s)", idBinding, strCommand) + if idBinding ~= PROXY_BINDING then + return + end + lightOff() +end + +function RFP.SET_LEVEL(idBinding, strCommand, tParams, args) + log:trace("RFP.SET_LEVEL(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local level = tointeger(Select(tParams, "LEVEL")) or 0 + if supportsDimming then + rampToBrightness(level, 0) + elseif level > 0 then + lightOn() + else + lightOff() + end +end + +-- Legacy command, retained for compatibility with older Composer programming +-- and Alexa Voice Scenes (other LIGHT_V2 drivers carry the same forwarder). +function RFP.RAMP_TO_LEVEL(idBinding, strCommand, tParams, args) + log:trace("RFP.RAMP_TO_LEVEL(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + RFP.SET_BRIGHTNESS_TARGET(idBinding, "SET_BRIGHTNESS_TARGET", { + LIGHT_BRIGHTNESS_TARGET = Select(tParams, "LEVEL"), + RATE = Select(tParams, "TIME"), + }) +end + +function RFP.SET_COLOR_TARGET(idBinding, strCommand, tParams, args) + log:trace("RFP.SET_COLOR_TARGET(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + + local kelvin = tonumber(Select(tParams, "LIGHT_COLOR_TARGET_COLOR_CORRELATED_TEMPERATURE")) + local x = tonumber(Select(tParams, "LIGHT_COLOR_TARGET_X")) + local y = tonumber(Select(tParams, "LIGHT_COLOR_TARGET_Y")) + local incomingMode = tointeger(Select(tParams, "LIGHT_COLOR_TARGET_MODE")) + local rate = tointeger( + Select(tParams, "LIGHT_COLOR_TARGET_COLOR_RATE") + or Select(tParams, "LIGHT_COLOR_TARGET_RATE") + or Select(tParams, "RATE") + ) or getDefaultColorRate() + + -- spec _3.1: if the proxy named a color preset and didn't pass explicit + -- coordinates, look the preset up locally so the bulb still receives + -- concrete values. Track the preset id either way so subsequent + -- LIGHT_COLOR_CHANGED notifies report it as the current preset. + local presetId = tointeger(Select(tParams, "LIGHT_COLOR_TARGET_PRESET_ID")) + if presetId ~= nil and not (x and y) and not (kelvin and kelvin > 0) then + local preset = (persist:get(P_COLOR_PRESETS) or {})[tostring(presetId)] + if preset then + x = preset.x + y = preset.y + incomingMode = preset.mode + else + log:warn("SET_COLOR_TARGET: unknown LIGHT_COLOR_TARGET_PRESET_ID=%s", presetId) + return + end + end + currentColorPresetId = presetId + + local targetX, targetY, targetMode + + if kelvin and kelvin > 0 and supportsCCT then + targetX, targetY = C4:ColorCCTtoXY(kelvin) + targetMode = LIGHT_COLOR_MODE_CCT + elseif incomingMode == LIGHT_COLOR_MODE_CCT and supportsCCT and x and y then + local k = tonumber(C4:ColorXYtoCCT(x, y)) + if not k or k <= 0 then + log:warn("SET_COLOR_TARGET: ColorXYtoCCT(%s, %s) returned %s", x, y, tostring(k)) + return + end + targetX, targetY, targetMode = x, y, LIGHT_COLOR_MODE_CCT + elseif x and y and supportsColor then + targetX, targetY, targetMode = x, y, LIGHT_COLOR_MODE_FULL + else + log:warn( + "SET_COLOR_TARGET ignored (kelvin=%s x=%s y=%s mode=%s color=%s cct=%s)", + tostring(kelvin), + tostring(x), + tostring(y), + tostring(incomingMode), + tostring(supportsColor), + tostring(supportsCCT) + ) + return + end + + -- Spec _7.2: any explicit SET_COLOR_TARGET while in fade mode disables the + -- formula until the next off→on cycle. We track this so subsequent + -- SET_BRIGHTNESS_TARGET commands during the same on cycle don't re-apply + -- dim-to-warm. + if currentBrightness > 0 then + fadeOverride = true + end + + -- Skip the device cmd if a SET_BRIGHTNESS_TARGET right before us already + -- merged this color into the brightness ramp cmd. Otherwise we'd send a + -- second cmd to the device that cancels and restarts the in-flight transition, + -- making the brightness fade-up snap visually. The earlier merged-color + -- path already emitted notifyColorChanging, and brightnessRampFinished + -- will emit notifyColorChanged when the ramp completes - so there is + -- nothing to notify here, just suppress the redundant the device cmd. + local now = C4:GetTime() + if now < mergedColorUntil and rampingBrightness then + log:debug("SET_COLOR_TARGET deduped (%sms remaining in merged-color window)", mergedColorUntil - now) + currentColorX = targetX + currentColorY = targetY + currentColorMode = targetMode + return + end + + rampToColor(targetX, targetY, targetMode, rate) +end + +-- Halt an in-flight brightness transition at the current stepped level. +function RFP.SET_BRIGHTNESS_STOP(idBinding, strCommand, tParams, args) + log:trace("RFP.SET_BRIGHTNESS_STOP(%s, %s)", idBinding, strCommand) + if idBinding ~= PROXY_BINDING then + return + end + brightnessRampStopped() +end + +-- Spec _4 / _5: cap the on-level range. Stored in persist; rampToBrightness +-- doesn't enforce them today (the device bulbs natively go 0-100), but we +-- echo the value back per-spec so the proxy and Composer track the setting. +function RFP.SET_MAX_ON_LEVEL(idBinding, strCommand, tParams, args) + log:trace("RFP.SET_MAX_ON_LEVEL(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local level = math.max(0, math.min(100, tointeger(Select(tParams, "LEVEL")) or 100)) + persist:set(P_MAX_ON_LEVEL, level) + SendToProxy(PROXY_BINDING, "MAX_ON", tostring(level), "NOTIFY") +end + +function RFP.SET_MIN_ON_LEVEL(idBinding, strCommand, tParams, args) + log:trace("RFP.SET_MIN_ON_LEVEL(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local level = math.max(0, math.min(100, tointeger(Select(tParams, "LEVEL")) or 0)) + persist:set(P_MIN_ON_LEVEL, level) + SendToProxy(PROXY_BINDING, "MIN_ON", tostring(level), "NOTIFY") +end + +-- Halt an in-flight color transition at the current stepped XY/mode. +function RFP.SET_COLOR_STOP(idBinding, strCommand, tParams, args) + log:trace("RFP.SET_COLOR_STOP(%s, %s)", idBinding, strCommand) + if idBinding ~= PROXY_BINDING then + return + end + colorRampStopped() +end + +function RFP.GET_CONNECTED_STATE(idBinding, strCommand, tParams, args) + log:trace("RFP.GET_CONNECTED_STATE(%s, %s)", idBinding, strCommand) + if idBinding ~= PROXY_BINDING then + return + end + SendToProxy(PROXY_BINDING, "ONLINE_CHANGED", { STATE = STATE ~= nil }, "NOTIFY") +end + +-- Legacy: re-emit the current brightness when the proxy asks. Modern callers +-- read the cached BRIGHTNESS_PERCENT variable, but the LIGHT_V2 contract +-- includes this command for compatibility. +function RFP.GET_LIGHT_LEVEL(idBinding, strCommand, tParams, args) + log:trace("RFP.GET_LIGHT_LEVEL(%s, %s)", idBinding, strCommand) + if idBinding ~= PROXY_BINDING then + return + end + notifyBrightnessChanged(currentBrightness) +end + +--------------------------------------------------------------------------- +-- Scene support (Advanced Lighting Scenes) +--------------------------------------------------------------------------- + +local function getScenes() + return persist:get(P_SCENES, {}) +end + +local function saveScenes(scenes) + persist:set(P_SCENES, scenes) +end + +-- Parse the LIGHT_V2 scene XML. The proxy passes a string of one or +-- more ... blocks describing what to do at each step. +-- Returns an array of normalized step tables. +local function parseSceneElements(elementsXml) + local steps = {} + if IsEmpty(elementsXml) then + return steps + end + local parsed = ParseXml("" .. elementsXml .. "") + local elementList = Select(parsed, "root", "element") or {} + if not IsList(elementList) then + elementList = { elementList } + end + for _, el in ipairs(elementList) do + if type(el) == "table" then + local rawBrightnessEnabled = Select(el, "brightnessEnabled") + local rawColorEnabled = Select(el, "colorEnabled") + local step = { + delay = tointeger(Select(el, "delay")) or 0, + brightnessRate = tointeger(Select(el, "brightnessRate") or Select(el, "rate")) or 0, + colorRate = tointeger(Select(el, "colorRate")) or 0, + level = tointeger(Select(el, "brightness") or Select(el, "level")), + levelEnabled = toboolean(rawBrightnessEnabled), + colorEnabled = toboolean(rawColorEnabled), + colorX = tonumber(Select(el, "colorX")), + colorY = tonumber(Select(el, "colorY")), + colorMode = tointeger(Select(el, "colorMode")), + } + -- Legacy schemas put at the element root with no + -- wrapper. Only promote when the wrapper is truly absent, not when it's + -- explicitly false (toboolean collapses nil and "false" to the same value). + if rawBrightnessEnabled == nil and rawColorEnabled == nil and step.level ~= nil then + step.levelEnabled = true + end + if step.colorRate == 0 and step.brightnessRate > 0 then + step.colorRate = step.brightnessRate + end + if step.levelEnabled or step.colorEnabled or step.delay > 0 then + table.insert(steps, step) + end + end + end + log:debug("parseSceneElements: %d step(s) parsed", #steps) + return steps +end + +-- Bumped any time we want to invalidate in-flight scene step callbacks. The +-- timer names alone don't always prevent a callback already queued by SetTimer +-- from running, so each step closure captures the generation it was born under +-- and bails out if it has changed. +local sceneGeneration = 0 + +local function stopAllScenes() + sceneGeneration = sceneGeneration + 1 + CancelTimer(SCENE_RAMP_TIMER) + local scenes = getScenes() + for sceneId, _ in pairs(scenes) do + CancelTimer(SCENE_TIMER_PREFIX .. tostring(sceneId)) + end + -- Drop any ramp state primed by an in-flight scene step so future echoes + -- don't get suppressed forever. Notify hooks that fired CHANGING are + -- finalised by the bulb's own state echo when ramping flags are cleared. + rampingBrightness = false + rampingColor = false + brightnessRamp = nil + colorRamp = nil +end + +local function applySceneStep(step) + -- Build one combined light_command so the device transitions atomically when + -- both brightness and color change in the same step. + if not step.levelEnabled and not step.colorEnabled then + return 0 + end + -- Cancel any in-flight ramp (whether from a prior step or a non-scene cmd) + -- and reset the flags so we can re-prime per this step's rates below. The + -- echo-suppression contract in UPDATE_STATE relies on rampingBrightness/ + -- rampingColor matching the cmd we are about to send. + cancelBrightnessRampTimers() + cancelColorRampTimers() + rampingBrightness = false + rampingColor = false + brightnessRamp = nil + colorRamp = nil + local cmd = {} + -- the device takes a single transition_length per cmd, so the bulb interpolates + -- both brightness and color over the longer of the two requested rates. Use + -- that unified rate for ramp metadata and notify payloads so the proxy's + -- picker animation, the local STOP-mid-step interpolation, and the SCENE_ + -- TIMER all agree on when the transition actually completes. + local rate = math.max(step.brightnessRate or 0, step.colorRate or 0) + if rate > 0 then + cmd.has_transition_length = true + cmd.transition_length = rate + end + local startTime = C4:GetTime() + -- A level of 0 means "off"; the color block is metadata for the next on. + -- Don't send color/RGB fields in that case so the device actually turns off. + local turningOff = step.levelEnabled and step.level == 0 + if step.levelEnabled and step.level ~= nil then + cmd.has_state = true + cmd.state = step.level > 0 + if step.level > 0 and supportsDimming then + cmd.has_brightness = true + cmd.brightness = step.level / 100.0 + end + -- Scene step is driving brightness directly; clear any active preset id + -- so subsequent CHANGED notifies don't echo a stale value. Color-only + -- steps don't touch this so a brightness preset can survive across them. + currentBrightnessPresetId = nil + -- Only prime a ramp when the level actually moves; an explicit step at + -- the current level with rate>0 would otherwise queue a pointless picker + -- animation and suppress the next echo for no reason. + if rate > 0 and step.level ~= currentBrightness then + rampingBrightness = true + brightnessRamp = { + startTime = startTime, + startLevel = currentBrightness, + targetLevel = step.level, + durationMs = rate, + } + notifyBrightnessChanging(step.level, rate) + end + end + if step.colorEnabled and step.colorX and step.colorY and not turningOff then + local mode = step.colorMode or LIGHT_COLOR_MODE_FULL + if mode == LIGHT_COLOR_MODE_CCT and supportsCCT then + local k = tonumber(C4:ColorXYtoCCT(step.colorX, step.colorY)) + if k and k > 0 then + cmd.has_color_temperature = true + cmd.color_temperature = kelvinToMireds(k) + end + elseif supportsColor then + local r, g, b = xyToRGB(step.colorX, step.colorY) + cmd.has_rgb = true + cmd.red = r + cmd.green = g + cmd.blue = b + end + cmd.has_state = true + cmd.state = true + currentColorPresetId = nil + local colorChanged = math.abs(step.colorX - currentColorX) > 1e-4 + or math.abs(step.colorY - currentColorY) > 1e-4 + or mode ~= currentColorMode + if rate > 0 and colorChanged then + rampingColor = true + colorRamp = { + startTime = startTime, + startX = currentColorX, + startY = currentColorY, + targetX = step.colorX, + targetY = step.colorY, + targetMode = mode, + durationMs = rate, + } + notifyColorChanging(step.colorX, step.colorY, mode, rate) + end + end + if next(cmd) ~= nil then + sendLightCommand(cmd) + end + return rate +end + +local function runScene(sceneId, generation) + if generation ~= nil and generation ~= sceneGeneration then + return + end + local gen = generation or sceneGeneration + local scenes = getScenes() + local scene = scenes[tostring(sceneId)] + if not scene then + log:warn("Scene %s not found", sceneId) + return + end + scene.state = scene.state or 0 + local timerName = SCENE_TIMER_PREFIX .. tostring(sceneId) + CancelTimer(timerName) + + while true do + if gen ~= sceneGeneration then + return + end + local idx = scene.state + 1 + if idx > #scene.elements then + if scene.flash then + scene.state = 0 + idx = 1 + else + scene.state = 0 + scenes[tostring(sceneId)] = scene + saveScenes(scenes) + return + end + end + local step = scene.elements[idx] + local delay = math.max(0, step.delay or 0) + scene.state = idx + scenes[tostring(sceneId)] = scene + saveScenes(scenes) + + -- When a step's ramp elapses, finalise any in-flight ramp metadata so + -- rampingBrightness/rampingColor are cleared and CHANGED notifies fire + -- before we apply the next step. + local function finishRampsAndAdvance() + if brightnessRamp and brightnessRamp.targetLevel ~= nil then + brightnessRampFinished(brightnessRamp.targetLevel) + end + if colorRamp and colorRamp.targetX and colorRamp.targetY and colorRamp.targetMode then + colorRampFinished(colorRamp.targetX, colorRamp.targetY, colorRamp.targetMode) + end + runScene(sceneId, gen) + end + + if delay > 0 then + SetTimer(timerName, delay, function() + if gen ~= sceneGeneration then + return + end + local rampMs = applySceneStep(step) + if rampMs > 0 then + SetTimer(timerName, rampMs, finishRampsAndAdvance) + else + runScene(sceneId, gen) + end + end) + return + end + + local rampMs = applySceneStep(step) + if rampMs > 0 then + SetTimer(timerName, rampMs, finishRampsAndAdvance) + return + end + -- otherwise loop synchronously to the next element + end +end + +function RFP.PUSH_SCENE(idBinding, strCommand, tParams, args) + log:trace("RFP.PUSH_SCENE(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local sceneId = tointeger(Select(tParams, "SCENE_ID")) + if sceneId == nil then + return + end + local elements = Select(tParams, "ELEMENTS") + local scenes = getScenes() + scenes[tostring(sceneId)] = { + elements = parseSceneElements(elements), + flash = toboolean(Select(tParams, "FLASH")), + ignoreRamp = toboolean(Select(tParams, "IGNORE_RAMP")), + fromGroup = toboolean(Select(tParams, "FROM_GROUP")), + state = 0, + } + saveScenes(scenes) + log:debug("Stored scene %s with %d element(s)", sceneId, #scenes[tostring(sceneId)].elements) +end + +function RFP.REMOVE_SCENE(idBinding, strCommand, tParams, args) + log:trace("RFP.REMOVE_SCENE(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local sceneId = tointeger(Select(tParams, "SCENE_ID")) + if sceneId == nil then + return + end + CancelTimer(SCENE_TIMER_PREFIX .. tostring(sceneId)) + local scenes = getScenes() + scenes[tostring(sceneId)] = nil + saveScenes(scenes) +end + +function RFP.CLEAR_ALL_SCENES(idBinding, strCommand, tParams, args) + log:trace("RFP.CLEAR_ALL_SCENES(%s, %s)", idBinding, strCommand) + if idBinding ~= PROXY_BINDING then + return + end + stopAllScenes() + saveScenes({}) +end + +function RFP.ALL_SCENES_PUSHED(idBinding, strCommand, tParams, args) + log:trace("RFP.ALL_SCENES_PUSHED(%s, %s)", idBinding, strCommand) + -- Marker that the proxy has finished pushing scenes; nothing to do. +end + +function RFP.ACTIVATE_SCENE(idBinding, strCommand, tParams, args) + log:trace("RFP.ACTIVATE_SCENE(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local sceneId = tointeger(Select(tParams, "SCENE_ID")) + if sceneId == nil then + return + end + stopAllScenes() + local scenes = getScenes() + local scene = scenes[tostring(sceneId)] + if not scene then + log:warn("ACTIVATE_SCENE: unknown scene id %s", sceneId) + return + end + scene.state = 0 + scenes[tostring(sceneId)] = scene + saveScenes(scenes) + runScene(sceneId) +end + +function RFP.DEACTIVATE_SCENE(idBinding, strCommand, tParams, args) + log:trace("RFP.DEACTIVATE_SCENE(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + -- The Advanced Lighting agent uses DEACTIVATE_SCENE to mark a scene "off" + -- in its own bookkeeping. Our driver doesn't track which scene is currently + -- "active" (the device just reflects the last commands sent), so we just + -- stop any running scene playback. + stopAllScenes() +end + +function RFP.RAMP_SCENE_UP(idBinding, strCommand, tParams, args) + log:trace("RFP.RAMP_SCENE_UP(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local sceneId = tointeger(Select(tParams, "SCENE_ID")) + local rate = tointeger(Select(tParams, "RATE")) or 0 + local scenes = getScenes() + local scene = sceneId and scenes[tostring(sceneId)] + if scene and scene.ignoreRamp then + return + end + stopAllScenes() + if supportsDimming then + rampToBrightness(getOnBrightness(), rate) + else + lightOn() + end +end + +function RFP.RAMP_SCENE_DOWN(idBinding, strCommand, tParams, args) + log:trace("RFP.RAMP_SCENE_DOWN(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local sceneId = tointeger(Select(tParams, "SCENE_ID")) + local rate = tointeger(Select(tParams, "RATE")) or 0 + local scenes = getScenes() + local scene = sceneId and scenes[tostring(sceneId)] + if scene and scene.ignoreRamp then + return + end + stopAllScenes() + if supportsDimming then + rampToBrightness(0, rate) + else + lightOff() + end +end + +function RFP.STOP_SCENE_RAMP(idBinding, strCommand, tParams, args) + log:trace("RFP.STOP_SCENE_RAMP(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + stopAllScenes() + brightnessRampStopped() + colorRampStopped() +end + +-- The published spec calls this command STOP_RAMP_SCENE; older / template code +-- uses STOP_SCENE_RAMP. Register both so the proxy can reach us either way. +RFP.STOP_RAMP_SCENE = RFP.STOP_SCENE_RAMP + +function RFP.TOGGLE_SCENE(idBinding, strCommand, tParams, args) + log:trace("RFP.TOGGLE_SCENE(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + -- We don't track per-scene "active" state on the device side, so we always + -- activate the requested scene. The agent's own bookkeeping handles toggle + -- semantics across the project. + RFP.ACTIVATE_SCENE(idBinding, "ACTIVATE_SCENE", tParams) +end + +--------------------------------------------------------------------------- +-- RFP: preset and rate management +--------------------------------------------------------------------------- + +function RFP.SET_PRESET_LEVEL(idBinding, strCommand, tParams, args) + log:trace("RFP.SET_PRESET_LEVEL(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local level = tointeger(Select(tParams, "LEVEL")) or DEFAULT_PRESET_LEVEL + persist:set(P_PRESET_LEVEL, level) + -- PRESET_LEVEL notify takes a single BRIGHTNESS value (1-100) as a plain + -- string, not a parameter map. Sending it as {BRIGHTNESS=N} causes the + -- proxy to reject the value and revert the preset to 0 - blocking users + -- from changing the Default On level in Composer. + SendToProxy(PROXY_BINDING, "PRESET_LEVEL", tostring(level), "NOTIFY") +end + +function RFP.UPDATE_BRIGHTNESS_ON_MODE(idBinding, strCommand, tParams, args) + log:trace("RFP.UPDATE_BRIGHTNESS_ON_MODE(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local presetId = tointeger(Select(tParams, "BRIGHTNESS_PRESET_ID")) + local presetLevel = tonumber(Select(tParams, "BRIGHTNESS_PRESET_LEVEL")) or DEFAULT_PRESET_LEVEL + persist:set(P_ON_MODE, { id = presetId, level = presetLevel }) +end + +-- Per spec _21.2: SET_BRIGHTNESS_ON_MODE is sent by the proxy to tell the +-- driver which preset ID should be used as the "On" target. When the proxy +-- isn't the initiator (button link, scene), we use this to know what level +-- to ramp to. +function RFP.SET_BRIGHTNESS_ON_MODE(idBinding, strCommand, tParams, args) + log:trace("RFP.SET_BRIGHTNESS_ON_MODE(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local presetId = tointeger(Select(tParams, "PRESET_ID")) + if presetId == nil then + return + end + persist:set(P_BRIGHTNESS_ON_MODE_PRESET, presetId) + -- Look up the preset's current level so getOnBrightness uses it immediately. + local presets = persist:get(P_BRIGHTNESS_PRESETS) or {} + local preset = presets[tostring(presetId)] + if preset and preset.level then + persist:set(P_ON_MODE, { id = presetId, level = preset.level }) + end +end + +function RFP.UPDATE_BRIGHTNESS_PRESET(idBinding, strCommand, tParams, args) + log:trace("RFP.UPDATE_BRIGHTNESS_PRESET(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local command = Select(tParams, "COMMAND") + local presetId = tointeger(Select(tParams, "ID")) + local level = tonumber(Select(tParams, "LEVEL")) + local name = Select(tParams, "NAME") + if presetId == nil then + return + end + local presets = persist:get(P_BRIGHTNESS_PRESETS) or {} + local key = tostring(presetId) + if command == "REMOVED" then + presets[key] = nil + else + presets[key] = { id = presetId, name = name, level = level } + end + persist:set(P_BRIGHTNESS_PRESETS, presets) + -- If this preset is the currently-active on-mode preset, refresh the + -- on-mode level so getOnBrightness picks up the change immediately. + local activeId = tointeger(persist:get(P_BRIGHTNESS_ON_MODE_PRESET)) + if activeId ~= nil and activeId == presetId then + if level == nil then + persist:delete(P_ON_MODE) + else + persist:set(P_ON_MODE, { id = presetId, level = level }) + end + end +end + +-- color_rate_behavior=1: brightness and color share a single default rate. +-- Composer's "Default Brightness and Color Rate" only sets one value; we +-- persist both keys to the same rate so the two getters can't drift. +function RFP.UPDATE_BRIGHTNESS_RATE_DEFAULT(idBinding, strCommand, tParams, args) + log:trace("RFP.UPDATE_BRIGHTNESS_RATE_DEFAULT(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local rate = tointeger(Select(tParams, "RATE")) or DEFAULT_RATE + persist:set(P_RATE_DEFAULT, rate) + persist:set(P_COLOR_RATE_DEFAULT, rate) +end + +function RFP.UPDATE_COLOR_RATE_DEFAULT(idBinding, strCommand, tParams, args) + log:trace("RFP.UPDATE_COLOR_RATE_DEFAULT(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local rate = tointeger(Select(tParams, "RATE")) or DEFAULT_RATE + persist:set(P_COLOR_RATE_DEFAULT, rate) + persist:set(P_RATE_DEFAULT, rate) +end + +-- Persist color presets keyed by ID so we can apply them when the proxy is +-- not the initiator (button link, scene, programming, dim-to-warm fade). +function RFP.UPDATE_COLOR_PRESET(idBinding, strCommand, tParams, args) + log:trace("RFP.UPDATE_COLOR_PRESET(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local command = Select(tParams, "COMMAND") + local presetId = tointeger(Select(tParams, "ID")) + if presetId == nil then + return + end + local presets = persist:get(P_COLOR_PRESETS) or {} + local key = tostring(presetId) + if command == "REMOVED" then + presets[key] = nil + else + presets[key] = { + id = presetId, + name = Select(tParams, "NAME"), + x = tonumber(Select(tParams, "COLOR_X")), + y = tonumber(Select(tParams, "COLOR_Y")), + mode = tointeger(Select(tParams, "COLOR_MODE")), + } + end + persist:set(P_COLOR_PRESETS, presets) +end + +-- Per spec _20.4: UPDATE_COLOR_ON_MODE carries the active On preset (and a +-- separate Fade pair for Dim-To-Warm). We persist both so we can drive color +-- ourselves on non-proxy on actions and apply the fade formula. +function RFP.UPDATE_COLOR_ON_MODE(idBinding, strCommand, tParams, args) + log:trace("RFP.UPDATE_COLOR_ON_MODE(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local mode = { + onPreset = { + id = tointeger(Select(tParams, "COLOR_PRESET_ID")), + origin = tointeger(Select(tParams, "COLOR_PRESET_ORIGIN")), + x = tonumber(Select(tParams, "COLOR_PRESET_COLOR_X")), + y = tonumber(Select(tParams, "COLOR_PRESET_COLOR_Y")), + mode = tointeger(Select(tParams, "COLOR_PRESET_COLOR_MODE")), + }, + fadePreset = { + id = tointeger(Select(tParams, "COLOR_FADE_PRESET_ID")), + origin = tointeger(Select(tParams, "COLOR_FADE_PRESET_ORIGIN")), + x = tonumber(Select(tParams, "COLOR_FADE_PRESET_COLOR_X")), + y = tonumber(Select(tParams, "COLOR_FADE_PRESET_COLOR_Y")), + mode = tointeger(Select(tParams, "COLOR_FADE_PRESET_COLOR_MODE")), + }, + } + persist:set(P_COLOR_ON_MODE, mode) +end + +-- SET_COLOR_ON_MODE (spec _9.1): proxy tells the driver which mode is active +-- (preset / fade / previous). We persist the mode kind so we can branch in +-- lightOn and brightness handling. +function RFP.SET_COLOR_ON_MODE(idBinding, strCommand, tParams, args) + log:trace("RFP.SET_COLOR_ON_MODE(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local presetId = tointeger(Select(tParams, "PRESET_ID")) + persist:set(P_COLOR_ON_MODE_PRESET, presetId) + -- A fresh on-mode selection clears any prior fadeOverride so the formula + -- runs again on the next on cycle. + fadeOverride = false +end + +-- Click/hold rate echo notifies follow the same convention as PRESET_LEVEL: +-- the proxy expects a plain string with the rate value, not a parameter map. +-- Sending {RATE=N} causes the proxy to reject the value and revert the +-- setting to 0, which is why Composer keeps showing 0 after a save. +function RFP.SET_CLICK_RATE_UP(idBinding, strCommand, tParams, args) + log:trace("RFP.SET_CLICK_RATE_UP(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local rate = tointeger(Select(tParams, "RATE")) or DEFAULT_CLICK_RATE + persist:set(P_CLICK_RATE_UP, rate) + SendToProxy(PROXY_BINDING, "CLICK_RATE_UP", tostring(rate), "NOTIFY") +end + +function RFP.SET_CLICK_RATE_DOWN(idBinding, strCommand, tParams, args) + log:trace("RFP.SET_CLICK_RATE_DOWN(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local rate = tointeger(Select(tParams, "RATE")) or DEFAULT_CLICK_RATE + persist:set(P_CLICK_RATE_DOWN, rate) + SendToProxy(PROXY_BINDING, "CLICK_RATE_DOWN", tostring(rate), "NOTIFY") +end + +function RFP.SET_HOLD_RATE_UP(idBinding, strCommand, tParams, args) + log:trace("RFP.SET_HOLD_RATE_UP(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local rate = tointeger(Select(tParams, "RATE")) or DEFAULT_HOLD_RATE + persist:set(P_HOLD_RATE_UP, rate) + SendToProxy(PROXY_BINDING, "HOLD_RATE_UP", tostring(rate), "NOTIFY") +end + +function RFP.SET_HOLD_RATE_DOWN(idBinding, strCommand, tParams, args) + log:trace("RFP.SET_HOLD_RATE_DOWN(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local rate = tointeger(Select(tParams, "RATE")) or DEFAULT_HOLD_RATE + persist:set(P_HOLD_RATE_DOWN, rate) + SendToProxy(PROXY_BINDING, "HOLD_RATE_DOWN", tostring(rate), "NOTIFY") +end + +--------------------------------------------------------------------------- +-- RFP: button colors +--------------------------------------------------------------------------- + +function RFP.REQUEST_BUTTON_COLORS(idBinding, strCommand, tParams, args) + log:trace("RFP.REQUEST_BUTTON_COLORS(%s, %s)", idBinding, strCommand) + if idBinding ~= PROXY_BINDING then + return + end + for _, buttonId in ipairs({ 0, 1, 2 }) do + local onColor, offColor = getButtonColors(buttonId) + SendToProxy(PROXY_BINDING, "BUTTON_COLORS", { + BUTTON_ID = buttonId, + ON_COLOR = onColor, + OFF_COLOR = offColor, + }, "NOTIFY") + end + -- MATCH_LED_STATE per button binding, with bottom inverted (its LED lights + -- when the light is off so the keypad shows the toggle state correctly). + local isOn = currentBrightness > 0 + SendToProxy(ON_BINDING, "MATCH_LED_STATE", { STATE = isOn }, "NOTIFY", true) + SendToProxy(OFF_BINDING, "MATCH_LED_STATE", { STATE = not isOn }, "NOTIFY", true) + SendToProxy(TOGGLE_BINDING, "MATCH_LED_STATE", { STATE = isOn }, "NOTIFY", true) +end + +function RFP.SET_BUTTON_COLOR(idBinding, strCommand, tParams, args) + log:trace("RFP.SET_BUTTON_COLOR(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + local buttonId = tointeger(Select(tParams, "BUTTON_ID")) + local onColor = Select(tParams, "ON_COLOR") + local offColor = Select(tParams, "OFF_COLOR") + if buttonId == nil then + return + end + setButtonColors(buttonId, onColor, offColor) + if onColor then + SendToProxy(PROXY_BINDING, "BUTTON_INFO", { BUTTON_ID = buttonId, ON_COLOR = onColor }, "NOTIFY") + end + if offColor then + SendToProxy(PROXY_BINDING, "BUTTON_INFO", { BUTTON_ID = buttonId, OFF_COLOR = offColor }, "NOTIFY") + end +end + +--------------------------------------------------------------------------- +-- RFP: button actions (from proxy) +--------------------------------------------------------------------------- + +-- Restore brightness to the pre-press snapshot. Called when a RELEASE_CLICK +-- arrives after a brief hold-ramp has already stepped 1-2%. Cancels timers, +-- snaps device + state back to the snapshot, and returns the effective level +-- the click logic should use for direction decisions. If no snapshot exists +-- (e.g. CLICK without preceding PRESS via DO_CLICK), returns currentBrightness. +local function rewindToPrePress() + local snapshot = prePressBrightness + prePressBrightness = nil + cancelBrightnessRampTimers() + if not rampingBrightness or snapshot == nil then + rampingBrightness = false + return snapshot or currentBrightness + end + rampingBrightness = false + if currentBrightness ~= snapshot then + setDeviceBrightness(snapshot, 0) + currentBrightness = snapshot + end + return snapshot +end + +-- Shared button-action implementation. Used by RFP.BUTTON_ACTION (proxy -> +-- driver path, e.g. on-device buttons or programming) and by DO_CLICK / +-- DO_PUSH / DO_RELEASE (button-link path, e.g. a keypad button bound to one +-- of our BUTTON_LINK connections). Returns nothing. +local function handleButtonAction(buttonId, action) + if action == constants.ButtonActions.PRESS then + -- Button-down. Snapshot brightness for the click race, then start a hold + -- ramp at the persisted hold rate. If the proxy decides this was a click, + -- a RELEASE_CLICK will arrive ~110ms later and rewindToPrePress() will + -- undo any partial step before the click ramp runs. + prePressBrightness = currentBrightness + if not supportsDimming then + if buttonId == constants.ButtonIds.TOP then + lightOn() + elseif buttonId == constants.ButtonIds.BOTTOM then + lightOff() + elseif buttonId == constants.ButtonIds.TOGGLE then + lightToggle() + end + return + end + if buttonId == constants.ButtonIds.TOP then + rampToBrightness(getOnBrightness(), getHoldRateUp()) + elseif buttonId == constants.ButtonIds.BOTTOM then + rampToBrightness(0, getHoldRateDown()) + elseif buttonId == constants.ButtonIds.TOGGLE then + if currentBrightness > 0 then + rampToBrightness(0, getHoldRateDown()) + else + rampToBrightness(getOnBrightness(), getHoldRateUp()) + end + end + elseif action == constants.ButtonActions.RELEASE_HOLD then + prePressBrightness = nil + brightnessRampStopped() + elseif action == constants.ButtonActions.RELEASE_CLICK then + local effective = rewindToPrePress() + if buttonId == constants.ButtonIds.TOP then + if supportsDimming then + rampToBrightness(getOnBrightness(), getClickRateUp()) + else + lightOn() + end + elseif buttonId == constants.ButtonIds.BOTTOM then + if supportsDimming then + rampToBrightness(0, getClickRateDown()) + else + lightOff() + end + elseif buttonId == constants.ButtonIds.TOGGLE then + if supportsDimming then + if effective > 0 then + rampToBrightness(0, getClickRateDown()) + else + rampToBrightness(getOnBrightness(), getClickRateUp()) + end + else + if effective > 0 then + lightOff() + else + lightOn() + end + end + end + end +end + +function RFP.BUTTON_ACTION(idBinding, strCommand, tParams, args) + log:trace("RFP.BUTTON_ACTION(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= PROXY_BINDING then + return + end + + local buttonId = tointeger(Select(tParams, "BUTTON_ID")) + local action = tointeger(Select(tParams, "ACTION")) + + handleButtonAction(buttonId, action) + + -- Echo the button action AFTER the ramp setup. If we send this BEFORE the + -- LIGHT_BRIGHTNESS_CHANGING notify, the proxy treats it as a state-change + -- event and snaps the UI to the on/off target, then our CHANGING repositions + -- back to current and animates - producing a visible jump-and-rewind. + SendToProxy(PROXY_BINDING, "BUTTON_ACTION", { + BUTTON_ID = buttonId, + ACTION = action, + }, "NOTIFY") +end + +--------------------------------------------------------------------------- +-- RFP: button link bindings (DO_CLICK, DO_PUSH, DO_RELEASE) +--------------------------------------------------------------------------- + +local function buttonIdFromBinding(idBinding) + if idBinding == ON_BINDING then + return constants.ButtonIds.TOP + elseif idBinding == OFF_BINDING then + return constants.ButtonIds.BOTTOM + elseif idBinding == TOGGLE_BINDING then + return constants.ButtonIds.TOGGLE + end + return nil +end + +-- Button-link bindings forward to handleButtonAction directly. Unlike the +-- proxy-initiated BUTTON_ACTION path, we don't send a BUTTON_ACTION echo +-- back to the proxy here: the proxy is the one that sent us DO_*, so it +-- already knows the button fired. Echoing would make the proxy snap the UI +-- to the on/off target before our LIGHT_BRIGHTNESS_CHANGING animates. +function RFP.DO_CLICK(idBinding, strCommand, tParams, args) + log:trace("RFP.DO_CLICK(%s, %s)", idBinding, strCommand) + local buttonId = buttonIdFromBinding(idBinding) + if buttonId == nil then + return + end + handleButtonAction(buttonId, constants.ButtonActions.RELEASE_CLICK) +end + +function RFP.DO_PUSH(idBinding, strCommand, tParams, args) + log:trace("RFP.DO_PUSH(%s, %s)", idBinding, strCommand) + local buttonId = buttonIdFromBinding(idBinding) + if buttonId == nil then + return + end + handleButtonAction(buttonId, constants.ButtonActions.PRESS) +end + +function RFP.DO_RELEASE(idBinding, strCommand, tParams, args) + log:trace("RFP.DO_RELEASE(%s, %s)", idBinding, strCommand) + local buttonId = buttonIdFromBinding(idBinding) + if buttonId == nil then + return + end + handleButtonAction(buttonId, constants.ButtonActions.RELEASE_HOLD) +end + +--------------------------------------------------------------------------- +-- RFP: the device state updates +--------------------------------------------------------------------------- + +function RFP.UPDATE_DISCONNECT(idBinding, strCommand, tParams, args) + log:trace("RFP.UPDATE_DISCONNECT(%s, %s)", idBinding, strCommand) + if idBinding ~= DEVICE_BINDING then + return + end + cancelBrightnessRampTimers() + cancelColorRampTimers() + rampingBrightness = false + rampingColor = false + brightnessRamp = nil + colorRamp = nil + stopAllScenes() + ENTITY = nil + STATE = nil + dynamicCapsSent = false + supportsDimming = false + supportsColor = false + supportsCCT = false + supportedColorModes = {} + currentBrightness = 0 + ledState = false + prePressBrightness = nil + fadeOverride = false + mergedColorUntil = 0 + currentBrightnessPresetId = nil + currentColorPresetId = nil + UpdateProperty("Driver Status", "Disconnected") + SendToProxy(PROXY_BINDING, "ONLINE_CHANGED", { STATE = false }, "NOTIFY") + notifyBrightnessChanged(0) +end + +function RFP.UPDATE_STATE(idBinding, strCommand, tParams, args) + log:trace("RFP.UPDATE_STATE(%s, %s, %s)", idBinding, strCommand, tParams) + if idBinding ~= DEVICE_BINDING then + log:error("RFP.UPDATE_STATE called with idBinding %s, expected %s", idBinding, DEVICE_BINDING) + return + end + + local entity = DeserializeSafe(Select(tParams, "entity")) + local state = DeserializeSafe(Select(tParams, "state")) + if IsEmpty(entity) or IsEmpty(state) then + log:error("RFP.UPDATE_STATE called with invalid parameters: %s", tParams) + return + end + + log:trace("Entity: %s", entity) + log:trace("State: %s", state) + + local wasConnected = STATE ~= nil + local isFirstUpdate = ENTITY == nil + ENTITY = entity + STATE = state + + -- Connection state must be sent BEFORE dynamic capabilities + if not wasConnected then + UpdateProperty("Driver Status", "Connected") + SendToProxy(PROXY_BINDING, "ONLINE_CHANGED", { STATE = true }, "NOTIFY") + end + + -- Send dynamic capabilities after ONLINE_CHANGED + if isFirstUpdate then + updateDynamicCapabilities(entity) + end + + -- Map device brightness (0.0-1.0) to C4 (0-100) + local newBrightness + local isOn = Select(state, "state") or false + if not isOn then + newBrightness = 0 + elseif supportsDimming then + local brightness = tonumber(Select(state, "brightness")) or 1.0 + newBrightness = math.floor(brightness * 100 + 0.5) + newBrightness = math.max(0, math.min(100, newBrightness)) + if newBrightness == 0 and isOn then + newBrightness = 1 + end + else + newBrightness = 100 + end + + -- During a ramp, the device's echo confirms the target value (not the + -- interpolated physical value), so we ignore it - rampingBrightness will + -- be cleared in brightnessRampFinished or brightnessRampStopped, both of + -- which set currentBrightness to the appropriate value before the snap + -- cmd's echo can arrive. Outside a ramp, the echo's target equals what + -- we last set, so processing it is a no-op (newBrightness already + -- matches currentBrightness). + if rampingBrightness then + log:trace("UPDATE_STATE brightness=%s ignored (ramping)", newBrightness) + elseif isFirstUpdate or newBrightness ~= currentBrightness then + -- Spec note: LIGHT_BRIGHTNESS_CHANGED should always be sent when the + -- driver starts and/or when the hardware comes online so the proxy is + -- seeded with the actual brightness, even if it matches our default. + notifyBrightnessChanged(newBrightness) + end + + if isOn and (supportsColor or supportsCCT) and not rampingColor then + local activeMode = tointeger(Select(state, "color_mode")) + local newX, newY, newColorMode + if activeMode and COLOR_MODES_SUPPORTING_CCT[activeMode] and Select(state, "color_temperature") then + local mireds = tonumber(Select(state, "color_temperature")) + if mireds and mireds > 0 then + local k = miredsToKelvin(mireds) + newX, newY = C4:ColorCCTtoXY(k) + newColorMode = LIGHT_COLOR_MODE_CCT + end + elseif activeMode and COLOR_MODES_SUPPORTING_RGB[activeMode] then + local r = tonumber(Select(state, "red")) or 0 + local g = tonumber(Select(state, "green")) or 0 + local b = tonumber(Select(state, "blue")) or 0 + if r > 0 or g > 0 or b > 0 then + local h, s = rgbToHSV(r, g, b) + newX, newY = C4:ColorHSVtoXY(h, s, 100) + newColorMode = LIGHT_COLOR_MODE_FULL + end + end + -- Threshold matches xy round-trip drift through RGB / HSV (typically + -- 1-2e-3 in either coordinate). Tighter than this fires spurious notifies + -- and clears the active preset id when the bulb just echoes our own cmd + -- back. Looser than ~1e-2 starts missing visible changes. + local COLOR_ECHO_TOLERANCE = 5e-3 + if + newX + and newY + and newColorMode + and ( + isFirstUpdate + or math.abs(newX - currentColorX) > COLOR_ECHO_TOLERANCE + or math.abs(newY - currentColorY) > COLOR_ECHO_TOLERANCE + or newColorMode ~= currentColorMode + ) + then + -- Hardware-driven color change (out-of-band update): no preset is + -- driving this, so don't echo a stale preset id. + currentColorPresetId = nil + notifyColorChanged(newX, newY, newColorMode) + end + end +end + +--------------------------------------------------------------------------- +-- Binding change +--------------------------------------------------------------------------- + +OBC[DEVICE_BINDING] = function() + ENTITY = nil + STATE = nil + dynamicCapsSent = false + supportsDimming = false + supportsColor = false + supportsCCT = false + supportedColorModes = {} + currentBrightness = 0 + ledState = false + rampingBrightness = false + rampingColor = false + brightnessRamp = nil + colorRamp = nil + prePressBrightness = nil + fadeOverride = false + mergedColorUntil = 0 + currentBrightnessPresetId = nil + currentColorPresetId = nil + currentColorX = DEFAULT_COLOR_X + currentColorY = DEFAULT_COLOR_Y + currentColorMode = LIGHT_COLOR_MODE_CCT + cancelBrightnessRampTimers() + cancelColorRampTimers() + stopAllScenes() +end diff --git a/drivers/zigbee3_light/driver.xml b/drivers/zigbee3_light/driver.xml new file mode 100644 index 0000000..3d8919a --- /dev/null +++ b/drivers/zigbee3_light/driver.xml @@ -0,0 +1,233 @@ + + Zigbee 3 Light + + Finite Labs + Zigbee 3 Light + Derek Miller + lua_gen + DriverWorks + Copyright 2026 Finite Labs, LLC. All rights reserved. + 08/25/2026 07:54:20 AM + + 3.3.0 + + Lighting + + + + +