Keeping the HejHome Z26 Connected to Zigbee2MQTT

A HejHome Z26 Zigbee bulb repeatedly left my Zigbee network after about 8–10 minutes. A device-specific Basic-cluster appVersion poll has so far prevented the self-leave behavior, although it remains a workaround under long-term observation.

The problem

I started this expecting a straightforward replacement of an existing Wi-Fi bulb, a Tapo L535E, with a Zigbee version. Pairing completed normally, and the bulb worked at first, but after roughly 10 minutes it became unresponsive again.

Assuming the original bulb was defective, I bought and installed another unit of the same model. The same thing happened with the replacement.

At first I suspected an ordinary Zigbee routing problem. I re-paired the bulb, changed the Zigbee2MQTT converter, and updated the coordinator firmware. None of this solved it. Eventually, while reviewing the Zigbee2MQTT debug log chronologically, I confirmed that this was not merely a device failing to respond: the bulb itself was issuing a leaveInd and leaving the network.

The bulb tested

The product is the HejHome Smart Color Bulb Z26. The unit tested was manufactured in April 2026, lot 26D15.

  • Base: E26
  • Power: 9 W
  • Brightness: 806 lm
  • Lighting: RGB and 2700–6500 K white
  • Package model: GKZ-LB431RGBCW-E26
  • Zigbee model: TS0505B
  • Manufacturer fingerprint: _TZ3210_cnicaghm
  • appVersion: 66; hardware version: 1; stack version: 0

Why the generic model name was not enough

TS0505B is a name shared by several Tuya-family RGB+CCT bulbs. Zigbee2MQTT therefore recognized this bulb as a generic TS0505B_1 device and exposed basic functions such as brightness, color temperature, and RGB control.

However, bulbs sharing the TS0505B name can still have different internal firmware and behavior depending on their manufacturer fingerprint. In this case, the relevant identifier was specifically _TZ3210_cnicaghm.

This was a network leave, not an ordinary offline event

I observed the same pattern with two Z26 bulbs: bulb A left the network 8 minutes 24 seconds after pairing, and bulb B left after 10 minutes 19 seconds.

An unresponsive Zigbee device does not always indicate the same failure. If a route is temporarily unavailable, the coordinator may retry or find another route and recover. Here, Zigbee2MQTT recorded an event showing that the device had left the network, and the device subsequently disappeared from the database.

Home Assistant continued to show the last on-state for a while. At first this made the bulb appear connected, but it was only retained state and did not indicate real connectivity.

Attempts that did not solve it

  • Factory reset and re-pairing: the bulb worked temporarily, then failed in the same way.
  • Enabling network joining: the Z26 rejoined by itself without intervention, then left again about 10 minutes later.
  • Replacing the bulb with a new Z26: the second bulb showed the same 8–10 minute pattern.
  • Using separate level and on/off commands instead of MoveToLevelWithOnOff: lighting commands worked, but the bulb still left after 10 minutes 19 seconds.
  • Updating a CC2652P2 coordinator from 2021 firmware to a 2024 version: the coordinator and the rest of the mesh were normal, but the Z26 issue remained.
  • MQTT QoS and Home Assistant entity settings did not appear to be the core cause, because the problem occurred below MQTT message delivery, at the Zigbee device/network layer.

The decisive clue

After more than a week of trying different approaches after work, I was close to giving up. Then Codex found a highly specific lead in a changelog buried on the manufacturer’s website. The GPT-5.6-Sol medium model running in OpenAI Codex found the small clue that led to the workaround. After struggling with this for more than a week, that was immensely satisfying.

The clue came from version 1.1.17 of the HejHome Homey app maintained by GOQUAL:

  • “Z26 color bulb: switch keep-alive from zclVersion/5min to appVersion/30s to fix the ~10-minute self-leave issue.”

What the changelog suggested

That single line matched the 8 minutes 24 seconds and 10 minutes 19 seconds observed directly with my two bulbs almost exactly.

It indicates that the Homey driver previously read zclVersion every five minutes, then changed to reading appVersion every 30 seconds in order to prevent the approximately 10-minute self-leave. In other words, the product had apparently already required a device-specific keep-alive in another ecosystem.

The Zigbee2MQTT workaround

I created a Zigbee2MQTT external converter that matches only the TS0505B / _TZ3210_cnicaghm fingerprint and periodically reads appVersion from the Basic cluster:

  • poll({ key: 'hejhome_z26_app_version_keepalive', defaultIntervalSeconds: 120, poll: async (device) => { await device.getEndpoint(1).read('genBasic', ['appVersion']); },})
  • The GOQUAL Homey driver uses a 30-second interval. Because the observed failure window was 8–10 minutes, I initially chose 120 seconds. My reasoning was that even if two polls failed, another opportunity would remain before the failure window, while unnecessary traffic would be reduced.
  • This interval was chosen empirically. I did not run a systematic comparison of 30-, 60-, 120-, and 180-second intervals. It should also not be applied blindly to TS0505B bulbs with other fingerprints.

Results so far

I initially tested with a 30-second interval. Responses with appVersion: 66 arrived repeatedly. One timeout occurred, but the next cycle recovered without human intervention.

I later removed a level-control override that I considered unnecessary and increased the polling interval to 120 seconds. After restart, six consecutive polls succeeded and the bulb passed the previous failure window. At the time of writing the draft, it had continued recording recent activity for about nine hours without leaving the network.

There was one lighting-command timeout during this period, but the command succeeded again after Zigbee retry and recovery. The appropriate conclusion for now is limited: 120-second appVersion polling suppressed the repeatedly observed 8–10 minute Z26 self-leave during the observation period. It has not eliminated all command latency, and whether this is a long-term solution still needs to be monitored.

What remains unknown

I still do not know why this happens. A likely hypothesis is that the Z26 firmware contains something like an inactivity timer or watchdog, and that a particular Basic-cluster transaction refreshes its state. Public information does not show whether any traffic would work, whether appVersion must specifically be read, or why 30 seconds was selected by the Homey driver.

The main lesson is not to rely on a generic model name alone. Different firmware may exist within the broad TS0505B category, so this case needs to be considered according to the exact _TZ3210_cnicaghm fingerprint.

Technical record and converter

The full reproduction environment, unsuccessful attempts, anonymized observation logs, and the complete external converter code are available on GitHub under “HejHome Z26 Zigbee2MQTT self-leave case report.”

This is not yet a confirmed final fix. It is a strong workaround that has been found and is now under longer-term observation. I will continue updating the GitHub record if anything changes. I hope it helps anyone, or an agent acting for them, who encounters a similar problem.