What it is
Zigbee Home Automation (ZHA) is Home Assistant's built-in integration for a Zigbee network. It uses a compatible coordinator to pair supported devices and expose their controls, sensor readings and events directly in Home Assistant.
My Setup
How ZHA Connects My Irrigation, Keypad and Sensors
One of my main ZHA builds brings a separate set of sprinkler valves under Rachio control. Those valves used to run from a standard non-smart controller on the opposite side of my home. I now use a Tuya TS0004 Zigbee relay and Home Assistant automations to make them follow selected Rachio zones.
I also use ZHA for a CentraLite keypad connected to Alarmo, switched devices and electrical measurements. Occupancy and contact sensors provide information in my dashboards.
Those devices do not all serve the same purpose. Some provide an input, some carry out a requested action, and others report a measurement. Home Assistant combines those functions with the rest of the system, while ZHA handles the Zigbee connection.
My setup also includes a local custom quirk for the keypad. It adapts the device's reports into useful Home Assistant entities, with specific limits on what the battery, interaction and tamper indications mean.
The coordinator and Home Assistant
Home Assistant runs on my Raspberry Pi. My ZHA configuration uses a USB-connected Zigbee coordinator with an Ember-compatible radio connection. ZHA works with the coordinator through the Zigbee software stack and exposes the supported controls, events and measurements in Home Assistant.
Zigbee device ↔ coordinator ↔ ZHA ↔ Home Assistant entity or automation
This path does not require an MQTT broker or a separate Z-Wave JS server. Those are other connection paths in my build, described in the MQTT and Z-Wave JS articles.
My Hue bridge has its own connection to Home Assistant. Zigbee devices joined to that bridge are not automatically part of the ZHA network. A device joins one Zigbee network at a time; Home Assistant can still combine devices from those separate networks in an automation.
What I connect through ZHA
These roles come from my configured devices, dashboard references and automation definitions. The table separates what a connection reports from what I use that information to do.
Scroll the table horizontally to compare all four columns.
| Connection | Information | How I use it | Limit or dependency |
|---|---|---|---|
| CentraLite 3400 keypad | Alarm commands, panel state and supporting sensors. | Physical alarm interaction connected to Alarmo through automations. | My local custom quirk adapts device behavior; keypad state and Alarmo state need coordination. |
| Tuya TS0004 relay | Controllable outputs, including outputs exposed as light entities. | Bring sprinkler valves formerly on a separate non-smart controller under Rachio schedules through Home Assistant. | The cloud update, Home Assistant automation and Zigbee link must work; output state does not measure water flow. |
| Metering plugs and switched outputs | Switch state and supported electrical measurements. | Dashboard controls and power readings in equipment-monitoring notifications. | The reported measurements and their freshness depend on the device. |
| Occupancy and contact sensors | Occupancy, opening and supporting sensor reports. | Sensor information in Home Assistant dashboards. | A registered sensor or dashboard reference does not establish an automation use. |
| GLEDOPTO GL-C-008 | A Zigbee device used as a repeater in my build. | Supports the Zigbee network rather than serving primarily as a lighting feature here. | Its role does not establish which route any particular device is currently using. |
My ZHA dashboards include alarm controls, switched outputs, occupancy and opening states, and measurements such as power, energy, battery and temperature. The functions available vary by device; pairing successfully does not mean every manufacturer-specific feature is exposed.
The CentraLite keypad and Alarmo
Commands in, alarm state back
My keypad automation receives ZHA events and maps the relevant commands to Alarmo arm or disarm actions. A separate automation responds to Alarmo state changes and updates the keypad's ZHA alarm-control entity for the corresponding mode.
Keypad command → ZHA event → Home Assistant automation → Alarmo
Alarmo state change → Home Assistant automation → keypad panel state
These are two directions of communication. Receiving a keypad request is different from Alarmo accepting it, and updating a keypad entity is different from verifying the physical keypad's response. When checking the workflow, both directions matter.
What my custom quirk changes
My local CentraLite 3400 quirk adapts several device-specific reports. It derives a battery percentage from reported voltage, adds an indication of keypad interaction and creates a timed tamper indication from the device's zone notifications.
- Battery is an estimate. The quirk converts voltage into a percentage rather than receiving a native percentage from this keypad.
- Interaction is not room occupancy. The quirk exposes keypad interaction as an occupancy entity and clears it after a timeout. It does not detect someone approaching the keypad or establish that a room is occupied.
- Tamper is a timed indication. The local implementation interprets the relevant notification as a tamper signal and clears it on a timer. That clearance is not confirmation that the cover has been physically restored.
The quirk includes a startup grace period to suppress enrollment-related notifications. Its behavior is specific to the device handling implemented here; it is not a general claim about every CentraLite firmware version.
The ZHA Device Handlers project (opens in a new tab) explains the quirk mechanism and upstream device support. That link points to the upstream project, not a published repository for my local keypad changes.
Bringing a separate sprinkler system under Rachio control
Why I built it
The sprinkler valves on the opposite side of my home were previously connected to their own non-smart controller. I wanted those existing valves to follow Rachio's schedules instead of keeping a separate watering program on that controller. The Zigbee relay provides the valve-control outputs, while Home Assistant connects them to Rachio.
For these valves, the selected Rachio zones have no valve wired directly to the Rachio controller. Their reported on/off states become the inputs for my relay automations. This is how the separate valve bank participates in the Rachio-controlled system.
From a Rachio zone to a sprinkler valve
Rachio zone state → Rachio cloud → Home Assistant automation → ZHA and Zigbee coordinator → Tuya TS0004 relay → sprinkler valve
When a selected Rachio zone reports on, my automation requests that its matching relay output turn on. When the zone reports off, it requests that output turn off. Rachio supplies the scheduling side, Home Assistant maps the zone to the output, and ZHA carries the local Zigbee command. There is no direct Rachio-to-Zigbee connection.
The relay outputs used here appear as light entities in Home Assistant, so the automations use light actions to operate them. They control irrigation valves in this build; the software entity type does not mean they are lighting circuits.
State checks, reconciliation and shutoff
The mirror automation includes a follow-up state check and notification path. A separate routine compares known Rachio and relay states at Home Assistant startup and periodically, requesting a matching output state if they disagree. This gives the system another opportunity to reconcile a mismatch after the original zone transition.
An overrun shutoff automation also requests that a relay output turn off if it stays on too long. These controls run in Home Assistant and depend on being able to reach the relay. They are not an independent hardware cutoff, and the Rachio controller's own run limit reaches these valves only through the automation path.
The Zigbee connection is local, but the full workflow still depends on Rachio cloud updates. A reported relay state is also different from a valve physically moving or water reaching the sprinklers. My Rachio article covers the controller side and the separate pump-monitoring information I use alongside it.
Metering and equipment monitoring
Other configured paths use output-state changes for notifications, or combine relay and Rachio state with equipment information for counters. Those are software observations, not measurements of water volume or proof that a watering cycle completed.
ZHA power readings are included in a configured notification alongside power information from other equipment integrations. My metering devices also expose supported electrical measurements such as energy, current and voltage for inspection in Home Assistant.
Power and energy answer different questions: power describes a reported rate of consumption, while energy represents accumulated consumption. Having those entities available does not establish that every reading is used in the Energy dashboard, or that every measurement has been calibrated.
My configuration also uses a ZHA switch-state input in an automation with a helper condition and a switching action. This is the same wider pattern: Home Assistant evaluates the logic, and each integration handles its own devices.
Reports, radio coverage and device support
Local Zigbee is one part of the workflow
ZHA provides a local connection to the joined devices. A wider routine still depends on Home Assistant and any other integration it calls. A working Zigbee relay connection does not establish that the Rachio side is available, just as a received keypad command does not establish that Alarmo changed state.
Network coverage and quirks solve different problems
I use the GLEDOPTO device as a Zigbee repeater. Router devices can help carry traffic through the mesh, but the existence of a router does not prove that a particular device is using it or has a healthy route. Coordinator placement, interference and powered routers remain part of connection troubleshooting.
A quirk adapts how a device's messages are interpreted. It cannot repair an unreachable radio device. Conversely, improving radio coverage will not correct a manufacturer-specific report that needs different handling.
Fresh reports matter
A saved battery value, a displayed contact state or an available control can outlast the last useful device report. Check for a fresh update when diagnosing a missing action. Battery-operated devices may also need waking for pairing or configuration work, following their own instructions.
Before changing coordinators, preserve the network backup and follow the supported migration process. Keep custom quirk code with the configuration needed to restore it. Network recovery and the continued behavior of a local customization are separate checks.
Checking the full path from device to result
The useful checks depend on where the information stops:
- Check ZHA and the coordinator. Confirm the integration can communicate with its radio before investigating an individual automation.
- Check a fresh device report. Look for the relevant keypad event, sensor update or output-state report. Avoid treating an old value as proof of a new interaction.
- Check the interpretation. For the keypad, distinguish device reports from the quirk's estimates and timed indications. For the relay, check the entity actually used by the automation.
- Check the automation trace. Inspect the trigger, conditions and selected action, then the state reported by Alarmo, Rachio or another participating integration.
- Verify the intended result. A command request, a reported output state and a physical outcome are different observations. For the keypad workflow, check the return path as well.
The official ZHA documentation (opens in a new tab) covers pairing, interference, device support and coordinator migration. In my build, ZHA supplies the direct Zigbee connection; Home Assistant makes those controls and measurements useful alongside the rest of the home.
What it can do
Direct pairing
Join supported Zigbee devices to the network managed by ZHA.
Device entities
Expose supported lighting, switching and sensor functions.
Automation events
Use supported remote and device events in Home Assistant automations.
Device-specific handling
Quirks can translate non-standard behavior and expose manufacturer-specific functions.
Install and connect
Before you start
- A supported Zigbee coordinator accessible to Home Assistant.
- Devices ready to join that coordinator's Zigbee network.
Prepare the coordinator
Connect a supported radio and keep it away from interference sources where practical.
Add ZHA
Use Settings > Devices & services > Add integration > Zigbee Home Automation, or accept its discovery.
Pair a device
Open the integration's add-device flow and put the device into its manufacturer's pairing mode.
Check the exposed functions
Verify its controls and reports. For missing features, check the device-handlers project before assuming full compatibility.
Limits and caveats
- A coordinator cannot simultaneously run ZHA and another Zigbee stack.
- A device's Zigbee branding does not ensure every manufacturer-specific feature is supported.
- Range, interference and the available Zigbee routers affect the mesh.
- A custom quirk can address device behavior; it cannot fix radio coverage or guarantee future compatibility.
