Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

esphome-adeo-mcu

ESPHome external component for the Adeo ceiling fan + light (sold by Leroy Merlin), controlled over UART through its internal Adeo MCU.

Tested on an ESP32-C3. The C++ builds cleanly against the current ESPHome dev branch (the target for upstream contributions).

Features

  • Light: on/off, brightness (1–100 %), color temperature (2700–6500 K)
  • Fan: on/off, 6 speed levels, direction (forward/reverse), Breeze preset mode
  • Bidirectional: state is kept in sync when the unit is operated with its physical remote — the changes are reflected back into Home Assistant

Hardware

The receiver's WiFi dongle is a SK-WVFC-ESP V1.0 board built around an ESP32-C3-MINI-1 module (4 MB flash). Its stock firmware is a Matter firmware (ADEO Enki SDK).

The dongle plugs into the receiver's WIFI-USB port through a USB-A connector, but this is not USB. The manufacturer repurposes the USB-A connector as a plain 4-pin header:

USB-A pin Actual role
VBUS Power — 3.3 V (not 5 V)
D− / D+ (middle two) UART to the MCU (GPIO6 / GPIO7)
GND Ground

⚠️ Never plug the dongle into a computer's USB port. The port's 5 V would destroy the ESP32-C3, whose rail is 3.3 V.

Installation

external_components:
  - source: github://rclsilver/esphome-adeo-mcu
    components: [adeo_mcu]

Usage

uart:
  id: mcu_uart
  tx_pin: GPIO7
  rx_pin: GPIO6
  baud_rate: 115200

adeo_mcu:
  id: adeo
  uart_id: mcu_uart

light:
  - platform: adeo_mcu
    name: "Ceiling Light"
    adeo_mcu_id: adeo
    restore_mode: RESTORE_DEFAULT_OFF

fan:
  - platform: adeo_mcu
    name: "Ceiling Fan"
    adeo_mcu_id: adeo
    restore_mode: RESTORE_DEFAULT_OFF

The UART bus must define both tx_pin and rx_pin (the protocol is bidirectional) and run at 115200 baud.

A complete, ready-to-flash configuration (WiFi, API, OTA, web server, secrets) is available in examples/ceiling-fan.yaml, with a matching examples/secrets.yaml.example.

Configuration variables

adeo_mcu (hub)

  • id (Optional): ID used for code generation, referenced by the light/fan platforms.
  • uart_id (Optional): ID of the UART bus the MCU is connected to.

light / fan platforms

  • name (Required): Name of the entity.
  • adeo_mcu_id (Optional): ID of the parent adeo_mcu hub.
  • All other options from the ESPHome Light and Fan base components.

Flashing the WiFi dongle

The dongle ships with stock Matter firmware, so the first flash has to be done over a wired serial connection.

What you need

  • A 3.3 V USB-to-UART adapter (e.g. CP2102). Make sure its 3V3 pin really outputs 3.3 V.
  • A few female Dupont wires.
  • esptool.py (installed with ESPHome, or pip install esptool).

Programming wiring

The back of the board exposes a header labelled GND · RXD · TXD · IO9 · IO8 · EN · 3.3V.

Wire it to the CP2102 adapter with TX and RX crossed:

Adapter SK-WVFC-ESP board
GND GND
TXD RXD
RXD TXD
3V3 3.3V
+5V do not connect

Entering bootloader mode

The ESP32-C3 enters download mode based on its strapping pins at power-up. On this board EN is tied high (no hardware reset is possible), so follow this exact order:

  1. Adapter unplugged from the PC.
  2. Connect IO9GND (hold).
  3. Connect IO83.3V (hold high).
  4. Double-check the crossed TX/RX wiring above.
  5. Plug the adapter into the PC — powering up in this state is what arms the bootloader.
  6. Once connected, IO9 can be released.

Because the CP2102 has no DTR/RTS lines and EN is fixed high, esptool cannot auto-reset the chip: you must use --before no_reset --after no_reset and set the strapping pins before applying power.

Verify the connection

esptool.py --port /dev/ttyUSB0 --before no_reset --after no_reset chip_id

Expected output: Chip is ESP32-C3 (QFN32), Features: WiFi, BLE, Embedded Flash 4MB. If you get No serial data received, it is almost always because TX/RX are swapped (swap them and retry) or the chip is not in bootloader mode (redo the sequence).

Back up the stock firmware (do this FIRST)

The stock firmware is a Matter firmware (ADEO Enki SDK). Backing it up lets you roll back later (e.g. to re-commission the device in Matter). This backup is irreplaceable once the flash is overwritten.

esptool.py --port /dev/ttyUSB0 -b 460800 read_flash 0x0 0x400000 stock-backup.bin

Check the file is exactly 4194304 bytes (4 MB) and keep it somewhere safe:

ls -l stock-backup.bin

Flash ESPHome

With the chip in bootloader mode, compile and upload over serial:

esphome run your-device.yaml

Pick the serial port (/dev/ttyUSB0) when prompted. If the upload fails on sync, power-cycle the board (toggle 3.3 V with IO9 tied to GND) right before retrying.

Subsequent uploads happen wirelessly over OTA (esphome run finds the device on the network) — no more wiring needed.

After flashing

Disconnect the programming rig and plug the dongle back into the receiver's WIFI-USB port: it gets its 3.3 V power and its UART (GPIO6/GPIO7) reconnects to the MCU. The device boots ESPHome, joins WiFi, and exposes its entities.

Restoring the stock firmware

To restore the Matter firmware (bootloader mode required, as above):

esptool.py --port /dev/ttyUSB0 write_flash 0x0 stock-backup.bin

Protocol

Frames are exchanged over UART at 115200 baud with the following structure:

Byte(s) Description
0x55 Start of frame
0x00 Reserved
2 bytes Frame type (uint16, little-endian)
4 bytes Payload length (uint32, little-endian)
N bytes Payload
1 byte CRC-8 (poly 0x07, init 0x00) over every preceding byte

Payload

Every mapped frame uses a payload of the form [channel][value…]:

  • channel — first payload byte: 0x01 for light frames, 0x02 for fan frames.
  • value — the remaining byte(s), interpreted per frame type below.

Frame types

Type Channel Direction Value (payload byte 1+)
0x0001 0x01 TX/RX Light power (0x01 = on, 0x00 = off)
0x0002 0x01 TX/RX Light brightness (0100)
0x0012 0x01 TX/RX Light color temperature in Kelvin (uint32 LE)
0x0020 0x02 TX/RX Fan power (0x04 = on, 0x00 = off)
0x0021 0x02 TX/RX Fan speed (0100, percent)
0x0023 0x02 TX/RX Fan breeze mode (0x02 = on, 0x00 = off)
0x0024 0x02 TX/RX Fan direction (0x01 = reverse, 0x00 = forward)

For example, turning the light on transmits the payload 01 01, and setting the fan to its reverse direction transmits 02 01.

License

This project follows ESPHome's dual-licensing scheme: the C++/runtime files (.h, .cpp) are under GPLv3, and the Python code and everything else are under the MIT license. See LICENSE.

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages