Project 7: The Zigbee Environment Sensor (XIAO ESP32C6)

Build a battery-friendly Zigbee sensor that joins a Zigbee network and reports temperature/humidity to Home Assistant.

Quick Reference

Attribute Value
Difficulty Advanced
Time Estimate 1-2 weeks
Main Programming Language C (ESP Zigbee SDK)
Alternative Programming Languages None recommended (Zigbee stack is C)
Coolness Level High
Business Potential Medium (smart home sensors)
Prerequisites Basic networking, low-power concepts, ESP-IDF build
Key Topics Zigbee roles, ZCL clusters, sleepy end devices

1. Learning Objectives

By completing this project, you will:

  1. Explain Zigbee roles (coordinator, router, end device).
  2. Configure a sleepy end device that conserves power.
  3. Implement ZCL clusters for temperature and humidity.
  4. Join a Zigbee network and report attributes on schedule.
  5. Debug join/rejoin issues and reporting failures.

2. All Theory Needed (Per-Concept Breakdown)

2.1 Concept 1: Zigbee Roles, Network Formation, and Mesh Routing

Fundamentals

Zigbee is a low-power mesh network built on 802.15.4. Devices take on roles: coordinator (forms the network), routers (extend the mesh), and end devices (usually battery powered). End devices do not route traffic; they communicate through a parent router. Understanding these roles is critical because the device behavior, power consumption, and network reliability all depend on the role. A sensor typically runs as a sleepy end device to maximize battery life.

Deep Dive into the Concept

Zigbee networks begin with a coordinator that selects a PAN ID and channel, then starts the network. Routers and end devices join by requesting association. Routers can accept child devices and relay messages, forming a mesh that extends coverage. End devices are optimized for low power: they do not stay awake to receive messages continuously. Instead, they poll their parent at intervals to check for pending messages. This polling mechanism is what enables years-long battery life.

Mesh routing in Zigbee uses a combination of tree-based addressing and route discovery. The coordinator assigns addresses, and routers can allocate address ranges to their children. For end devices, routing is not required; they simply send to their parent. However, the mesh is still important because the parent may forward data to the coordinator or to a gateway. The reliability of the network depends on router placement and link quality. If the parent router fails, the end device must rejoin and choose a new parent. This rejoin process can take time and affect data availability.

The Zigbee stack handles routing and network management, but you must understand the constraints. For instance, a sleepy end device cannot receive commands unless it polls. If the polling interval is long, commands such as “identify” or “configure reporting” may take longer to apply. This is acceptable for sensors but not for actuators like lights. Understanding these tradeoffs helps you choose the right role for each device type.

The ESP32-C6 supports 802.15.4 radio, enabling Zigbee stacks. It can operate as a router or end device. For a sensor, you will choose end device mode. That means you must configure the stack for low-power operation and ensure that the application does not keep the CPU awake unnecessarily. The mesh behavior also means you must trust the parent router and manage rejoin events properly.

How this fits on projects

You will configure the ESP32-C6 as a sleepy end device, join a Zigbee coordinator, and understand why it cannot receive messages instantly.

Definitions & Key Terms

  • Coordinator: Forms the Zigbee network and assigns addresses.
  • Router: Extends network coverage and routes messages.
  • End Device: Battery device that does not route traffic.
  • Parent: Router or coordinator that an end device is attached to.
  • PAN ID: Zigbee network identifier.

Mental Model Diagram (ASCII)

[Coordinator]
     |
  [Router]----[Router]
     |
 [End Device] (sleepy)

How It Works (Step-by-Step)

  1. Coordinator forms the network on a channel.
  2. End device scans and requests to join.
  3. Parent accepts and assigns address.
  4. End device sleeps and polls parent periodically.
  5. Parent forwards sensor reports to coordinator.

Minimal Concrete Example

[Zigbee] Joining PAN 0x1A2B on channel 15
[Zigbee] Joined, short address 0x1234

Common Misconceptions

  • “End devices can receive commands anytime.” They only receive on poll.
  • “Mesh is automatic and always reliable.” It depends on router placement.
  • “Any device can be coordinator.” Only one coordinator per network.

Check-Your-Understanding Questions

  1. Why does a sleepy end device poll its parent?
  2. What happens if the parent router goes offline?
  3. Why is the coordinator special?

Check-Your-Understanding Answers

  1. To conserve power while still receiving pending messages.
  2. The end device must rejoin and find a new parent.
  3. It forms the network and manages address assignments.

Real-World Applications

  • Battery-powered sensors in smart homes and industrial monitoring.

Where You’ll Apply It

  • See Section 3.2 Functional Requirements and Section 5.10 Phase 1.
  • Also used in: P04 Matter Smart Light for network model comparisons.

References

  • Zigbee specification overview
  • ESP Zigbee SDK documentation

Key Insights

Role selection is the most important design decision in Zigbee.

Summary

Zigbee roles define how devices behave in the mesh. A sensor should be a sleepy end device to save power, but that changes how it receives commands.

Homework/Exercises to Practice the Concept

  1. Draw a Zigbee network with one coordinator, two routers, and two end devices.
  2. Explain how an end device would recover if its parent fails.

Solutions to the Homework/Exercises

  1. Coordinator at root, routers in middle, end devices attached to routers.
  2. It performs a rejoin and selects a new parent router.

2.2 Concept 2: ZCL Clusters and Attribute Reporting

Fundamentals

Zigbee uses the Zigbee Cluster Library (ZCL) to standardize device behavior. A cluster is a group of attributes and commands. Sensors typically use the Temperature Measurement cluster and Relative Humidity cluster. Reporting is how a device sends attribute updates to the coordinator. You can configure reporting intervals and thresholds to balance data freshness and battery life. Without proper reporting, your sensor will not show updates in Home Assistant.

Deep Dive into the Concept

ZCL defines clusters with IDs and attribute semantics. The Temperature Measurement cluster includes attributes like MeasuredValue, MinMeasuredValue, and MaxMeasuredValue, typically expressed in 0.01 degrees Celsius. The Relative Humidity cluster uses 0.01 percent units. The device must provide these values correctly, or controllers will display nonsense. This is why scaling and unit conversion are important. If your sensor reads 23.45 C, you must report 2345 as a 16-bit signed integer.

Reporting is configured by the coordinator. It specifies min and max reporting intervals and a reportable change threshold. For example, report every 60 seconds or if temperature changes by 0.5 C. The device then sends reports only when needed. This reduces traffic and saves power. However, if the device is a sleepy end device, the reporting schedule must align with its wake cycle. If the device sleeps for 10 minutes but the max interval is 1 minute, it will miss the schedule. In practice, you should set reporting intervals that match the device’s duty cycle.

Attribute reporting is handled by the Zigbee stack, but you must inform the stack when attribute values change. This is often done by writing the attribute in the ZCL database and triggering a report. Some stacks allow manual reporting, but the standard approach is to let the stack manage it based on configured intervals. If you update attributes only in RAM and do not inform the stack, no reports will be sent.

ZCL also defines mandatory clusters for specific device types. A temperature sensor device type may require Identify or Basic clusters in addition to Temperature Measurement. For compatibility with Home Assistant and other coordinators, you should include the standard Basic cluster with manufacturer and model strings. This is a small detail but often determines whether a device is recognized correctly.

How this fits on projects

You will implement Temperature and Humidity clusters and configure reporting intervals that match your sleep schedule. This is the core of the sensor behavior.

Definitions & Key Terms

  • ZCL: Zigbee Cluster Library, standard device model.
  • Cluster: Group of attributes and commands.
  • Attribute: State value in a cluster.
  • Reporting: Automatic attribute updates to the coordinator.
  • Reportable change: Minimum change before sending a report.

Mental Model Diagram (ASCII)

Sensor -> ZCL Attribute Update -> Zigbee Stack -> Report to Coordinator

How It Works (Step-by-Step)

  1. Read sensor data and convert to ZCL units.
  2. Update ZCL attributes in the stack database.
  3. Zigbee stack checks reporting configuration.
  4. If conditions met, send report to coordinator.

Minimal Concrete Example

int16_t temp_zcl = (int16_t)(temp_c * 100);
zb_zcl_set_attr(EP, TEMP_CLUSTER, MEASURED_VALUE, &temp_zcl);

Common Misconceptions

  • “Reporting is automatic without configuration.” It requires setup by the coordinator.
  • “Units are raw sensor values.” ZCL uses fixed-point units.
  • “Any cluster is fine.” Standard clusters improve interoperability.

Check-Your-Understanding Questions

  1. Why are ZCL values scaled (0.01 units)?
  2. How does reporting reduce network traffic?
  3. What happens if your wake cycle is longer than max reporting interval?

Check-Your-Understanding Answers

  1. Fixed-point units avoid floats and standardize precision.
  2. Reports are sent only when needed or on interval.
  3. Reports will be late or missed; you must align intervals with wake schedule.

Real-World Applications

  • Temperature, humidity, and air quality sensors in smart homes.

Where You’ll Apply It

  • See Section 3.2 Functional Requirements and Section 5.10 Phase 2.
  • Also used in: P04 Matter Smart Light for cluster-based thinking.

References

  • Zigbee Cluster Library specification
  • Home Assistant ZHA device database

Key Insights

Correct clusters and reporting are the difference between a “talking” device and a working sensor.

Summary

ZCL defines the data model for Zigbee. Implementing standard clusters and reporting intervals ensures your sensor appears correctly in controllers.

Homework/Exercises to Practice the Concept

  1. Convert 23.45 C into ZCL units.
  2. Design a reporting configuration for a sensor that wakes every 5 minutes.

Solutions to the Homework/Exercises

  1. 23.45 C -> 2345.
  2. Min interval 300s, max interval 600s, reportable change 0.5 C.

2.3 Concept 3: Sleepy End Device Power Strategy

Fundamentals

A sleepy end device minimizes power by sleeping most of the time. It only wakes to sample sensors and send reports. Because it cannot receive messages while sleeping, it must poll its parent periodically or at wake. The firmware must carefully manage wake intervals and sensor power. The goal is to align reporting with wake cycles and minimize the active time.

Deep Dive into the Concept

Sleepy end devices follow a pattern: wake, sample, transmit, sleep. The time spent awake should be as short as possible. This requires efficient sensor readouts and minimal network traffic. Many sensors have a warm-up time; you may need to power the sensor early or keep it powered between sleeps. This is a key design decision. If you power off the sensor between cycles, you save power but pay a warm-up cost. If you keep it on, you simplify timing but increase baseline current.

The Zigbee stack itself consumes energy during wake. It must re-establish or maintain its connection to the parent. In some stacks, the device can “deep sleep” and lose network context, then perform a rejoin on every wake. This is more expensive but can be simpler. Alternatively, the device can retain network keys and poll the parent quickly, which reduces overhead. You must understand what your stack supports and choose accordingly.

Polling interval is another tradeoff. A shorter poll interval reduces the latency for receiving commands, but increases power consumption. For a sensor that rarely receives commands, a longer poll interval is fine. In practice, you might poll only when awake for reporting and otherwise sleep. That means the device is not responsive to commands between reports, which is acceptable for sensors but not for actuators.

Finally, battery life estimation is essential. Use the power profiling techniques from Project 2 to measure current in active and sleep states. Compute the average current based on your wake schedule. This gives you realistic battery life estimates and lets you tune the reporting interval.

How this fits on projects

You will design a wake schedule and reporting interval, then measure actual current to validate your power budget.

Definitions & Key Terms

  • Sleepy end device: A Zigbee end device that sleeps to save power.
  • Poll: Request from end device to check for pending messages.
  • Rejoin: Process of reattaching to the network after losing context.
  • Duty cycle: Fraction of time the device is awake.

Mental Model Diagram (ASCII)

Wake -> Sample -> Report -> Sleep -> (repeat)

How It Works (Step-by-Step)

  1. Wake from timer.
  2. Power sensor and read data.
  3. Update ZCL attributes and send report.
  4. Sleep for fixed interval.

Minimal Concrete Example

read_sensor();
report_attributes();
enter_sleep(300); // 5 minutes

Common Misconceptions

  • “Sleepy end device is always responsive.” It is only responsive when awake or polling.
  • “Longer sleep always better.” Too long can make data stale.
  • “Sensor power is negligible.” Sensors can dominate current.

Check-Your-Understanding Questions

  1. Why do sleepy devices poll their parent?
  2. What is the tradeoff in choosing a long reporting interval?
  3. How does sensor warm-up affect energy budget?

Check-Your-Understanding Answers

  1. To receive pending messages without staying awake.
  2. Less power but slower data updates.
  3. Warm-up time increases active duration and energy per cycle.

Real-World Applications

  • Battery-powered environmental monitoring.
  • Industrial sensors with long reporting intervals.

Where You’ll Apply It

  • See Section 5.10 Phase 3 and Section 6.2 Critical Test Cases.
  • Also used in: P02 Deep Sleep Champion for measurement.

References

  • Zigbee low-power design guides
  • ESP Zigbee SDK power management docs

Key Insights

Battery life is determined more by wake schedule than by radio spec.

Summary

Sleepy end devices trade responsiveness for battery life. Align reporting with wake cycles and measure the real current.

Homework/Exercises to Practice the Concept

  1. Compute average current for 30 mA active 200 ms and 10 uA sleep for 5 minutes.
  2. List three ways to reduce active time.

Solutions to the Homework/Exercises

  1. Average = (30mA0.2s + 0.01mA300s)/300.2s ~ 0.03 mA.
  2. Optimize sensor read, reduce log output, reduce network overhead.

3. Project Specification

3.1 What You Will Build

A Zigbee end device that measures temperature and humidity, joins a Zigbee coordinator, and reports data at a fixed interval. The device should appear in Home Assistant via ZHA.

3.2 Functional Requirements

  1. Zigbee Join: Device joins a coordinator as a sleepy end device.
  2. ZCL Clusters: Implement Temperature and Humidity clusters.
  3. Reporting: Configure attribute reporting intervals.
  4. Power Management: Enter sleep between reports.
  5. Logging: Print join status and report events.

3.3 Non-Functional Requirements

  • Battery Life: Demonstrate low sleep current.
  • Reliability: Rejoin network after reset.
  • Compatibility: Recognized by Home Assistant ZHA.

3.4 Example Usage / Output

[Zigbee] Joined PAN 0x1A2B
[Report] Temp=23.45C Hum=45.0%

3.5 Data Formats / Schemas / Protocols

  • ZCL Temperature: int16, 0.01 C units
  • ZCL Humidity: uint16, 0.01 percent units

3.6 Edge Cases

  • Coordinator not available; device retries join.
  • Reporting interval too short for sleep cycle.
  • Sensor read fails; report stale data.

3.7 Real World Outcome

A Home Assistant dashboard shows live temperature and humidity updates from your sensor.

3.7.1 How to Run (Copy/Paste)

idf.py set-target esp32c6
idf.py build
idf.py -p /dev/ttyUSB0 flash monitor

3.7.2 Golden Path Demo (Deterministic)

  • Fixed report interval 5 minutes.
  • Fixed sensor stub values for testing.

Expected log:

[Report] Temp=23.45C Hum=45.00%

3.7.3 Failure Demo (Join Failed)

E (123) ZIGBEE: Join failed, retrying in 30s

3.7.4 If CLI

No standalone CLI. Exit codes not applicable.

3.7.5 If Web App

Not applicable.

3.7.6 If API

No API is exposed. Error JSON shape not applicable.

3.7.7 If GUI / Desktop / Mobile

Dashboard is provided by Home Assistant.

3.7.8 If TUI

Not applicable.


4. Solution Architecture

4.1 High-Level Design

Sensor -> ZCL Attributes -> Zigbee Stack -> Coordinator -> Home Assistant

4.2 Key Components

| Component | Responsibility | Key Decisions | |———-|—————-|—————| | Zigbee stack | Join and manage network | Sleepy end device mode | | Sensor driver | Read temp/humidity | I2C sensor selection | | ZCL layer | Map sensor values to attributes | Proper scaling | | Power manager | Sleep between reports | Timer-based wake |

4.3 Data Structures (No Full Code)

struct env_data {
    int16_t temp_zcl;
    uint16_t hum_zcl;
};

4.4 Algorithm Overview

Key Algorithm: Report Cycle

  1. Wake from timer.
  2. Read sensor and convert to ZCL units.
  3. Update attributes and send report.
  4. Sleep until next cycle.

Complexity Analysis:

  • Time: O(1) per cycle
  • Space: O(1)

5. Implementation Guide

5.1 Development Environment Setup

idf.py set-target esp32c6
idf.py build

5.2 Project Structure

p07_zigbee_sensor/
+-- main/
|   +-- zigbee_app.c
|   +-- sensor_driver.c
|   +-- power_mgr.c
+-- README.md

5.3 The Core Question You’re Answering

“How do mesh sensors run for years on a coin cell?”

5.4 Concepts You Must Understand First

  1. Zigbee roles and network formation
  2. ZCL clusters and reporting
  3. Sleepy end device power strategy

5.5 Questions to Guide Your Design

  1. What reporting interval matches your power budget?
  2. Which ZCL clusters are required for temperature and humidity?
  3. How will you handle failed joins or rejoin events?

5.6 Thinking Exercise

If you report every 60 seconds vs every 10 minutes, how does battery life change?

5.7 The Interview Questions They’ll Ask

  1. What is the role of a Zigbee coordinator?
  2. Why do end devices poll their parent?
  3. How does ZCL reporting reduce traffic?

5.8 Hints in Layers

Hint 1: Start with a Zigbee sensor example from the ESP SDK.

