00 — l'essentiel
Ce qu'on obtient au final
L'enceinte est vendue avec une entrée Bluetooth, une optique et une HDMI ARC, mais aucune API. Après reverse, un petit ESP32-C3 caché à l'intérieur expose tout dans Home Assistant : le contrôle complet et — c'est la vraie valeur ajoutée — le retour d'état réel, chose qu'un simple émetteur infrarouge « à l'aveugle » ne donne jamais.
- Contrôle
- power · sources · vol · mute · lecture
- État lu
- source · volume · mute · appareil BT
- Câblage
- 2 fils + masse + alim
- Télécommande
- toujours fonctionnelle
01 — ouvrir
Trouver par où parler à l'enceinte
À l'ouverture, la carte principale porte la référence TX600BJ-MBS06789 et un SoC audio Bluetooth Mvsilicon BP1048B1. Sur le cuivre, la sérigraphie ne ment pas : un pad TXD traîne près du contrôleur, avec des masses partout (AGND, LGND, blindage optique).
Un coup de multimètre confirme la piste : TXD repose à 3,30 V au repos — la signature d'une ligne UART émettrice en logique 3,3 V. On soude un fil, masse commune, et on écoute. Écouter ne casse rien : c'est une entrée sur notre adaptateur, une rue à sens unique.
02 — écouter
L'enceinte se raconte à voix haute
Un scan de débits trouve la bonne vitesse : 460800 bauds, 8N1. Et là, jackpot — ce n'est pas un bus muet, c'est un journal de debug bavard. Le firmware commente chacun de ses gestes en clair :
A2dp Connected : bt address = 7d:d7:3d:xx:xx:xx
name = iPhone du salon
SysCurrentMode = OpticalPlay
APP_SOURCE_NUM vol = 12
Mute Digital / Demute Digital
En parsant ces lignes, l'ESP reconstruit tout l'état en temps réel : la source active (SysCurrentMode), le volume numérique exact, le mute, l'appareil Bluetooth connecté et son nom. Voilà l'atout qu'aucun blaster IR ne peut offrir : savoir où en est vraiment l'enceinte.
03 — décoder
La télécommande, entièrement cartographiée
Le même journal logge chaque touche infrarouge reçue : IrKeyVal = 619ea129. C'est de l'infrarouge NEC, adresse constante 0xA129. En pressant chaque bouton, on relève la table complète — power, volume, mute, les trois sources en codes directs (un par entrée, pas de bascule à l'aveugle), la lecture, et cinq presets d'égaliseur.
| Fonction | IrKeyVal loggé | address | command |
|---|---|---|---|
| Power | 807fa129 | 0xA129 | 0x807F |
| Volume + | 619ea129 | 0xA129 | 0x619E |
| Volume − | 609fa129 | 0xA129 | 0x609F |
| Mute | 649ba129 | 0xA129 | 0x649B |
| Source Bluetooth | 32cda129 | 0xA129 | 0x32CD |
| Source Optique | 57a8a129 | 0xA129 | 0x57A8 |
| Source HDMI ARC | 56a9a129 | 0xA129 | 0x56A9 |
| Play / Pause | 659aa129 | 0xA129 | 0x659A |
| Suivant / Préc. | 629d· / 639c· | 0xA129 | 0x629D / 0x639C |
Détail qui a son importance pour la suite : la règle du command = la moitié haute de l'IrKeyVal imprimé, l'adresse étant la moitié basse. On y revient — c'est là que tout s'est joué.
04 — le piège
Le piège d'encodage qui bloque tout le monde
Émettre les codes semble trivial — et pourtant, avec l'encodage « intuitif », l'enceinte ignore chaque trame. Deux fausses pistes très convaincantes détournent l'attention du vrai problème ; autant les baliser pour t'épargner le détour.
Fausse piste électrique. La sortie du récepteur IR est push-pull (~30 Ω) et « tient » la ligne : on croit alors devoir isoler le récepteur au prix de la télécommande. Fausse piste matérielle. Récepteur débranché, l'ESP « seul maître » ne fait toujours rien, et une capture au vol — un « blob » de 3 ms au lieu d'un leader NEC de 9 ms — fait accuser le périphérique RMT de l'ESP32-C3. Les deux sont des impasses : ni l'électronique ni le silicium ne sont en cause.
Ce qu'on écarte à tort avant de trouver
- ✗Débit / codes — l'état se lit parfaitement, les codes correspondent à la télécommande.
- ✗Porteuse 38 kHz résiduelle — écartée (carrier_duty 100%).
- ✗Niveau logique / câblage — 0 Ω vers un signal propre, le FTDI décode la télécommande.
- ✗Repos collé en bas — non, le GPIO au repos est à 3,28 V.
Toutes ces pistes sont vraies mais hors sujet. Le vrai bug tient en trois mots : l'ordre des octets.
05 — l'oracle
Faire dire à l'enceinte ce qu'elle a compris
La méthode fiable : le firmware imprime IrKeyVal = … pour chaque trame NEC qu'il décode — la sienne comme la nôtre. Or on lit déjà cet UART ! Il suffit de republier cette ligne dans un capteur. L'enceinte devient alors un oracle : elle dit exactement ce qu'elle reçoit, et transforme chaque essai en verdict.
Une trame NEC transporte [adresse][commande][~commande]. ESPHome prend address et command en 16 bits — mais on ne savait pas dans quel sens le SDK Mvsilicon assemble ses 32 bits. Piège diabolique : un mauvais ordre reste une trame NEC parfaitement valide (le contrôle cmd ^ ~cmd passe), mais avec la commande au mauvais endroit → rejetée en silence. Quatre combinaisons possibles, une seule testée. On les a toutes tirées, l'oracle en surveillance :
H0 — l'encodage intuitif
command: 0x9E61
l'enceinte décode ↓
IrKeyVal = 9e61a129
Reçue — mais commande inversée, donc ignorée. Le signal partait bien ; c'est la sémantique qui clochait.
H1 — octets dans l'autre sens
command: 0x619E
l'enceinte décode ↓
IrKeyVal = 619ea129
Code exact de la télécommande — et le volume monte 9 → 10 → 11 → 12. ✔
La règle, une fois pour toutes
address = moitié basse de l'IrKeyVal (0xA129), command = moitié haute (vol+ → 0x619E). Le RMT de l'ESP32-C3 n'a jamais été en cause ; l'injection passe même récepteur branché, sans diode — donc la télécommande d'origine reste vivante.
06 — ça marche
Le montage final
Un ESP32-C3 alimenté par le rail 3,3 V de l'enceinte (maintenu même en veille, donc l'ESP peut la réveiller). Deux signaux, une masse, quelques lignes de YAML :
uart:
rx_pin: GPIO1
baud_rate: 460800
remote_transmitter:
pin: { number: GPIO4, inverted: true, mode: { output: true } }
carrier_duty_percent: 100%
# Volume +
transmit_nec: { address: 0xA129, command: 0x619E }
Résultat : contrôle complet et retour d'état dans Home Assistant, avec un bonus — le capteur oracle remonte aussi les appuis de la vraie télécommande, de quoi bâtir des automatisations (« touche power pressée → allumer l'ampli »).
07 — la config
La configuration ESPHome complète
À copier-coller dans ESPHome — ajoute simplement tes secrets (api_key, wifi_ssid, wifi_password), flashe une première fois en USB puis en OTA. Tout est là : lecture d'état, dix boutons de contrôle, et le capteur oracle qui remonte aussi les appuis de la vraie télécommande.
08 — à emporter