Bonjour à tous,
Je suis possesseur d’un sèche-serviette hybride ACOVA (à eau avec soufflerie élec) et d’une hotte aspirante Roblin.
La soufflerie et la hotte sont pilotables par IR avec une télécommande fournie propre à chacun.
Il me semble qu’il existe une passerelle propriétaire pour le connecter, mais je ne suis pas trop partisan d’avoir des hub partout.
Voici le github de mon projet : IRverse-Hub-IR-DIY-universel/README.md at main · Quentin90000/IRverse-Hub-IR-DIY-universel · GitHub
Du coup, je me suis lancé un petit défi : Et si je fabriquai moi-même un module pouvant snifer les communications et émettre des demandes le tout intégrable sous HA ?
Maintenant, que le cahier des charges est établi, voilà la liste du matériel nécessaire :
- 1* D1 Mini Pro 16Mb avec antenne externe : Le cerveau de mon projet, il va gérer l’émission IR et alimenté tous mes composants.
- 1 * LED IR « TSAL6400 » : Pour émettre une lumière IR et communiquer avec ma soufflerie IR
- 1 * Résistance 220 Ohms : Montage en série sur l’anode de la LED pour limiter le courant et éviter qu’elle ne grille
- 1* Résistance 10 kOhms : Montage en pull-up avec le TSOP38238
- 1 * Condensateur 100nF céramique : Pour le découplage et filtrer les hautes-fréquences
- 1 * Condensateur 100uF électrolytique : Stabilisation globale de l’alimentation
- 1 * PCB sur mesure pour monter tout ça proprement
- 1 * Module d’alimentation HLK-PM01 : Passer du 230V AC vers du 5V DC
- 2 * Borniers 2P 5.08mm
Un morceau de câble 2G1.5 ou câble USB, presse-étoupe PG9 pour la version alimentation embarqué ou un PG7 pour la version alimentation séparée (pour le boîtier), etc.
Il faudrait également un boîtier en impression 3D pour tout mettre proprement à l’intérieur, mais chaque chose en son temps.
Coût du projet : Tout le matériel a été acheté sur aliexpress, et j’estime le coût du projet à environ 7€ version sans alimentation et 10€ version alimentation.
J’ai déjà fait la sélection du matériel via alibaba (https://www.aliexpress.com/p/wish-manage/share.html?smbPageCode=wishlist-amp&spreadId=825b08d8ee9aa58db2064336b0b6bf776838f56c5a1a1ad3830c99c9f8354210), et dessiné les PCB via Kicad (version shéma et PCB) :
EDIT : J’ai poussé le vice un peu plus loin en fabricant un module pour être raccordé directement au 230V et la version où il faut amener un 5VDC, ça me permet de palier à toutes les situations.
Version alimentation séparée (il faut raccorder un 5VDC environnant avec un USB par exemple) :
Version alimentation embarquée (une arrivée en 230V) :
Après avoir fait les différents tests (ERC et DRC), Kicad ne me remontent aucune erreur.
Ceci est mon premier projet, je me suis aidé de chatGPT pour le choix des composants, mais rien ne vaut des avis techniques, qu’en pensez-vous de ce projet ?
Je ne voulais pas d’un broadlink etc, c’est un challenge pour moi ![]()
S’il faut, je peux partager le fichier Kicad si ça intéresse des personnes.
Voilà le PCB avec alimentation embarqué fabriqué :
Et voilà avec tous les composants soudés :
Voici mon programme avec des codes de ma télécommande IR de ma soufflerie du sèche-serviette ACOVA :
esphome:
name: esp8266-acova-ir
friendly_name: ESP8266-Acova_IR
esp8266:
board: d1_mini_pro
logger:
api:
encryption:
key: "tacléAPI"
ota:
platform: esphome
password: "0a1abb4344477f1f0dd6a6e9c7143608"
wifi:
ssid: "tonssidwifi"
password: "tonmotdepasse"
ap:
ssid: "Esp8266-Acova-Ir"
password: "RD8YW3fHcbNL"
captive_portal:
remote_transmitter:
pin: D5
carrier_duty_percent: 50%
remote_receiver:
pin:
number: D4
inverted: true
dump: all
# --- Scripts pour appuis longs (ON/OFF uniquement) ---
script:
- id: acova_on_long
then:
# Phase 1 : Code ON normal (3 fois)
- repeat:
count: 3
then:
- remote_transmitter.transmit_pronto:
data: "0000 006D 000E 0000 000C 004B 0028 004A 004D 0049 0028 0023 0029 0023 004D 0024 0027 0024 0029 0023 0029 0022 0029 0048 0029 0048 0027 004A 004D 0023 0029 0181"
- delay: 250ms
# Phase 2 : Code "appui maintenu" (4 fois)
- repeat:
count: 4
then:
- remote_transmitter.transmit_pronto:
data: "0000 006D 000E 0000 000C 004B 0029 0024 0027 0049 0028 0024 0027 0024 004E 0049 004F 0049 0028 0022 0027 0025 004D 0049 0027 0049 004E 0049 004E 0023 004F 0181"
- delay: 250ms
# Phase 3 : Code de relâchement (1 fois)
- remote_transmitter.transmit_pronto:
data: "0000 006D 000E 0000 000C 004B 0028 004A 004C 004A 0027 0024 0029 0023 004C 0025 0027 0024 0028 0024 0027 0024 0028 0049 0027 004A 0028 0049 004D 0023 0028 0181"
- id: acova_off_long
then:
# Phase 1 : Code OFF normal (3 fois)
- repeat:
count: 3
then:
- remote_transmitter.transmit_pronto:
data: "0000 006D 000E 0000 000C 004B 0029 0049 004D 0024 0027 0024 0028 0024 0027 0023 0027 0025 0027 0023 0027 0025 0027 004A 004D 0023 0029 0023 0027 0023 0028 0181"
- delay: 250ms
# Phase 2 : Code "appui maintenu" (4 fois)
- repeat:
count: 4
then:
- remote_transmitter.transmit_pronto:
data: "0000 006D 000E 0000 000C 004B 0028 0025 0027 0023 0028 0024 0028 0023 0027 004A 004D 004A 0028 0024 0027 0023 004E 0049 004E 0023 004D 0025 0027 0023 004F 0181"
- delay: 250ms
# Phase 3 : Code de relâchement (1 fois)
- remote_transmitter.transmit_pronto:
data: "0000 006D 000E 0000 000C 004B 0028 004A 004D 0025 0027 0023 0027 0025 0027 0023 0028 0024 0028 0023 0029 0023 0027 004A 004D 0023 0029 0023 0027 0024 0028 0181"
# --- Tous les switches ---
switch:
# Boost ON/OFF - Séquence complète automatique
- platform: template
name: "Acova BOOST ON"
turn_on_action:
- repeat:
count: 3
then:
- remote_transmitter.transmit_pronto:
data: "0000 006D 000E 0000 000C 004C 0028 0025 004C 004A 0026 0024 0026 0026 004C 0024 0027 0024 004F 0048 004D 004A 0026 004B 0026 004B 004C 0024 0027 0024 0027 0181"
- delay: 250ms
- repeat:
count: 4
then:
- remote_transmitter.transmit_pronto:
data: "0000 006D 000E 0000 000C 004C 0027 0026 0027 0049 0028 0024 0026 0025 004D 004B 004C 004A 0027 0024 0027 0025 004B 004B 0026 004A 004D 004B 004B 0024 004D 0181"
- delay: 250ms
- remote_transmitter.transmit_pronto:
data: "0000 006D 000E 0000 000C 004C 0028 0025 004C 004B 0026 0025 0028 0024 004B 0025 0027 0024 004D 004A 004D 004A 0026 004B 0027 004A 004C 0024 0028 0024 0026 0181"
- platform: template
name: "Acova BOOST OFF"
turn_on_action:
- repeat:
count: 3
then:
- remote_transmitter.transmit_pronto:
data: "0000 006D 000E 0000 000C 004C 0027 004B 004C 004A 0026 0025 0027 0024 004C 0026 0027 0024 0027 0024 0026 0024 0027 004A 0026 004B 0026 004B 004C 0024 0027 0181"
- delay: 250ms
- repeat:
count: 4
then:
- remote_transmitter.transmit_pronto:
data: "0000 006D 000E 0000 000A 004D 0027 0026 0026 004A 0027 0025 0026 0025 004D 004B 004B 004B 0026 0024 0028 0024 004C 004A 0026 004A 004D 004C 004A 0025 004D 0181"
- delay: 250ms
- remote_transmitter.transmit_pronto:
data: "0000 006D 000E 0000 000C 004C 0027 004B 004B 004C 0025 0025 0027 0024 004C 0026 0026 0025 0027 0025 0026 0025 0027 004A 0026 004B 0026 004B 004B 0026 0026 0181"
# Timer Boost +/- (ajout/retrait de 15 minutes) - Séquence complète
- platform: template
name: "Acova BOOST + (timer)"
turn_on_action:
- repeat:
count: 3
then:
- remote_transmitter.transmit_pronto:
data: "0000 006D 000E 0000 000C 004C 0027 0026 004C 004A 0027 0024 0026 0026 004B 0024 0028 0049 0027 004A 004F 0023 004C 004B 0026 0025 0027 0024 0026 004B 004C 0181"
- delay: 250ms
- repeat:
count: 4
then:
- remote_transmitter.transmit_pronto:
data: "0000 006D 000E 0000 000C 004B 0028 0025 0026 004A 0027 0025 0026 0025 004D 004A 004D 004C 0025 0025 0026 0026 004B 004B 0026 004A 004D 004B 004B 0026 004C 0181"
- delay: 250ms
- remote_transmitter.transmit_pronto:
data: "0000 006D 000E 0000 000C 004C 0027 0026 004B 004B 0026 0025 0026 0026 004C 0024 0027 004B 0026 004A 004D 0025 004B 004B 0026 0025 0027 0025 0026 004B 004B 0181"
- platform: template
name: "Acova BOOST - (timer)"
turn_on_action:
- repeat:
count: 3
then:
- remote_transmitter.transmit_pronto:
data: "0000 006D 000E 0000 000C 004C 0027 0026 004B 004B 0026 0024 0026 0026 004C 0024 0027 0025 004D 004A 004E 0049 0026 004B 0026 004B 004B 0025 0027 0025 0026 0181"
- delay: 250ms
- repeat:
count: 4
then:
- remote_transmitter.transmit_pronto:
data: "0000 006D 000E 0000 000C 004B 0027 0026 0027 0049 0027 0025 0026 0025 004D 004A 004D 004B 0027 0024 0026 0026 004B 004B 0026 004A 004E 004A 004C 0025 004D 0181"
- delay: 250ms
- remote_transmitter.transmit_pronto:
data: "0000 006D 000E 0000 000C 004C 0028 0025 004C 004B 0027 0024 0026 0027 004A 0024 0029 0023 004D 004A 004D 004A 0026 004B 0026 004B 004B 0026 0026 0024 0026 0181"
# ON/OFF avec appui long (3 secondes)
- platform: template
name: "Acova ON - appui long 3s"
turn_on_action:
- script.execute: acova_on_long
- platform: template
name: "Acova OFF - appui long 3s"
turn_on_action:
- script.execute: acova_off_long
Sa carte de fonctionnement accompagnée de son code :
type: vertical-stack
cards:
# Header Card
- type: custom:mushroom-title-card
title: Radiateur Acova
subtitle: Contrôle infrarouge
# Boutons ON/OFF et BOOST
- type: horizontal-stack
cards:
- type: custom:mushroom-template-card
primary: ''
secondary: ON
icon: mdi:power
icon_color: green
layout: vertical
tap_action:
action: call-service
service: switch.turn_on
target:
entity_id: switch.acova_on_appui_long_3s
card_mod:
style: |
ha-card {
background: rgba(76, 175, 80, 0.1);
border: 1px solid rgba(76, 175, 80, 0.3);
}
- type: custom:mushroom-template-card
primary: ''
secondary: OFF
icon: mdi:power-off
icon_color: red
layout: vertical
tap_action:
action: call-service
service: switch.turn_on
target:
entity_id: switch.acova_off_appui_long_3s
card_mod:
style: |
ha-card {
background: rgba(244, 67, 54, 0.1);
border: 1px solid rgba(244, 67, 54, 0.3);
}
- type: custom:mushroom-template-card
primary: ''
secondary: Boost ON
icon: mdi:lightning-bolt
icon_color: orange
layout: vertical
tap_action:
action: call-service
service: switch.turn_on
target:
entity_id: switch.acova_boost_on
card_mod:
style: |
ha-card {
background: rgba(255, 152, 0, 0.1);
border: 1px solid rgba(255, 152, 0, 0.3);
}
- type: custom:mushroom-template-card
primary: ''
secondary: Boost OFF
icon: mdi:lightning-bolt-outline
icon_color: grey
layout: vertical
tap_action:
action: call-service
service: switch.turn_on
target:
entity_id: switch.acova_boost_off
card_mod:
style: |
ha-card {
background: rgba(158, 158, 158, 0.1);
border: 1px solid rgba(158, 158, 158, 0.3);
}
- type: custom:mushroom-template-card
primary: ''
secondary: Timer +
icon: mdi:plus-circle
icon_color: blue
layout: vertical
tap_action:
action: call-service
service: switch.turn_on
target:
entity_id: switch.acova_boost_timer
card_mod:
style: |
ha-card {
background: rgba(33, 150, 243, 0.1);
border: 1px solid rgba(33, 150, 243, 0.3);
}
- type: custom:mushroom-template-card
primary: ''
secondary: Timer -
icon: mdi:minus-circle
icon_color: purple
layout: vertical
tap_action:
action: call-service
service: switch.turn_on
target:
entity_id: switch.acova_boost_timer_2
card_mod:
style: |
ha-card {
background: rgba(156, 39, 176, 0.1);
border: 1px solid rgba(156, 39, 176, 0.3);
}
Programme fonctionnel de ma hotte aspirante Roblin Aqua avec tous les codes, si ça peut aider :
esphome:
name: esp8266-roblin-ir
friendly_name: ESP8266-Roblin_IR
esp8266:
board: d1_mini_pro
logger:
api:
encryption:
key: "tacléapi"
ota:
platform: esphome
password: "0a1abb4344477f1f0dd6a6e9c7143608"
wifi:
ssid: "tonwifi"
password: "tonmotdepasse"
ap:
ssid: "Esp8266-Roblin-Ir"
password: "cvi91SvuVJfn"
captive_portal:
remote_transmitter:
id: my_remote
pin: D5
carrier_duty_percent: 50%
# --- Récepteur IR pour sniffer ---
remote_receiver:
pin:
number: D4
inverted: true
dump: all
# --- Scripts pour appuis longs ---
script:
- id: lumiere_min
then:
- delay: 3s
- remote_transmitter.transmit_pronto:
data: "0000 006D 000B 0000 0021 001A 001E 001A 001E 0019 003C 0034 001E 001A 001F 0019 001F 0019 001F 0019 001E 001B 001E 001A 001D 0181"
- id: mode_24h_on
then:
- delay: 3s
- remote_transmitter.transmit_pronto:
data: "0000 006D 0009 0000 003E 0035 001E 0019 003B 0019 001E 0034 001F 001A 001E 001A 003B 0034 001F 001A 001E 0181"
- id: mode_24h_off
then:
- delay: 3s
- remote_transmitter.transmit_pronto:
data: "0000 006D 0009 0000 003D 0034 001F 0019 003C 0019 001F 0034 001F 0019 001E 001A 003C 0035 001E 0019 001F 0181"
# --- Tous les boutons ---
button:
# Lumière
- platform: template
name: "Lumière ON (max)"
on_press:
- remote_transmitter.transmit_pronto:
data: "0000 006D 0009 0000 0021 0018 001F 0018 003C 0034 001E 001A 001E 001A 003B 006A 001E 001A 001E 001A 0057 0181"
- platform: template
name: "Lumière ON (min) - appui long"
on_press:
- script.execute: lumiere_min
- platform: template
name: "Lumière OFF"
on_press:
- remote_transmitter.transmit_pronto:
data: "0000 006D 0009 0000 0021 0018 001F 0018 003C 0034 001E 001A 001E 001A 003A 006A 001E 001A 001E 001A 0057 0181"
# Hotte
- platform: template
name: "Hotte ON"
on_press:
- remote_transmitter.transmit_pronto:
data: "0000 006D 0009 0000 0021 0018 001F 0033 003C 001A 001E 001A 001E 0035 003B 004F 001E 0034 001E 001A 003B 0181"
- platform: template
name: "Hotte OFF"
on_press:
- remote_transmitter.transmit_pronto:
data: "0000 006D 0009 0000 0021 0019 001F 0034 003C 0019 001F 0019 001F 0034 003B 004E 001F 0033 001F 001A 003B 0181"
# Aspiration
- platform: template
name: "Aspiration +1"
on_press:
- remote_transmitter.transmit_pronto:
data: "0000 006D 0008 0000 0021 0018 0059 0019 001E 001A 001E 001A 0057 001A 001E 004F 0057 0034 003B 0181"
- platform: template
name: "Aspiration -1"
on_press:
- remote_transmitter.transmit_pronto:
data: "0000 006D 0008 0000 0021 0033 003C 0018 001F 0019 001E 0035 003B 001A 001E 006A 003B 0034 003B 0181"
# Boost
- platform: template
name: "Boost ON"
on_press:
- remote_transmitter.transmit_pronto:
data: "0000 006D 0008 0000 0021 0018 003C 0033 001F 001A 001E 001A 003B 0035 001E 004F 003B 004F 003B 0181"
- platform: template
name: "Boost OFF"
on_press:
- remote_transmitter.transmit_pronto:
data: "0000 006D 0008 0000 0021 0019 003C 0033 001F 001A 001E 001A 003B 0034 001E 004F 003B 004F 003B 0181"
# Arrêt différé
- platform: template
name: "Arrêt différé ON"
on_press:
- remote_transmitter.transmit_pronto:
data: "0000 006D 0006 0000 0020 0034 003B 0034 001E 004F 003C 004F 001D 0034 003B 0181"
- platform: template
name: "Arrêt différé OFF"
on_press:
- remote_transmitter.transmit_pronto:
data: "0000 006D 0006 0000 0021 0034 003B 0034 001F 004E 003B 004E 001E 0034 003C 0181"
# Mode 24H
- platform: template
name: "Mode 24H ON - appui long"
on_press:
- script.execute: mode_24h_on
- platform: template
name: "Mode 24H OFF - appui long"
on_press:
- script.execute: mode_24h_off
# Réserve / Inconnu
- platform: template
name: "Réserve / Inconnu"
on_press:
- remote_transmitter.transmit_pronto:
data: "0000 006D 0009 0000 0021 0018 001F 0033 001F 0018 001F 0034 001E 0034 001E 0034 001E 001A 001E 0034 001E 0181"
Pour terminer, j’utilise une antenne externe donc il faut bien penser à déplacer la résistance “0 Ohms” de 90 degrés mais uniquement à la toute fin de votre montage car en cas d’erreur, si vous devez faire un erase de la mémoire flash de votre wemos, il n’arrivera pas à se connecter au wifi pour repartir (du moins c’était mon cas). ![]()
















