private@homelab: ~/latest
local-first guides · privacy-aware · no noisy tracking
private@homelab:~$ cat guides/article.md
· ·
7–10 minutes
read

Xiaomi GZCGQ01LM Light Sensor in Home Assistant (Z2M)

Pair the Xiaomi GZCGQ01LM light sensor straight into Zigbee2MQTT, no Mi Home needed. Entity set, calibration options, and two illuminance bugs to know first.

Xiaomi GZCGQ01LM Light Sensor in Home Assistant (Zigbee2MQTT)

The Xiaomi Mijia Light Intensity Sensor, model GZCGQ01LM, is one of the cheapest ways to get a real lux reading into Home Assistant without touching the Mi Home app. It’s a small round puck, it runs on Zigbee, and it pairs straight to a Zigbee2MQTT coordinator with nothing phoning home to Xiaomi’s servers. I’ve had one running on a windowsill for a while now, mostly feeding a “don’t turn the lamp on if it’s already bright enough” automation, and it’s been mostly boring in the good way. Mostly. This walkthrough uses Zigbee2MQTT throughout; if you’re still choosing between it and ZHA, that comparison lives here.

What the GZCGQ01LM Actually Is (and Isn’t)

First, the disambiguation, because this trips people up during the buying stage. The GZCGQ01LM is a Zigbee light sensor only. It measures ambient illuminance in lux and reports battery and voltage. That’s it. No motion, no presence, no night light function. If you’re after motion or occupancy instead, the Xiaomi Mi Motion Sensor (RTCGQ01LM) is the round-puck sibling to look at — it’s a common mix-up because the model codes are so close.

It also gets confused constantly with the Mi Motion-Activated Night Light 2 (MJYD02YL-A), which is a Bluetooth device, has a built-in LED, and integrates with Home Assistant through the Xiaomi BLE integration rather than Zigbee2MQTT. If you’ve searched “xiaomi light sensor home assistant” and landed on results for a night light with a built-in glow ring, you’re looking at the wrong product for a pure lux-only sensor. Different radio, different integration path, different setup guide entirely. Worth knowing before you buy the wrong SKU off a marketplace listing that uses both names interchangeably.

Pairing It to Zigbee2MQTT

Pairing is a long-press: hold the reset button on the back for roughly 5 seconds until the LED blinks blue, then let Zigbee2MQTT’s permit-join window pick it up. If that doesn’t trigger the join for whatever reason, the documented fallback is a single, brief press instead — no long hold. I’ve seen both methods work on different units, so if the 5-second hold doesn’t do anything after a couple of tries, don’t keep repeating it. Switch to the short press before you assume the sensor is dead. Like most Xiaomi sleeping end devices, it can drop back to sleep mid-interview, so a light tap on the button every second or so during pairing helps keep it awake long enough to finish joining.

Once paired, expect the battery percentage entity to sit unpopulated for as long as 24 hours. That’s expected behavior on this device, not a fault or a failed pairing — the sensor doesn’t push a battery report immediately, and there isn’t a way to force it. If your automations depend on the battery entity existing, build in that grace period.

One more thing worth flagging: a major coordinator firmware flash can drop this sensor from the mesh, the way a lot of Xiaomi sleeping end devices don’t survive a coordinator reset gracefully. If illuminance suddenly stops updating right after you’ve flashed new coordinator firmware, re-pairing is the first thing to try, not a factory reset or a support ticket.

What You Get in Home Assistant: The Entity Set

Zigbee2MQTT exposes three properties from this device (see the Zigbee2MQTT device page for the authoritative list):

  • Illuminance (lux) — the main reason you bought it
  • Battery (%) — read-only, delayed on first pairing as noted above
  • Voltage (mV) — read-only

The voltage entity is easy to ignore, but it’s a decent sanity check when the percentage figure looks wrong or gets stuck. A fresh CR2450 reading around 3000mV is healthy; if percentage says 40% but voltage has been flat for weeks, trust the voltage curve over the percentage estimate. None of these entities have a corresponding “set” command — this is a sensor, not a controllable device, so don’t go looking for a service call to configure it from Home Assistant directly. Configuration happens on the Zigbee2MQTT side, covered below.

The Illuminance Bug You’ll Probably Run Into

This is the part that doesn’t show up on the spec sheet, and it’s the reason a chunk of the search traffic for this device is troubleshooting rather than setup.

