ESPHome support for WIZnet WSM Ethernet backends, packaged as an external component.
New here? Start with Getting Started.
This repository extends ESPHome's existing ethernet: component with a new
type, WSM_W5500, which drives a WIZnet W5500 through
wsm_driver and lets you choose between
two completely different network backends:
backend: lwip— the W5500 acts as a plain Ethernet MAC/PHY. The TCP/IP stack is ESP-IDF'sesp_netif+ LwIP, so ESPHome behaves exactly as it does on any other Ethernet board. This is the recommended backend for ESPHome and Home Assistant users.backend: toe— the W5500 runs the TCP/IP stack itself (TCP/IP Offload Engine). Sockets are hardware sockets on the chip; the ESP32-S3 never runs a software IP stack for Ethernet traffic.
Selecting the backend itself is a one-line change in your YAML — the
backend: key. Switching to toe, however, is not only that line: TOE also
requires mdns: disabled: true in the configuration, and the device must then be
reached by IP address instead of by mDNS hostname (see
Limitations).
Important:
type: WSM_W5500is not the name of the WSM-W55E module, and it is not tied to any single product. It names thewsm_driver-based W5500 implementation — the code path that drives a W5500 throughwsm_driver, with a selectable LwIP or TOE backend.
The implementation is designed for ESP32-S3 + W5500 hardware, and the GPIO pin mapping is ordinary YAML configuration rather than something the component hardcodes. The only board that is officially supported and hardware-verified today is the ESP32 W5500 DevKit; other ESP32-S3 + W5500 boards such as WSM-W55E are planned, and become supported once their board-specific pin mapping has been validated on hardware (see Hardware Roadmap). The type name stays the same as those boards are added.
type: W5500 — ESPHome's stock, upstream W5500 support — is untouched and keeps
working exactly as before. backend: exists only on type: WSM_W5500 and is
rejected on any other type.
| Board | Ethernet controller | LwIP | TOE | Status |
|---|---|---|---|---|
| ESP32 W5500 DevKit (ESP32-S3 + W5500) | W5500 | ✅ | ✅ | Supported |
| WSM-W55E (ESP32-S3 + W5500) | W5500 | — | — | Planned |
| ESP W6300 DevKit (ESP32-S3 + W6300) | W6300 | — | — | Planned |
| WSM-W63E (ESP32-S3 + W6300) | W6300 | — | — | Planned |
In this release, the ESP32 W5500 DevKit (ESP32-S3 + W5500) is the only board
that is supported and hardware-verified, on both the lwip and toe
backends.
The other boards are not supported yet — they are on the roadmap only. See Hardware Roadmap for what each of them still needs.
| ESPHome — target stable requirement | >= 2026.9.0 |
| ESPHome — pre-release validation | 2026.9.0b2 |
| Framework | esp-idf only (no Arduino) |
| ESP-IDF | 6.0.1 for the WSM backends (must be pinned in YAML — ESPHome's default is still 5.5.x) |
| wsm_driver | v1.1.1 (fetched automatically, no manual step) |
| Target | ESP32-S3 |
| Hardware | ESP32 W5500 DevKit (ESP32-S3 + W5500) |
Two different ESPHome versions are named above, and they mean different things:
- Target stable requirement — ESPHome >= 2026.9.0. This is the minimum version the component validates against, and the version to use once 2026.9.0 is released as stable.
- Pre-release validation — ESPHome 2026.9.0b2. This is the exact pre-release build the hardware testing for this release was performed on. Stable 2026.9.0 had not been released at the time of testing, so 2026.9.0b2 is what the verification results below refer to.
type: WSM_W5500 is checked against all of the above at configuration time, so a
wrong platform, variant, framework or IDF version is reported before the build
starts.
Add the repository to your configuration, pinned to a release tag. No download, clone or submodule step is needed — ESPHome fetches it:
external_components:
- source:
type: git
url: https://github.com/Wiznet/wsm-esphome
ref: v0.1.0
components:
- ethernet
- mdns- Always pin
ref:to a release tag (v0.1.0), not tomain.mainmoves, and a moving ref means a device can change behaviour on the next rebuild. ethernetis required. It replaces ESPHome's built-inethernetcomponent (this is how ESPHome's external components work — the whole component is overridden by name).mdnsis required for the TOE backend, where it refuses configurations that would silently fail. Include it in every configuration so that switchingbackend:keeps working without editing anything else.
wsm_driver is not vendored in this repository. When the build sees
type: WSM_W5500, ESPHome adds wsm_driver as an ESP-IDF managed component
pinned to tag v1.1.1, and the ESP-IDF component manager clones it (including
its ioLibrary submodule).
A complete type: WSM_W5500 configuration, on both backends. Everything here
except the pin mapping is board-independent — the YAML is the same on any
ESP32-S3 + W5500 board. The pin mapping below is the ESP32 W5500 DevKit's,
the board this release is verified on; on another board, change those pins and
nothing else.
The SPI wiring used for validation, and used by every example in this repository:
| Signal | GPIO |
|---|---|
| SCLK | GPIO12 |
| MOSI | GPIO11 |
| MISO | GPIO13 |
| CS | GPIO10 |
| INT | GPIO14 |
| RESET | GPIO9 |
with clock_speed: 33MHz and interface: spi2.
These pins are ordinary YAML configuration, not something the component hardcodes. Adapting them to a board's own wiring is exactly what other ESP32-S3 + W5500 boards (such as WSM-W55E) will need — and all they will need.
The recommended configuration. DHCP, DNS, mDNS and Home Assistant discovery all work the way they do on any other ESPHome Ethernet board.
esphome:
name: wsm-w5500-lwip
external_components:
- source:
type: git
url: https://github.com/Wiznet/wsm-esphome
ref: v0.1.0
components:
- ethernet
- mdns
esp32:
board: esp32-s3-devkitc-1
framework:
type: esp-idf
version: 6.0.1 # required by wsm_driver
logger:
ethernet:
type: WSM_W5500
backend: lwip
clk_pin: GPIO12
mosi_pin: GPIO11
miso_pin: GPIO13
cs_pin: GPIO10
interrupt_pin: GPIO14
reset_pin: GPIO9
clock_speed: 33MHz
interface: spi2
api:
ota:
- platform: esphomeReady to build: examples/wsm-w5500-lwip.yaml.
Identical, except for backend: toe and the explicit mdns: disabled: true:
ethernet:
type: WSM_W5500
backend: toe # <-- the only backend difference
clk_pin: GPIO12
mosi_pin: GPIO11
miso_pin: GPIO13
cs_pin: GPIO10
interrupt_pin: GPIO14
reset_pin: GPIO9
clock_speed: 33MHz
interface: spi2
# A fixed address is strongly recommended without mDNS:
# manual_ip:
# static_ip: 192.168.1.50
# gateway: 192.168.1.1
# subnet: 255.255.255.0
# dns1: 168.126.63.1
mdns:
disabled: true # mDNS is not supported on TOE
api:
ota:
- platform: esphomeWithout mDNS the device is reached by IP address:
esphome logs wsm-w5500-toe.yaml --device 192.168.1.50
esphome upload wsm-w5500-toe.yaml --device 192.168.1.50Use a DHCP reservation or manual_ip: so the address does not move — there is
no name-based way to find the device again.
Ready to build: examples/wsm-w5500-toe.yaml.
The component can be installed from the ESPHome Device Builder add-on inside Home Assistant — no local ESPHome CLI needed.
-
Check the add-on version. Settings → Add-ons → ESPHome Device Builder. The add-on must ship ESPHome >= 2026.9.0, the target stable requirement. If it is older, update the add-on first; while 2026.9.0 is still in pre-release the add-on's beta channel may be required — that is the channel carrying 2026.9.0b2, the build this release was validated on.
-
Create the device. Open the add-on → + NEW DEVICE → give it a name → pick ESP32-S3 → SKIP the wireless step (this is an Ethernet device).
-
Edit the YAML. Click EDIT on the new device and paste the
external_components:,esp32:andethernet:blocks from section 5. Two things the wizard does not do for you:- pin the framework —
framework: { type: esp-idf, version: 6.0.1 } - remove any
wifi:block the wizard added.
- pin the framework —
-
First flash over USB. INSTALL → Plug into this computer (or Manual download, then flash with ESPHome Web). The first flash cannot be done over the network.
-
Adopt the device.
backend: lwip— the device is discovered over mDNS, and Home Assistant offers it under Settings → Devices & Services → ESPHome.backend: toe— there is no mDNS, so there is no discovery and no.localhostname to connect to; everything is IP-based. Give the device a stable address before adopting it — either a DHCP reservation on your router ormanual_ip:in the YAML — then add it manually: Settings → Devices & Services → + ADD INTEGRATION → ESPHome → enter the device's IP address and port6053.
-
Later updates are OTA from the add-on's INSTALL button — over the network for LwIP.
For TOE, OTA is also IP-based: the add-on has no name to resolve, so the device must be reachable at the same IP address it was adopted with. If the address changes (a DHCP lease moving, for example), both the Home Assistant integration and OTA stop working until the new address is entered again. A DHCP reservation or
manual_ip:is what keeps the address stable across reboots and firmware updates, so treat it as required rather than optional on TOE.
Builds made by the add-on are subject to the same requirements as the CLI:
ESP-IDF 6.0.1 is pinned from the YAML, and wsm_driver v1.1.1 is fetched during
the first build (so expect that build to take noticeably longer than later ones).
backend: lwip |
backend: toe |
|
|---|---|---|
| TCP/IP stack | ESP-IDF esp_netif + LwIP on the ESP32-S3 |
W5500 hardware TCP/IP (TOE) |
| Sockets | software LwIP sockets | 8 hardware sockets, system-wide ceiling |
| DHCP / Static IP | supported | supported |
| DNS | supported | supported |
| mDNS | supported | not supported |
| Home Assistant | discovery via mDNS, standard hostname resolution | connect by IP address (add the host manually) |
| Hostname-based components | work normally | limited — anything that expects .local name resolution needs an IP instead |
| IPv6 | supported | not supported (IPv4 only) |
| Native API / OTA | supported | supported |
ethernet.disable() |
powers the PHY down | does not physically drop the link (the PHY is not powered down) |
| ESP32 RAM used by the IP stack | LwIP buffers on the ESP32-S3 | offloaded to the W5500 |
Recommendation: use backend: lwip. It is the right default for ESPHome and
Home Assistant users — mDNS discovery, .local addressing and the full ESPHome
component set all behave exactly as on any other Ethernet board.
Choose backend: toe when you specifically want the TCP/IP stack off the
ESP32-S3, and can live with IP-based addressing and the 8-socket budget.
Everything below applies only to backend: toe. backend: lwip runs the
standard ESP-IDF esp_eth + esp_netif + LwIP path and has none of these
limitations.
- mDNS is not supported. Rejected at configuration time — write
mdns: disabled: trueexplicitly. ESP-IDF's mDNS depends onesp_netif, and there is noesp_netifon the TOE data path. - Home Assistant connects by IP address. The device is not discovered; add it
manually (ESPHome integration → IP address, port 6053) and give it a fixed
address via a DHCP reservation or
manual_ip:. - The W5500 has 8 hardware sockets, and there is no software fallback. That is the absolute, system-wide ceiling for TCP clients, TCP listeners and UDP endpoints combined. The configured demand is checked at build time, and the build fails with a breakdown if the total exceeds 8.
ethernet.disable()does not physically drop the PHY link. PHY power-down is not performed on this path: the W5500 is not actually powered down, and the physical link can stay up, so the link partner may still see link. ESPHome reports the interface as down, but do not rely onethernet.disable()to electrically isolate the device from the network.- Some hostname /
.localbased features are limited. The device's own name is not announced, and.localnames do not resolve. Outbound DNS lookups against ordinary hostnames do work. - IPv4 only — use
backend: lwipif you need IPv6. - No
esp_netifand no ESP-IDF network events (IP_EVENT_ETH_GOT_IP,ETHERNET_EVENT_CONNECTED) for third-party code on the data path. ESPHome's ownnetwork::is_connected()and IP reporting work normally.
Full details, including the measured socket baseline:
docs/limitations.md.
Planned, and not supported in this release:
A WIZnet network module combining an ESP32-S3 with a W5500 on one board.
Architecturally identical to the ESP32 W5500 DevKit — the same wsm_driver
W5500 implementation, the same type: WSM_W5500, and both backends.
The main difference is the ESP32-S3 ↔ W5500 GPIO pin mapping, which is fixed by the module's on-board wiring rather than chosen by the user. Support means documenting and validating that pin map on real hardware.
A development board pairing an ESP32-S3 with the W6300. This is a different
Ethernet controller, so it needs its own wsm_driver support and its own
ESPHome ethernet type — not just a pin map change.
The W6300 module counterpart of WSM-W55E: ESP32-S3 + W6300 on one module, with its own fixed on-board pin mapping.
type: WSM_W5500 stays the type name for the wsm_driver W5500 implementation
across all of these — WSM-W55E will use it unchanged. The W6300 boards will get
a separate type when their driver support lands; backend: lwip | toe is
expected to remain the same selector.
| ESPHome | target stable requirement >= 2026.9.0; pre-release validation on 2026.9.0b2 |
| ESP-IDF | 6.0.1, pinned in YAML |
| wsm_driver | v1.1.1 (463abb6), fetched automatically |
| Target | ESP32-S3, esp-idf framework only |
Installing this component does not change any existing behaviour. Because the
whole upstream ethernet component is included unmodified apart from the WSM
additions, type: W5500, DM9051, CH390, ENC28J60, the RMII PHYs and the
RP2040 types all keep working exactly as in upstream ESPHome — with no ESP-IDF
6.0.1 pin and no wsm_driver:
ethernet:
type: W5500
clk_pin: GPIO12
mosi_pin: GPIO11
miso_pin: GPIO13
cs_pin: GPIO10
interrupt_pin: GPIO14
reset_pin: GPIO9See examples/stock-w5500.yaml and
docs/compatibility.md for the full version matrix and
the list of what is validated automatically.
Verified on ESP32 W5500 DevKit (ESP32-S3 + W5500) hardware:
backend: lwip— 19/19 hardware smoke tests passbackend: toe— 22/22 hardware smoke tests pass- stock
type: W5500— compiles unchanged
This repository is a temporary distribution channel. The same code is intended for upstream ESPHome; once merged, no external component will be needed.
| File | What it shows |
|---|---|
examples/wsm-w5500-lwip.yaml |
type: WSM_W5500, backend: lwip — the recommended configuration |
examples/wsm-w5500-toe.yaml |
type: WSM_W5500, backend: toe — with mdns: disabled: true and a manual_ip: template |
examples/stock-w5500.yaml |
stock type: W5500, unchanged upstream behaviour |
All three use the ESP32 W5500 DevKit pin mapping from
section 5 and pin ref: v0.1.0, so they build reproducibly
as they are.
Further documentation:
docs/limitations.md— TOE backend limitations in fulldocs/compatibility.md— supported versions and automatic validation
ESPHome License (GPLv3 for C/C++ sources, MIT for Python and everything else) —
see LICENSE and NOTICE for provenance and third-party
copyrights.