Skip to content

Instantly share code, notes, and snippets.

@casebeer
Last active October 8, 2025 20:05
Show Gist options
  • Select an option

  • Save casebeer/8ef6f9a3549701cc9ad3fc62504b9e24 to your computer and use it in GitHub Desktop.

Select an option

Save casebeer/8ef6f9a3549701cc9ad3fc62504b9e24 to your computer and use it in GitHub Desktop.
Working esphome config and install notes for ewelink ZB-GW03 esp32-based 10/100 Ethernet to Zigbee device.
# eWeLink ZB GW03 Modified ESPHome Config
#
# - Add debug text sensors
# - Add bluetooth_proxy
# - Add web_server for offline reflash
#
# Important documentation from upstream
#
# - https://github.com/syssi/esphome-zb-gw03
# - [Flash ESPHome and use the ZB-GW03 as Zigbee Coordinator](https://github.com/syssi/esphome-zb-gw03/blob/main/docs/flashing.md)
# - [How to convert from Zigbee Coordinator into a Zigbee Router device](https://github.com/syssi/esphome-zb-gw03/blob/main/docs/router.md)
#
# Flashing the Zigbee chipset
#
# Get the flashing tools:
# apt-get install telnet lrzsz
# brew install telnet lrzsz
#
# Enter firmware upload mode:
# - Trigger firmware mode by setting the "Zigbeen download mode" switch ON
# and pressing the Zigbee reset button from Home Assistant
# - Telnet to the serial stream port 6638. Hit "Enter" if nothing appears.
# - In the "Gecko bootloader" main menu displayed, choose "Upload GBL"
# - Disconnect telent (or go to a fresh terminal window)
#
# Upload firmware:
# - Get an appropriate Silicon Labs EFR32MG21 radio Coordinator or Router firmware:
# - Coordinator: https://github.com/arendst/Tasmota/raw/development/tools/fw_SonoffZigbeeBridge_ezsp/ncp-uart-sw_6.7.8_115200.ota
# - Router: https://github.com/digiblur/Tasmota/raw/development/zigbee_router/efr32mg21_zigbee_router_signed-6.7.10.gbl.ota
# - Note that Tasmota's `ncp-uart-sw-6.7.8_115200.ota` is the current (2021–2023) Coordinator firmare, while
# `ncp-uart-nsw_6.7.9_115200.ota` is still marked "Testing" after two years.
# - Use the `sx` tool to upload the firmware:
#
# sx -vv -X -b --tcp-client <zb-gw03-ip>:6638 <firmware-file.ota>
#
# GPIO15 LedLink (red led)
# GPIO14 Led_i 1 (green led)
# GPIO16 ETH POWER
# GPIO18 ETH MDIO
# GPIO23 ETH MDC
# GPIO34 Button 1
# GPIO12 Zigbee RST 2
# GPIO13 Zigbee RST 1
# GPIO02 Zigbee Tx
# GPIO04 Zigbee Rx
# GPIO32 I2C SCL 1
# GPIO33 I2C SDA 1
substitutions:
name: zb-gw03-coordinator
device_name: "${name}"
device_description: "ZB-GW03 eWeLink Ethernet Zigbee Gateway based Zigbee Coordinator"
device_role: "coordinator"
packages:
zb-gw03:
url: https://github.com/syssi/esphome-zb-gw03
ref: main
files:
#- packages/core.yaml
- packages/ethernet.yaml
- packages/status_led.yaml
- packages/green_led.yaml
#- packages/i2c.yaml
- packages/button_zigbee_reset.yaml # alt button_pairing_mode.yaml
- packages/mdns.yaml
#- packages/wifi.yaml
refresh: 0s
esphome:
name: ${name}
name_add_mac_suffix: true
comment: ${device_description}
min_version: 2024.6.0
project:
name: "syssi.esphome-zb-gw03"
version: 2.1.0
platformio_options:
build_flags: "-DUSE_MDNS_EXTRA_SERVICES"
on_boot:
priority: 600
then:
- switch.turn_off: download_mode
- switch.turn_on: zigbee_reset
- lambda: |-
if("${device_role}" == "coordinator") {
id(mdns0).add_extra_service({
"_zigbee-coordinator",
"_tcp",
6638,
{
{"name", "ZB-GW03"},
{"serial_number", get_mac_address()},
{"radio_type", "ezsp"}
}
});
}
esp32:
board: esp-wrover-kit
framework:
type: esp-idf
external_components:
- source: github://oxan/esphome-stream-server@master
ota:
- platform: esphome
id: esp_ota
# password: !secret ota_password
- platform: web_server # no auth unless web_server auth enabled!
# disable web_server before using bluetooth proxy
bluetooth_proxy:
active: true
cache_services: true
esp32_ble_tracker:
scan_parameters:
interval: 1100ms # disable if using wifi
window: 1100ms # disable if using wifi
active: true
# Don't enable alongside bluetooth_proxy
web_server:
port: 80
logger:
level: DEBUG
api:
encryption:
# key: !secret api_encryption_key
mdns:
id: mdns0
uart:
id: uart_zigbee
rx_pin: GPIO4
tx_pin: GPIO2
baud_rate: 115200
stream_server:
uart_id: uart_zigbee
port: 6638
switch:
- platform: restart
name: "${name} Restart"
- platform: safe_mode
name: "Safe mode restart ${device_name}"
- platform: template
id: zigbee_reset
name: "${name} Zigbee Reset"
turn_on_action:
- switch.turn_on: zigbee_rst
- delay: 10ms
- switch.turn_off: zigbee_rst
# SM-011 V1.0 nRST
- platform: gpio
id: zigbee_rst
pin: GPIO13
name: "${name} Zigbee nRST"
inverted: true
internal: true
restore_mode: ALWAYS_OFF
# SM-011 V1.0 PA00
- platform: gpio
id: download_mode
pin: GPIO12
name: "${name} Zigbee Download Mode"
inverted: true
restore_mode: ALWAYS_OFF
binary_sensor:
- platform: stream_server
connected:
name: "Serial Connected ${device_name}"
sensor:
- platform: stream_server
connection_count:
name: "Number of connections ${device_name}"
- platform: debug
free:
name: "[debug] Heap Free ${device_name}"
#fragmentation: # esp8266 only
# name: "[debug] Heap Fragmentation ${device_name}"
block:
name: "[debug] Heap Max Block ${device_name}"
loop_time:
name: "[debug] Loop Time ${device_name}"
#psram: # PSRAM esp32 only
# name: "[debug] Free PSRAM ${device_name}"
debug:
text_sensor:
- platform: debug
device:
name: "[debug] Device info ${device_name}"
reset_reason:
name: "[debug] Reset reason ${device_name}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment