Adding ESP32-H2-Zero (Matter/Thread) device using ESPHome

I am trying to get started with my first ESP32-H2-Zero microcontroller (from WaveShare). It is very low power and does not have wifi. I specifically picked it because I am trying to keep my wifi clean and double down on matter over thread.

I have a ZBT-2 antenna on my system and it is configured for Matter (which means it does not support Zigbee).

I created my device in esphome but the device appears offline. How can I add it to my matter/thread network? the default mechanism is to scan a bar code, but there is no bar code to scan as it is a custom device I just created. How can I download a key or something and get it to bind to my HA? Other matter devices seem to require my phone and bluetooth to do the binding, but I am not seeing how I can add this device.

Has anyone created a matter/thread device with esphome and added it to HA?

Update: the flash process I used does not seem to be bootable. I was able to connect to the device and download the logs from it, and this is what I see. It looks like the partition (factory) that I uploaded the image to is not bootable. I don’t know which partition I need to use to make this bootable. I kept a copy of the original factory image. Should I flash that back, and then flash this image to the first empty address after it? Or how do I designate a partition as bootable?

[22:02:55]I (28) boot: ESP-IDF v5.5 2nd stage bootloader
[22:02:55]I (28) boot: compile time Aug 19 2025 16:16:36
[22:02:55]I (29) boot: chip revision: v1.2
[22:02:55]I (29) boot: efuse block revision: v0.3
[22:02:55]I (31) boot.esp32h2: SPI Speed      : 64MHz
[22:02:55]I (35) boot.esp32h2: SPI Mode       : DIO
[22:02:55]I (39) boot.esp32h2: SPI Flash Size : 4MB
[22:02:55]I (43) boot: Enabling RNG early entropy source...
[22:02:55]I (47) boot: Partition Table:
[22:02:55]I (50) boot: ## Label            Usage          Type ST Offset   Length
[22:02:55]I (56) boot:  0 nvs              WiFi data        01 02 00009000 00006000
[22:02:55]I (63) boot:  1 phy_init         RF data          01 01 0000f000 00001000
[22:02:55]I (69) boot:  2 factory          factory app      00 00 00010000 00100000
[22:02:55]I (76) boot: End of partition table
[22:02:55]E (79) esp_image: Failed to fetch app description header!
[22:02:55]E (84) boot: Factory app partition is not bootable
[22:02:55]E (88) boot: No bootable app partitions in the partition table
[22:02:55]ESP-ROM:esp32h2-eco5-20240613
[22:02:55]Build:Jun 13 2024
[22:02:55]rst:0x3 (LP_SW_HPSYS),boot:0xc (SPI_FAST_FLASH_BOOT)
[22:02:55]Saved PC:0x40003308
[22:02:55]SPIWP:0xee
[22:02:55]mode:DIO, clock div:1
[22:02:55]load:0x408460f0,len:0x1700
[22:02:55]load:0x4083c2d0,len:0xf78
[22:02:55]load:0x4083efd0,len:0x2fdc
[22:02:55]entry 0x4083c2da

Did it run before you attempted to load ESPHome on it?

Post your ESPHome yaml, compile and a bit of the run log. [Formatted please]

It is a new board, and this is my first attempt to get it running. It fails to initialize or flash via the device management tool. I had to use the raw esp connect tool to flash an image. The image flashes fine but the board is not bootable after the flash. I think there is a bug in esphome regarding this board, and I obviously don’t know enough about how to work around the issue with the raw esp connect tool. The only logs I get are the ones I put in the question.

AFAIK, you can’t use ESPHome for Matter. Its just ESPHome protocol over Thread.

Good news, I have figured it out. There needs to be a better guide for this process. What I discovered after reading a few other blogs is that matter/thread provisioning with ESPHome is different than straight up HA. You capture your TLVs string from Settings | integrations | thread | configure (gear icon), then the info icon on that screen. It is a long string.

Then you wipe out the wifi and captive portal section in your yaml file, and inject the following, substituting your TLVs string:

network:
enable_ipv6: true

openthread:
tlv:

Once you get this flashed to your board, the device will automatically authenticate to the thread border router using that information. This replaces the standard matter/thread provisioning using bluetooth and screen capturing a bar code. Once you boot your board, it should just show up as a discovered device and you can then configure it and add it to your dashboard.

2 Likes

Did this really solved the boot loop problem? I did it exactly the same (various reciepts exists on the net). But I cannot leave the boot loop telling me

[18:40:50]ESP-ROM:esp32h2-eco5-20240613
[18:40:50]Build:Jun 13 2024
[18:40:50]rst:0xc (SW_CPU),boot:0x1c (SPI_FAST_FLASH_BOOT)
[18:40:50]Saved PC:0x40003318
[18:40:50]SPIWP:0xee
[18:40:50]mode:DIO, clock div:1
[18:40:50]load:0x408460f0,len:0x1744
[18:40:50]load:0x4083c2d0,len:0xf98
[18:40:50]load:0x4083efd0,len:0x3074
[18:40:50]entry 0x4083c2d0
[18:40:50]I (22) boot: ESP-IDF 5.5.2 2nd stage bootloader
[18:40:50]I (23) boot: compile time Jan 21 2026 18:39:01
[18:40:50]I (24) boot: chip revision: v1.2
[18:40:50]I (24) boot: efuse block revision: v0.3
[18:40:50]I (25) boot.esp32h2: SPI Speed      : 64MHz
[18:40:50]I (25) boot.esp32h2: SPI Mode       : DIO
[18:40:50]I (26) boot.esp32h2: SPI Flash Size : 4MB
[18:40:50]I (26) boot: Enabling RNG early entropy source...
[18:40:50]I (27) boot: Partition Table:
[18:40:50]I (27) boot: ## Label            Usage          Type ST Offset   Length
[18:40:50]I (28) boot:  0 otadata          OTA data         01 00 00009000 00002000
[18:40:50]I (29) boot:  1 phy_init         RF data          01 01 0000b000 00001000
[18:40:50]I (30) boot:  2 app0             OTA app          00 10 00010000 001c0000
[18:40:50]I (31) boot:  3 app1             OTA app          00 11 001d0000 001c0000
[18:40:50]I (32) boot:  4 nvs              WiFi data        01 02 00390000 0006d000
[18:40:50]I (33) boot: End of partition table
[18:40:50]I (34) esp_image: segment 0: paddr=00010020 vaddr=420b0020 size=244d8h (148696) map
[18:40:50]I (94) esp_image: segment 1: paddr=00034500 vaddr=40800000 size=0b3dch ( 46044) load
[18:40:50]I (116) esp_image: segment 2: paddr=0003f8e4 vaddr=4080b3e0 size=00734h (  1844) load
[18:40:50]I (118) esp_image: segment 3: paddr=00040020 vaddr=42000020 size=a1f1ch (663324) map
[18:40:50]I (379) esp_image: segment 4: paddr=000e1f44 vaddr=4080bb14 size=014d4h (  5332) load
[18:40:50]I (390) boot: Loaded app from partition at offset 0x10000
[18:40:50]I (390) boot: Disabling RNG early entropy source...
[18:40:50][I][logger:121]: Log initialized
[18:40:50][C][safe_mode:118]: Unsuccessful boot attempts: 10
[18:40:50][E][safe_mode:130]: Boot loop detected
[18:40:50][E][component:415]: safe_mode set Error flag: unspecified
[18:40:50][I][app:087]: Running through setup()
[18:40:50]
[18:40:50]assert failed: xQueueSemaphoreTake queue.c:1709 (( pxQueue ))
[18:40:50]Core  0 register dump:
[18:40:50]MEPC    : 0x40804b52  RA      : 0x40804b16  SP      : 0x4081d640  GP      : 0x4080bbe4

My yaml looks like this:

esphome:
  name: thread-test
  friendly_name: thread-test
 
esp32:
  variant: ESP32H2
  framework:
    type: esp-idf
 
# Enable logging
logger:
 
# Enable Home Assistant API
api:
  encryption:
    key: "some-valid-key="
 
ota:
  - platform: esphome
    password: areallysecretpassword

network:
  enable_ipv6: true
 
openthread:
  device_type: FTD
  tlv: mytlv-a-long-string

remove the OTA section

1 Like

May i inquire as to why this helps? having the exact same issue.