Help with ESP32-H2 Zigbee

Hello community,

I’m introducing myself, I’m an IT specialist and electronics engineer (my IT job has taken over my electronics background), and I’m quite skilled in electronics.
I’m looking to do some home automation with my eldest son to teach him the principles of IT and electronics by creating all the tools and managing the home automation with temperature, humidity, and light sensors, etc.
I’ve chosen the ESP32-H2, but after several searches, I’ve found that this module is not widely used and there are few code examples.
Could someone help me with a code example? I’m looking to manage relays with GPIO for on/off functionality.

Thank you for your help.

Are you using arduino or esp-idf?

The ESP32-H2 is an ESP-IDF, I have installed all the development tools in Visual Studio.

The expressif examples are probably the best place to start. Here’s a link to a standard on/off switch. The have examples for the other common ZHA types as well.

This isn’t a switch, but it’s an example of a complete device, in this case temp sensor + binary output. Writeup is here.

For your described use-case scenario I would recommend that it would be a better idea to only use ESP32 with Wi-Fi or Ethernet (instead of Zigbee) and first get started with either ESPHome or Tasmota firmware for other ESP32 SoCs (like example the popular ESP32-S3). You can use ESPHome or Tasmota with the same components as long as use WiFi or Ethernet.

Understand that even though the ESP32-H2 (and ESP32-C6) SoC hardware with Zigbee/Thread radio was announced a couple of years ago the the dependency code/libraries and software development kit are just now slowly beginning to become available (as still only as experimental pre-alpha as Zigbee on ESP32 is not even close to be called mature). Regardless, this forum-section is not the best place to ask about DIY Zigbee device development as this is instead more about the built-in Zigbee Home Automation integration (i.e. Home Assistant’s native “ZHA” Zigbee Gateway) and end-users trying to get existing retail Zigbee devices working with that. So if you still insist on using Zigbee on ESP32 then check out either Espressif’s official ESP-Zigbee-SDK or maybe the new Zigbee API that Espressif’s developer is working on for Arduino (but note that niether of those should be considered close to mature or good for beginners):

PS: As far as I know DIY Zigbee device development is still a very niche and small scene as still requires relatively low-level C/C++ programming skills, (and those who are experimenting with Zigbee are not commonly using ESP32 but instead I think are instead probably using Digi XBee (Digi XBee-PRO Zigbee RF modules) or more professional/commercial platforms like example either Nordic Semiconductor nRF5 (for nRF52/nRF53) or Silicon Labs Simplicity SDK (for EFR32 Series 2/3) as platforms which far more mature with great documentation (but still require C/C++ programming skills for programming).

Admittedly, I just switched over from building Zigbee devices with xbee + arduino to esp-idf, but I haven’t yet found any limitations in the sdk. The major device types are defined and it works well, the biggest issue is the lack of documentation and several of their examples are out of date and won’t compile, but it’s doable.

The missing piece is more in ZHA at this point, we need to finish up support for the Analog In and Multistate clusters to start.

FYI, tomaszduda23 is also working on experimental native Zigbee support for ESPHome (but for now he is only testing that on an experimental nrf52 platform with nrf52840 SoC for ESPHome so doubly experimental):

You might be right, but I guess that it would then be better to have discussions on GitHub under the zigpy organization’s repositories instead of here (as other than you yourself have not seen any other Zigbee developers hang out here in Home Assistant’s community forum often :wink: )

Discord chats is an alternative but then it does not help others in the future who might stubmple onto this.

Hello,

Thank you for your feedback and assistance. However, as I am stubborn and resourceful, I have researched how to use my ESP32-H2 and found and programmed a code that allows me to use an ESP32-H2 with a relay connected to light bulbs using Home Assistant. To better do all this, I created a tutorial, but without telling you, I am stuck at a step which is the compilation of the code.

The error I have:1/1] idf (5.3.0)
CMake Error at /Users/name/esp2/v5.3/esp-idf/tools/cmake/build.cmake:268 (message):

Failed to resolve component 'some_dependency'.
Call Stack (most recent call first):
/Users/name/esp2/v5.3/esp-idf/tools/cmake/build.cmake:304 (__build_resolve_and_add_req)
/Users/name/esp2/v5.3/esp-idf/tools/cmake/build.cmake:607 (__build_expand_requirements)
/Users/name/esp2/v5.3/esp-idf/tools/cmake/project.cmake:710 (idf_build_process)
CMakeLists.txt:7 (project)

I have tried several changes without result. If you have any ideas, I’m open to them.Following this, here’s my tutorial to perhaps start something new on the ESP32-H2To install the ESP-IDF (Espressif IoT Development Framework) in Visual Studio Code (VS Code) on a Mac, here are the steps to follow:Prerequisites on macOS:

  1. Homebrew:
    You need to install Homebrew, a package manager.
    Run this command in your terminal:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  1. Python 3.x:
    You need to verify that Python 3 is installed:
python3 --version

If not installed, move on to the next step.

Step 1: Install ESP-IDF dependencies via HomebrewIn a terminal, run the following commands to install the cmake, ninja, and python3 dependencies:

brew install cmake ninja python3 gitStep 2: Download ESP-IDF
  1. You need to install the ESP-IDF repository from GitHub via the terminal:
mkdir esp32
git clone --recursive https://github.com/espressif/esp-idf.gitthencd esp-idf
  1. Install the necessary tools for ESP-IDF:
./install.sh esp32-h2

Replace esp32-h2 with esp32s2, or esp32c3 depending on the esp32.

Step 3: Configure ESP-IDF
Configure the environment by running the following command:

. $HOME/esp/esp-idf/export.sh

This will set up the environment variables for ESP-IDF.

Step 4: Install Visual Studio Code
If you don’t have Visual Studio Code installed yet, download and install it.

Step 5: Then install the ESP-IDF extension for Visual Studio Code

  1. Launch Visual Studio Code and open the VS Code Marketplace.
  2. Search for Espressif-IDF in the search bar.
  3. Install the official Espressif-IDF extension.

Step 6: Configure the ESP-IDF extension in VS Code

  1. Once the extension is installed, open the Command Palette in Visual Studio Code.
  2. Type and select ESP-IDF: Configure ESP-IDF extension.
  3. The extension will guide you to:
    o Configure the path to your ESP-IDF (the directory where you cloned esp-idf).
    o Install Python and associated tools (if not already done).
    o Configure the environment for the extension to work correctly.

Step 7: Verify the configuration

Open the integrated terminal in Visual Studio Code and type the following command to verify that the environment is properly configured:

idf.py --version

You should see the installed version of ESP-IDF.

Step 8: Create a new ESP-IDF project

  1. Open the Command Palette.
  2. Type ESP-IDF: Create project to create a new project.
  3. Choose a Template, select the folder where you want to store your project, and follow the steps.

Step 9: Compile and upload the project

  1. To compile the project, use the command:
idf.py build
  1. To upload the firmware to your ESP32, use:
idf.py flash

With these steps, you should be ready to use ESP-IDF with Visual Studio Code on a Mac.

To control relays with an ESP32-H2 via the Zigbee network and interact with Home Assistant.
Here are the steps to follow:

Step 1: Create a directory structure

File structure:/esp32h2_zigbee_relay_project
├── main
│ ├── CMakeLists.txt
│ ├── main.c
│ └── relay_control.h
├── build/
├── sdkconfig
└── CMakeLists.txtFiles to create:
  1. main.c:
    The main file containing the code to control the relays.

  2. relay_control.h:
    Header declaring relay management functions.

  3. CMakeLists.txt:
    Configuration files for compilation.

  4. sdkconfig:
    SDK configuration for the project.

Step 2: The code

main.c : Code to control relays with Zigbee.

// main.c: Code to control relays with Zigbee

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "relay_control.h"
#include "esp_zigbee.h"

#define MAX_RELAYS 20  // Modify this number based on the maximum number of relays used

// GPIOs associated with relays
const int relay_pins[MAX_RELAYS] = {
    2, 4, 5, 12
};

static const char *TAG = "Zigbee_Relay";

// GPIO initialization function for relays
void configure_gpio() {
    gpio_config_t io_conf;
    io_conf.intr_type = GPIO_INTR_DISABLE;
    io_conf.mode = GPIO_MODE_OUTPUT;
    io_conf.pin_bit_mask = 0;

    for (int i = 0; i < MAX_RELAYS; i++) {
        io_conf.pin_bit_mask |= (1ULL << relay_pins[i]);
    }

    io_conf.pull_down_en = 0;
    io_conf.pull_up_en = 0;
    gpio_config(&io_conf);

    // Initialize all relays to OFF
    for (int i = 0; i < MAX_RELAYS; i++) {
        gpio_set_level(relay_pins[i], 0);
    }
}

// Function to turn on/off a relay
void control_relay(int relay_index, bool turn_on) {
    if (relay_index >= 0 && relay_index < MAX_RELAYS) {
        gpio_set_level(relay_pins[relay_index], turn_on ? 1 : 0);
        ESP_LOGI(TAG, "Relay %d is now %s", relay_index, turn_on ? "ON" : "OFF");
    } else {
        ESP_LOGW(TAG, "Invalid relay index: %d", relay_index);
    }
}

// Zigbee callback to receive on/off commands
void zigbee_onoff_callback(uint8_t endpoint_id, uint8_t command_id, uint8_t relay_index) {
    if (command_id == 0x01) {  // "ON" command
        control_relay(relay_index, true);
    } else if (command_id == 0x00) {  // "OFF" command
        control_relay(relay_index, false);
    }
}

// Zigbee initialization
void zigbee_init() {
    esp_zb_init();

    esp_zb_endpoint_t endpoint = {
        .endpoint_id = 1,
        .profile_id = ZIGBEE_PROFILE_HOME_AUTOMATION,
        .device_id = ZIGBEE_DEVICE_ONOFF_SWITCH,
        .callback = zigbee_onoff_callback
    };

    esp_zb_add_endpoint(&endpoint);
    esp_zb_start();
}

void app_main() {
    configure_gpio();  // Configure GPIOs for relays
    zigbee_init();     // Initialize Zigbee

    ESP_LOGI(TAG, "Zigbee relay controller started");
}

// relay_control.h: Function declarations

#ifndef RELAY_CONTROL_H
#define RELAY_CONTROL_H

#include <stdbool.h>

void configure_gpio();
void control_relay(int relay_index, bool turn_on);

#endif // RELAY_CONTROL_H

# CMakeLists.txt in the main folder

idf_component_register(SRCS "main.c"
                    INCLUDE_DIRS ".")

CMakeLists.txt at the root

cmake_minimum_required(VERSION 3.5)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(esp32h2_zigbee_relay_project)

I’ll explain the Code:

  1. GPIO Configuration: Each relay is connected to a GPIO, configured as output, and we initialize them all to OFF state at startup.

  2. Relay Control: The control_relay function allows activating or deactivating a specific relay based on the index and the received command (ON/OFF).

  3. Zigbee Callback: The zigbee_on/off_callback receives Zigbee commands from Home Assistant via the Zigbee on/off cluster. The relay is activated or deactivated based on the received command.

  4. Zigbee Init: The zigbee_init function initializes the Zigbee stack and registers an endpoint for on/off type messages. This allows Home Assistant to detect the device as an on/off switch and send it commands.

Step 3: Home Assistant Configuration

  1. Zigbee Configuration: Make sure your ESP32-H2 is properly configured to work with a Zigbee dongle compatible with Home Assistant.

  2. Automatic Detection: Once connected to the Zigbee network, the controller will appear in Home Assistant as a Zigbee device. You can then define entities for each relay and control them via automations or via the user interface.

Step 4: Compilation and Flashing

  1. Compilation: Compile and flash the code on the ESP32-H2 using the following commands:
    Compile the code:
idf.py build

Then flash, if the compilation goes well, move on to the next step:

idf.py flash

Then finish and test.

A few things.

  1. #include "esp_zigbee.h" isn’t valid. you probably wanted #include "esp_zigbee_core.h"

  2. You are adding multiple clusters with the same id to a single end point.

  3. .profile_id = ZIGBEE_PROFILE_HOME_AUTOMATION,
    .device_id = ZIGBEE_DEVICE_ONOFF_SWITCH,
    These aren’t the correct constants, you likely wanted ESP_ZB_AF_HA_PROFILE_ID and ESP_ZB_HA_ON_OFF_SWITCH_DEVICE_ID

  4. The entire pattern of defining an endpoint and adding it looks wrong, that should be esp_zb_endpoint_config_t then add it with esp_zb_ep_list_add_ep

I’d suggest starting with a working example, then add your logic from there.

1 Like

Here is an example of a working device that I have been using to test some ZHA modifications. I added a switch endpoint, it will print the state to debug, but GPIO implementation would still need to be completed.

prairiesnpr/esp_zha_test_bench (github.com)

2 Likes

Lurking around. I’m very interested in using ESP and Zigbee as well, for its price and flexibility. If any of your results should go into a blog post, I would sure love a link :eyes:
I know my way around a terminal, but Zigbee is not as straight forward as I thought. I want to control my old Toshiba AC with an IR blaster.

As someone who loves to build things, it pains me to suggest otherwise, but I think there are Zigbee IR blasters on the market that work well, and it would likely be difficult to build something better or cheaper.

That said, if your AC isn’t compatible or you just wish to build it yourself, I completely understand that. As far as blog posts, that’s not really something I do, but everything is on GitHub, so feel free to look through it and ask if you have questions. There aren’t too many Zigbee device developers here, but there are a few.

And here am I now.
I just got a esp32 h2 that can use Zigbee protocols.
I have Home Assistant and a Zigbee network using the Zigbee2MQTT.
And I’m not a teck guy, so I don;t know how to connect it :frowning:

Hi, I used your project but unfortunately, it did not work. I ran in to this error. Did anything change ?

D:/Espressif/frameworks/esp-idf-v5.3.1/components/esp-zigbee-sdk/examples/esp_zha_test_bench-master/main/main.c:41:20: error: 'esp_zb_zcl_report_attr_cmd_t' {aka 'struct esp_zb_zcl_report_attr_cmd_s'} has no member named 'cluster_role'
   41 |     report_attr_cmd.cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE;
      |                    ^
D:/Espressif/frameworks/esp-idf-v5.3.1/components/esp-zigbee-sdk/examples/esp_zha_test_bench-master/main/main.c: In function 'report_analog_in_attr':
D:/Espressif/frameworks/esp-idf-v5.3.1/components/esp-zigbee-sdk/examples/esp_zha_test_bench-master/main/main.c:56:20: error: 'esp_zb_zcl_report_attr_cmd_t' {aka 'struct esp_zb_zcl_report_attr_cmd_s'} has no member named 'cluster_role'
   56 |     report_attr_cmd.cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE;
      |                    ^
D:/Espressif/frameworks/esp-idf-v5.3.1/components/esp-zigbee-sdk/examples/esp_zha_test_bench-master/main/main.c: In function 'esp_zb_task':
D:/Espressif/frameworks/esp-idf-v5.3.1/components/esp-zigbee-sdk/examples/esp_zha_test_bench-master/main/main.c:382:5: warning: 'esp_zb_main_loop_iteration' is deprecated [-Wdeprecated-declarations]
  382 |     esp_zb_main_loop_iteration();
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from D:/Espressif/frameworks/esp-idf-v5.3.1/components/esp-zigbee-sdk/examples/esp_zha_test_bench-master/main/main.h:1,
                 from D:/Espressif/frameworks/esp-idf-v5.3.1/components/esp-zigbee-sdk/examples/esp_zha_test_bench-master/main/main.c:1:
D:/Espressif/frameworks/esp-idf-v5.3.1/components/esp-zigbee-sdk/examples/esp_zha_test_bench-master/managed_components/espressif__esp-zigbee-lib/include/esp_zigbee_core.h:691:6: note: declared here
  691 | void esp_zb_main_loop_iteration(void);
      |      ^~~~~~~~~~~~~~~~~~~~~~~~~~
ninja: build stopped: subcommand failed.
ninja failed with exit code 1, output of the command is in the D:\Espressif\frameworks\esp-idf-v5.3.1\components\esp-zigbee-sdk\examples\esp_zha_test_bench-master\build\log\idf_py_stderr_output_2668 and D:\Espressif\frameworks\esp-idf-v5.3.1\components\esp-zigbee-sdk\examples\esp_zha_test_bench-master\build\log\id```

Looks like it, that was compiled with 5.3.0. Make sure you have the correct configuration set, this needs to be a router.

Someone else installed the same project here and had some notes, but I don’t think it’s related. Using analog input clusters in esp-zigbee-sdk (TZ-1142) · Issue #431 · espressif/esp-zigbee-sdk · GitHub