Hint 2: Use standard ZCL clusters for compatibility.

Hint 3: Align report interval with wake schedule.

Hint 4: Use Home Assistant ZHA for easy validation.

5.9 Books That Will Help

| Topic | Book | Chapter | |——|——|———| | Zigbee | Zigbee Wireless Networking | Stack chapters | | Low power | Making Embedded Systems | Power chapters |

5.10 Implementation Phases

Phase 1: Join Network (2 days)

Goals:

  • Join as a sleepy end device.
  • Log network info.

Tasks:

  1. Configure Zigbee stack.
  2. Join coordinator and store short address.

Checkpoint: Device joins and prints PAN ID.

Phase 2: Sensor Reporting (2-3 days)

Goals:

  • Read sensor data.
  • Update ZCL attributes.

Tasks:

  1. Implement sensor driver.
  2. Write attributes and report.

Checkpoint: Coordinator receives reports.

Phase 3: Power Optimization (2 days)

Goals:

  • Enter sleep between reports.
  • Measure current.

Tasks:

  1. Implement timer-based sleep.
  2. Capture power profile.

Checkpoint: Sleep current in microamps.

5.11 Key Implementation Decisions

| Decision | Options | Recommendation | Rationale | |———-|———|—————-|———–| | Device role | Router vs end device | Sleepy end device | Battery life | | Reporting interval | Short vs long | Long (5-10 min) | Reduce power | | Sensor power | Always on vs duty cycled | Duty cycled | Lower current |


6. Testing Strategy

6.1 Test Categories

| Category | Purpose | Examples | |———-|———|———-| | Unit Tests | Validate ZCL scaling | Temperature conversion | | Integration Tests | Join and report | Home Assistant logs | | Edge Case Tests | Rejoin after reset | Network stability |

6.2 Critical Test Cases

  1. Join: Device joins coordinator within 60 seconds.
  2. Reporting: Reports appear in Home Assistant.
  3. Sleep: Device sleeps between reports and wakes on schedule.

6.3 Test Data

Temp=23.45C -> 2345
Hum=45.0% -> 4500

7. Common Pitfalls & Debugging

7.1 Frequent Mistakes

| Pitfall | Symptom | Solution | |——–|———|———-| | Wrong cluster IDs | No data in HA | Use standard cluster IDs | | Sleep too long | Reports stale | Shorten interval or increase reportable change | | Join fails | Device keeps scanning | Ensure coordinator is open to join |

7.2 Debugging Strategies

  • Use Zigbee logs to verify join and report events.
  • Temporarily disable sleep to debug reporting.

7.3 Performance Traps

  • Frequent reporting increases battery drain and network congestion.

8. Extensions & Challenges

8.1 Beginner Extensions

  • Add battery voltage reporting.
  • Add an LED indicator for join status.

8.2 Intermediate Extensions

  • Add a second sensor (pressure or light).
  • Implement identify cluster with LED blink.

8.3 Advanced Extensions

  • Secure joining with install codes.
  • Implement OTA update cluster.

9. Real-World Connections

9.1 Industry Applications

  • Smart home environmental sensors.
  • Industrial monitoring with low power mesh networks.
  • ZHA (Home Assistant) - Zigbee integration.
  • Zigbee2MQTT - alternative Zigbee coordinator stack.

9.3 Interview Relevance

  • Zigbee roles, ZCL clusters, and power design are common interview topics.

10. Resources

10.1 Essential Reading

  • Zigbee Cluster Library specification
  • ESP Zigbee SDK documentation

10.2 Video Resources

  • “Zigbee Basics” (tutorial)
  • “Zigbee for Developers” (talk)

10.3 Tools & Documentation

  • Home Assistant ZHA
  • Zigbee2MQTT (optional)

11. Self-Assessment Checklist

11.1 Understanding

  • I can explain Zigbee roles and parent-child relationships.
  • I can map sensor values to ZCL attributes.
  • I can design a sleep schedule for reporting.

11.2 Implementation

  • Device joins Zigbee network.
  • Reports appear in Home Assistant.
  • Sleep current is low and stable.

11.3 Growth

  • I can explain tradeoffs between report interval and battery life.
  • I can troubleshoot join failures.

12. Submission / Completion Criteria

Minimum Viable Completion:

  • Device joins network and reports temperature.

Full Completion:

  • Reports temperature and humidity on schedule.
  • Sleep current and battery estimate documented.

Excellence (Going Above & Beyond):

  • Secure joining and OTA update support.
  • Extended sensor suite with additional clusters.