Koenkk / Koenkk/zigbee2mqtt

[HORTI-RB / Philips] Generated support works partially, dimming works on endpoint 64, proprietary Signify clusters discovered

Open
#33,135 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

problem
Dominant language
TypeScript
Stars
15.7k
Forks
2k
Avg merge
18h 55m
Merged PRs (30d)
35

Description

What happened?

I paired a Philips / Signify horticulture grow light that identifies itself as:

Model: HORTI-RB
Vendor: Philips
Manufacturer: Philips Lighting BV

Zigbee2MQTT generated an automatic definition successfully and the device joins/interviews without problems.

The generated support exposes:

  • Light
  • Brightness
  • Power
  • Energy
  • Illuminance
  • Occupancy

However, several exposed functions either don't work correctly or appear to be mapped incorrectly.

Observations:

  • ON/OFF works.
  • Device interview completes successfully.
  • Generated support is created automatically.
  • Device is detected as router.
  • Color control commands are exposed but appear to have no visible effect.
  • Reading standard Color Control attributes returns UNSUPPORTED_ATTRIBUTE.

Examples:

  • currentHue -> UNSUPPORTED_ATTRIBUTE
  • currentSaturation -> UNSUPPORTED_ATTRIBUTE
  • colorMode -> UNSUPPORTED_ATTRIBUTE
  • enhancedColorMode -> UNSUPPORTED_ATTRIBUTE

Commands such as:

  • moveToHue
  • moveToHueAndSaturation
  • moveToColor
  • moveToColorTemp

are accepted and sent successfully but produce no obvious visible result.

What did you expect to happen?

I expected the generated definition to expose the device correctly.

This is a Philips / Signify horticulture fixture used together with the GrowWise Control System, which supports independently controllable color channels such as:

  • Red
  • Blue
  • Green
  • Far Red

The light appears to expose more functionality than Zigbee2MQTT currently understands.

Important findings
The generated definition appears to map brightness incorrectly.

The actual dimming endpoint is:

Endpoint: 64
Cluster: genLevelCtrl
Command: moveToLevel

Tested values:

level = 1
-> Light dims to minimum output

level = 254
-> Light reaches maximum output

This works reliably.

The generated brightness implementation does not appear to use this endpoint correctly.

Endpoint discovery
Endpoint 64

Input clusters:

  • genBasic
  • genIdentify
  • genGroups
  • genScenes
  • genOnOff
  • genLevelCtrl
  • lightingBallastCfg
  • touchlink
  • 64771
  • 64772
  • 64773
  • 64774
  • 64775
  • 64780
  • 64783
  • 64784

This endpoint appears to be the actual lighting/ballast endpoint.

Endpoint 144

Input clusters:

  • genIdentify
  • genOta
  • greenPower
  • 1793

Output clusters:

  • lightingColorCtrl
  • 64769
  • 64771
  • 64772
  • 64773
  • 64774
  • 64775
  • 64778
  • 64783

This endpoint appears to expose advanced control functionality.

Proprietary clusters
The following proprietary Signify clusters were discovered:

64769
64771
64772
64773
64774
64775
64778
64780
64783
64784

Zigbee2MQTT Dev Console cannot decode them.

No attributes or commands are exposed for these clusters, but they appear repeatedly on the HORTI-RB endpoints.

Given that this is a GrowWise-compatible horticulture fixture, these clusters may contain spectrum control functionality.

Firmware
Manufacturer: Philips Lighting BV
Model: HORTI-RB

Firmware ID: 1.4.7
Firmware version: 66567

Additional context
This appears to be a Philips / Signify GrowWise horticulture fixture.

According to Signify documentation, GrowWise supports independent control of multiple light spectra, including Red, Blue, Green and Far Red channels.

There is a strong indication that additional functionality exists behind the proprietary Signify clusters listed above.

The most important confirmed finding from testing is that dimming works through:

Endpoint 64
genLevelCtrl.moveToLevel

while endpoint 144 appears to expose an advanced control interface.

How to reproduce it (minimal and precise)
  1. Pair HORTI-RB with Zigbee2MQTT.
  2. Allow generated support to be created.
  3. Open Dev Console.
  4. Test Endpoint 144 / lightingColorCtrl commands:
    • moveToHue
    • moveToHueAndSaturation
    • moveToColor
    • moveToColorTemp
  5. Attempt to read:
    • currentHue
    • currentSaturation
    • colorMode
    • enhancedColorMode

Result:

  • Reads return UNSUPPORTED_ATTRIBUTE.
  • Commands are accepted but no obvious visible effect can be observed.
Zigbee2MQTT version

2.14.1 (unknown)

Adapter firmware version

{"build":0,"ezsp":13,"major":7,"minor":4,"patch":5,"revision":"7.4.5 [GA]","special":0,"type":170}

Adapter

EmberZNet

Setup

os: #1 SMP PREEMPT Thu Jul 30 12:00:40 UTC 2026 - 6.18.34-haos-raspi - arm64
node: v24.18.1
ha: true

Device database.db entry

No response

Debug log

No response

Notes
Device

definition: HORTI-RB - Philips (v0.0.0)
software_build_id: 1.4.7
date_code: 20260423
endpoints:

{"64":{"bindings":[],"clusters":{"input":["genBasic","genIdentify","genGroups","genScenes","genOnOff","genLevelCtrl","genCommissioning","lightingBallastCfg","772","seMetering","haDiagnostic","touchlink","64771","64772","64773","64774","64775","64780","64783","64784"],"output":["genOta","msIlluminanceMeasurement","msOccupancySensing","1793","haDiagnostic","64771","64772","64784"]},"configured_reportings":[],"name":"64","scenes":[]},"65":{"bindings":[],"clusters":{"input":["genBasic","genIdentify","genGroups","msIlluminanceMeasurement"],"output":[]},"configured_reportings":[],"name":"65","scenes":[]},"66":{"bindings":[],"clusters":{"input":["genBasic","genIdentify","genGroups","msOccupancySensing"],"output":[]},"configured_reportings":[],"name":"66","scenes":[]},"80":{"bindings":[],"clusters":{"input":["genBasic","genIdentify","genGroups","genTime","64769"],"output":[]},"configured_reportings":[],"name":"80","scenes":[]},"144":{"bindings":[],"clusters":{"input":["genIdentify","genOta","greenPower","1793"],"output":["genBasic","genIdentify","genGroups","genScenes","genOnOff","genLevelCtrl","genTime","genCommissioning","greenPower","lightingColorCtrl","lightingBallastCfg","msIlluminanceMeasurement","msOccupancySensing","seMetering","64769","64771","64772","64773","64774","64775","64778","64783"]},"configured_reportings":[],"name":"144","scenes":[]},"242":{"bindings":[],"clusters":{"input":["genGroups","greenPower"],"output":["greenPower"]},"configured_reportings":[],"scenes":[]}}
Health

time: Tue Sep 15 2026 10:34:59 GMT+0200 (Centraleuropæisk sommertid)
os.load_average: 0.15, 0.16, 0.17
os.memory_percent: 28.3393
process.memory_percent: 1.5257
process.uptime_sec: 12005

{"leave_count":0,"messages":75,"messages_per_sec":0.0064,"network_address_changes":0}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the generated device support and the Dev Console results for HORTI-RB, comparing endpoint 64 with endpoint 144. Verify the confirmed genLevelCtrl.moveToLevel behavior on endpoint 64 and investigate whether the proprietary Signify clusters expose additional controls; done means the device mapping and supported controls match behavior that can be reproduced.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
embedded-iot
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.