Since Zigbee2MQTT 2.1.0 (released 3 February 2025), users have reported illuminance flickering between 0 and 1 lux at night — the value bounces rapidly instead of settling (issue #26241). If you’ve built a threshold automation (“turn on the lamp when illuminance drops below 5”), this is exactly the kind of noise that fires the automation repeatedly instead of once. The maintainers closed the issue as “not planned,” so there’s no upstream fix on the roadmap — treat the for: workaround below as the long-term answer, not a stopgap while you wait for a patch.

There’s also a separate failure mode reported after the Zigbee2MQTT 2.0 update (issue #25609): some units stopped publishing to MQTT entirely, sometimes with binding errors in the log. The workaround reported by affected users was re-pairing the device. If your sensor goes fully silent — no MQTT messages at all, not just flaky values — try a re-pair before assuming a hardware fault. It’s fixable without a factory reset in most reported cases.

What I didn’t expect the first time I hit the flicker bug: I’d built a simple “turn on porch light below 3 lux” automation, and it started clicking the light on and off every ten minutes after dusk. I assumed my own automation had a race condition. It took cross-referencing the GitHub issue tracker to realize the sensor itself was the noisy input, not my YAML.

Calibration Options in Zigbee2MQTT

Zigbee2MQTT exposes two device-specific configuration options for this sensor:

  1. An illuminance calibration value, expressed as a percentage offset, letting you correct for a sensor that consistently reads high or low against a reference light meter
  2. A toggle to expose raw illuminance — the uncalibrated value straight off the sensor, alongside the calibrated one

If you’re chasing the flicker bug, enabling the raw exposure and watching it next to the calibrated value is a reasonable first diagnostic step — it tells you whether the noise is already present in the raw sensor data or only shows up after Zigbee2MQTT applies its calibration offset. The public reports don’t settle that either way, so it’s worth checking on your own unit rather than assuming.

A Lux-Threshold Automation That Doesn’t Fight the Flicker Bug

Given the flicker issue above, a naive threshold trigger is asking for trouble at night. Adding a for: duration to the trigger — requiring the low-lux state to hold for a few minutes before firing — filters out the rapid 0/1 bouncing without meaningfully delaying the automation in normal use. Something like this (adjust entity IDs to match your own setup — these are representative, not literal):

automation:
  - alias: "Porch light on low ambient light"
    trigger:
      - platform: numeric_state
        entity_id: sensor.porch_light_sensor_illuminance
        below: 5
        for:
          minutes: 3
    action:
      - service: light.turn_on
        target:
          entity_id: light.porch

The three-minute hold is a starting point, not a documented recommendation — tune it against how the flicker actually behaves on your own unit, since severity seems to vary between reports.

GZCGQ01LM vs. Aqara Light Sensor T1 vs. the Night Light You Don’t Want

Three different products keep circling each other in search results and I’ll try to untangle them plainly. The GZCGQ01LM is Xiaomi’s own light-only Zigbee sensor, cheap, no hub required for Zigbee2MQTT use, and the subject of this whole article. The Aqara Light Sensor T1 (model GZCGQ11LM) is Aqara’s competing take on the same category — another single-purpose Zigbee illuminance sensor that pairs to Zigbee2MQTT without a hub. The practical differences between the two come down to reporting behavior and firmware quirks rather than the core feature set, and the T1 has its own separate write-up if you’re deciding between them. And the Mi Motion-Activated Night Light 2 is a different device family entirely, Bluetooth-based, with a built-in light, and not a like-for-like substitute for either.

Honestly, I think the fact that Xiaomi ships a percentage-based calibration option at all, on a sensor this cheap, is more thoughtful than most budget IoT vendors bother with — it’s the kind of detail that suggests the firmware team cared about accuracy, even if the recent flicker regression undercuts that a bit right now.

FAQ

Does the Xiaomi light sensor need a Mi Home hub?
No, not for Zigbee2MQTT. It pairs directly to your Zigbee coordinator through the standard join process described above. Mi Home and its cloud have no part in this setup path.

Why is my GZCGQ01LM illuminance reading stuck at 0 or 1 lux?
Most likely the Zigbee2MQTT 2.1.0-era flicker bug described above, especially if it’s happening after dark. It’s a known regression (issue #26241, closed “not planned”), so the fix is the for:-duration workaround rather than waiting on an update.

What’s the difference between GZCGQ01LM and the Aqara Light Sensor T1?
Both are budget, single-purpose Zigbee illuminance sensors that run locally through Zigbee2MQTT without a hub — the GZCGQ01LM is Xiaomi’s, the T1 (GZCGQ11LM) is Aqara’s. They differ mainly in reporting behavior and firmware quirks; the Aqara T1 guide covers its specifics.

Can I use this sensor to trigger lights based on ambient brightness without the cloud?
Yes — that’s the whole point of running it through Zigbee2MQTT rather than Mi Home. The automation example above is a reasonable starting template.

Why does the battery percentage not update for 24 hours after pairing?
That’s documented, expected behavior on this device, not a fault. Give it a full day before troubleshooting.

Because the maintainers closed the 2.1.0 flicker regression as “not planned,” the for:-duration workaround is the realistic long-term answer rather than something you’ll be able to delete after the next update — worth keeping in mind before you build anything more elaborate on top of this sensor’s illuminance value.

local-firstHome Assistantno-cloud