Contrôler des volets Dooya RF433 avec un ESP32 + CC1101 via ESPHome

[Tuto] Contrôler des volets Dooya RF433 avec un ESP32 + CC1101 via ESPHome

Introduction

Salut à tous !

Je partage ici mon retour d’expérience sur le contrôle de volets roulants Dooya (moteurs RF433 MHz) depuis Home Assistant, en utilisant un ESP32 et un module CC1101 sous ESPHome.

Les volets Dooya (et rebrands type Zemismart, AM43, etc.) utilisent des télécommandes RF 433 MHz avec un protocole propriétaire. L’idée : remplacer toutes les télécommandes DC90 par un seul ESP32 qui émet les mêmes codes RF.

Résultat : 8 volets contrôlés depuis HA, sans cloud, sans hub propriétaire, pour ~10€ de matériel.


Matériel nécessaire

Composant Prix approximatif Lien
ESP32 DevKit V1 (ou clone) ~4€ AliExpress
Module CC1101 433MHz (vert E07, 8 pins) ~3€ AliExpress
Fils Dupont femelle-femelle ~2€ AliExpress
Câble micro-USB + chargeur 5V déjà dispo -

Total : ~10€

Optionnel pour l’installation finale

  • Boîtier plastique (~83x58x33mm)
  • Presse-étoupe PG7 (passage câble USB)
  • Adhésif double-face 3M 9448A (fixation dans le boîtier)

Câblage ESP32 + CC1101

Identifier votre module CC1101

:warning: La couleur du PCB n’est pas un indicateur fiable — certains modules bleus ont le pinout du vert et inversement, selon le fabricant. La seule façon fiable de distinguer les deux versions est de regarder directement la broche n°2 de ton module :
Broche n°2 = VCC → utilise le câblage « Module VERT (E07) »
Broche n°2 = GND → utilise le câblage « Module BLEU (Standard) »

Pinout A — Broche 2 = VCC (souvent E07 vert, mais pas toujours)

Pin CC1101 Nom ESP32 GPIO Fonction
1 GND GND Masse
2 VCC 3V3 Alimentation 3.3V
3 GDO0 GPIO 4 RX/TX (données RF)
4 CSN GPIO 5 SPI Chip Select
5 SCK GPIO 18 SPI Clock
6 MOSI GPIO 23 SPI MOSI
7 MISO GPIO 19 SPI MISO
8 GDO2 (non utilisé) -

Pinout B — Broche 2 = GND

Pin CC1101 Nom ESP32 GPIO Fonction
1 VCC 3V3 Alimentation
2 GND GND Masse
3 MOSI GPIO 23 SPI MOSI
4 SCLK GPIO 18 SPI Clock
5 MISO GPIO 19 SPI MISO
6 GDO2 (non utilisé) -
7 GDO0 GPIO 4 RX/TX
8 CSN GPIO 5 SPI Chip Select

:warning: Attention : le CC1101 fonctionne en 3.3V uniquement. Ne le branchez pas en 5V sous peine de le griller.


Étape 1 : Sniffer les codes de vos télécommandes

Avant de pouvoir émettre, il faut capturer les codes RF de chaque télécommande Dooya. Chaque télécommande a un ID unique (24 bits) qui est appairé au moteur du volet.

Config ESPHome RX (sniffer)

:warning: Point crucial : la réception ne fonctionne que si le remote_receiver est utilisé seul, sans remote_transmitter dans la même config. C’est une limitation du partage du GPIO4 entre RX et TX.

substitutions:
  device_name: esp32-rf433-sniffer
  friendly_name: "Sniffer RF433"

esphome:
  name: ${device_name}
  friendly_name: ${friendly_name}
  on_boot:
    priority: -100
    then:
      - lambda: id(mycc1101).recv();

esp32:
  board: esp32dev
  framework:
    type: esp-idf

external_components:
  - source: github://juanboro/esphome-radiolib-cc1101@main
    components: [ radiolib_cc1101 ]

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  power_save_mode: none
  fast_connect: true
  ap:
    ssid: "${device_name}-fallback"
    password: "12345678"

captive_portal:

logger:
  level: DEBUG

api:

ota:
  - platform: esphome
    password: "1234"

web_server:
  port: 80

spi:
  id: spi_bus
  type: single
  clk_pin: GPIO18
  mosi_pin: GPIO23
  miso_pin: GPIO19

radiolib_cc1101:
  id: mycc1101
  cs_pin: 5
  rx_pin:
    number: 4
    allow_other_uses: true
  frequency: 433.9205
  filter: 468khz
  bitrate: 5

# Récepteur SEUL - PAS de remote_transmitter !
remote_receiver:
  id: rf_receiver
  pin:
    number: 4
    allow_other_uses: true
  dump: all

Comment sniffer

  1. Flashez cette config sur l’ESP32
  2. Ouvrez les logs ESPHome (via le dashboard ou esphome logs)
  3. Appuyez sur un bouton de votre télécommande DC90 (Monter, Stop ou Descendre)
  4. Cherchez dans les logs une ligne du type :
Received Dooya: id=0x00D1C917, channel=5, button=1, check=1
  1. Notez les valeurs id, channel, button et check pour chaque bouton
  2. Répétez pour chaque télécommande

Protocole Dooya

  • id : 24 bits, unique par télécommande (appairé au moteur)
  • channel : canal (généralement 5 pour une télécommande mono-canal)
  • button : 1 = Monter, 3 = Descendre, 5 = Stop
  • check : généralement égal à button

Étape 2 : Configurer l’émission TX

Une fois tous les codes capturés, on passe à la config TX. On retire le remote_receiver et on met un remote_transmitter à la place.

Config ESPHome TX

substitutions:
  device_name: esp32-volets-rf433
  friendly_name: "Volets Dooya RF433"

esphome:
  name: ${device_name}
  friendly_name: ${friendly_name}

esp32:
  board: esp32dev
  framework:
    type: esp-idf

external_components:
  - source: github://juanboro/esphome-radiolib-cc1101@main
    components: [ radiolib_cc1101 ]

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  power_save_mode: none
  fast_connect: true
  ap:
    ssid: "${device_name}-fallback"
    password: "12345678"

captive_portal:

logger:
  level: DEBUG

api:

ota:
  - platform: esphome
    password: "1234"

web_server:
  port: 80

# Configuration SPI pour CC1101
spi:
  id: spi_bus
  type: single
  clk_pin: GPIO18
  mosi_pin: GPIO23
  miso_pin: GPIO19

# RadioLib CC1101 - paramètres Dooya
radiolib_cc1101:
  id: mycc1101
  cs_pin: 5
  rx_pin:
    number: 4
    allow_other_uses: true
  frequency: 433.9205
  filter: 468khz
  bitrate: 5

# Émetteur RF sur GDO0 (GPIO4)
remote_transmitter:
  - id: rf_transmitter
    pin:
      number: 4
      allow_other_uses: true
    carrier_duty_percent: 100%
    non_blocking: false
    on_transmit:
      then:
        - lambda: id(mycc1101).xmit();
    on_complete:
      then:
        - lambda: id(mycc1101).recv();

# === Boutons par volet ===
# Dupliquez ce bloc pour chaque volet en changeant le nom et l'ID
button:
  # --- Volet Salon ---
  - platform: template
    name: "Volet Salon - Monter"
    id: volet_salon_up
    icon: "mdi:arrow-up-bold-box"
    on_press:
      - remote_transmitter.transmit_dooya:
          transmitter_id: rf_transmitter
          id: 0x00D1C917        # <-- Remplacez par l'ID de votre télécommande
          channel: 5
          button: 1
          check: 1
          repeat: { times: 5, wait_time: 1ms }

  - platform: template
    name: "Volet Salon - Stop"
    id: volet_salon_stop
    icon: "mdi:stop-circle"
    on_press:
      - remote_transmitter.transmit_dooya:
          transmitter_id: rf_transmitter
          id: 0x00D1C917
          channel: 5
          button: 5
          check: 5
          repeat: { times: 5, wait_time: 1ms }

  - platform: template
    name: "Volet Salon - Descendre"
    id: volet_salon_down
    icon: "mdi:arrow-down-bold-box"
    on_press:
      - remote_transmitter.transmit_dooya:
          transmitter_id: rf_transmitter
          id: 0x00D1C917
          channel: 5
          button: 3
          check: 3
          repeat: { times: 5, wait_time: 1ms }

Points importants

  • Le repeat: { times: 5, wait_time: 1ms } envoie le code 5 fois pour fiabiliser la réception par le moteur
  • Les lambdas on_transmit / on_complete basculent le CC1101 entre mode TX et mode idle — c’est indispensable
  • Framework ESP-IDF obligatoire : le framework Arduino ne fonctionne pas correctement pour le TX avec le CC1101

Étape 3 : Intégration Home Assistant

Les boutons apparaissent automatiquement dans HA via l’intégration ESPHome. Vous aurez 3 boutons par volet : Monter, Stop, Descendre.

Créer une entité Cover (optionnel)

Pour avoir une vraie entité volet dans HA avec les boutons haut/bas/stop, vous pouvez créer un template cover dans votre configuration.yaml :

cover:
  - platform: template
    covers:
      volet_salon:
        device_class: shutter
        friendly_name: "Volet Salon"
        open_cover:
          - action: button.press
            target:
              entity_id: button.volet_salon_monter
        close_cover:
          - action: button.press
            target:
              entity_id: button.volet_salon_descendre
        stop_cover:
          - action: button.press
            target:
              entity_id: button.volet_salon_stop

Note : sans retour d’état RF, la position du volet n’est pas connue. Le cover sera toujours en état « inconnu » mais les commandes fonctionnent.


Mise en boîtier (installation finale)

Une fois que tout fonctionne sur le breadboard :

  1. Souder les fils Dupont directement sur les pins de l’ESP32 (côté composants)
  2. Couper les pins qui dépassent au verso à la pince coupante (ou les plier si vous voulez garder l’option breadboard)
  3. Fixer l’ESP32 et le CC1101 dans le boîtier avec du double-face 3M 9448A
  4. Percer un trou pour le câble USB (presse-étoupe PG7 = propre et solide)
  5. L’antenne du CC1101 peut rester à l’intérieur si le boîtier est en plastique (le signal RF passe à travers)

Placement

Placez le boîtier de façon centrale par rapport à vos volets pour une portée optimale. Le CC1101 a une portée de ~30-50m en intérieur, largement suffisant pour une maison.


Pièges et astuces

:cross_mark: RX + TX ensemble = ça ne marche pas

Le remote_receiver et le remote_transmitter partagent le même GPIO4. Quand les deux sont dans la même config, la réception ne fonctionne plus, même quand on n’émet pas. Solution : deux fichiers YAML séparés, un pour sniffer, un pour émettre.

:cross_mark: Framework Arduino = TX instable

Avec le framework Arduino, le TX se bloque après quelques émissions. Passez en ESP-IDF, c’est la seule config stable.

:white_check_mark: Fréquence Dooya = 433.9205 MHz

Ce n’est PAS du 433.92 standard. La fréquence exacte est 433.9205 MHz. Si vos volets ne répondent pas, vérifiez ce paramètre.

:white_check_mark: allow_other_uses: true obligatoire

Le GPIO4 est utilisé à la fois par radiolib_cc1101 (rx_pin) et par remote_transmitter (pin). Il faut ajouter allow_other_uses: true sur les deux déclarations, sinon ESPHome refuse de compiler.

:white_check_mark: Le repeat est important

Les moteurs Dooya ont besoin de recevoir le code plusieurs fois pour réagir. repeat: { times: 5 } est un bon compromis fiabilité/vitesse.


Composant externe utilisé

  • esphome-radiolib-cc1101 par juanboro
  • Basé sur la librairie RadioLib, permet d’utiliser le CC1101 en mode OOK direct avec ESPHome
  • Le protocole Dooya est nativement supporté par ESPHome (remote_transmitter.transmit_dooya)

Conclusion

Ça fonctionne parfaitement pour mon installation de 8 volets Dooya. Le CC1101 est bien plus fiable qu’un simple émetteur 433 MHz car il permet de régler précisément la fréquence (433.9205 MHz vs 433.92 générique).

Le coût total est ridicule (~10€) comparé aux solutions Zigbee/WiFi propriétaires, et tout reste 100% local via Home Assistant.

Si vous avez des questions, n’hésitez pas ! :slightly_smiling_face:


Testé avec : ESPHome 2025.x / ESP-IDF 5.x / ESP32 DevKit v1 / CC1101 E07 vert / Home Assistant 2025.x+

4 « J'aime »

C’est top, bravo.
Je suis un amoureux du CC1101 aussi, super module, qui ne vaut presque rien pour le service qu’il rend !

1 « J'aime »

Salut,

@David_Simon

Super cela fonctionne à merveille.

Petit précision j’ai un module BLEU avec pinout du VERT, attention erreur dans la doc ou autre ?
Mon module acheté chez Amazon.

Fred

Salut Fred55 !

Pas d’erreur dans la doc, c’est juste que les fabricants sont… créatifs :grinning_face_with_smiling_eyes:

La couleur du PCB n’est malheureusement pas un indicateur fiable — certains modules bleus ont le pinout du vert et vice versa, surtout ceux vendus sur Amazon où les sources sont variées.

La vraie règle c’est de regarder directement sur ton module :
:backhand_index_pointing_right: Broche n°2 = VCC → utilise le câblage « vert »
:backhand_index_pointing_right: Broche n°2 = GND → utilise le câblage « bleu »

Puisque ça fonctionne chez toi avec le câblage vert, c’est que ton module bleu a bien le pinout vert. L’essentiel c’est que les volets répondent !

Je vais mettre à jour le tuto pour préciser que la couleur n’est pas fiable et qu’il faut toujours vérifier la broche n°2. Merci du retour, c’est exactement ce genre de précision qui aide les suivants :raising_hands:

1 « J'aime »

Ce sujet a été automatiquement fermé après 2 jours. Aucune réponse n’est permise dorénavant.