ESPHome è il pezzo che rende l’ESP32 accessibile a chi non programma. L’idea è tutta qui: tu descrivi in un file YAML cosa deve fare il chip (“c’è un BME280 sul bus I²C, leggilo ogni minuto”), ESPHome traduce quella descrizione in codice C++, lo compila con il toolchain di Espressif e ti restituisce un file binario da caricare sul chip. Il device si accende, si connette al Wi-Fi, e Home Assistant lo trova da solo.

Sembra magia ma non lo è, ed è importante capire cosa succede sotto perché quando qualcosa si rompe (e prima o poi succede) sapere in quale dei passaggi sei ti fa risparmiare ore. In questo capitolo vediamo l’architettura completa dal YAML al chip acceso, come è fatto un file di configurazione, la differenza fra API nativa e MQTT, e quali sono le alternative a ESPHome nei casi in cui non è lo strumento giusto.

La catena completa, dal YAML al chip

Quando premi “Install”, succedono cinque cose in fila.

  1. Validazione. ESPHome legge il YAML e controlla che ogni componente esista, che i pin dichiarati siano validi per quel chip, che i tipi tornino. È qui che vengono fuori i “GPIO6 is not a valid pin for this board” e gli errori di indentazione. Nessuna compilazione è ancora partita, quindi questo passaggio dura secondi.
  2. Generazione del codice. ESPHome traduce il YAML in un progetto C++ completo, con main.cpp, i driver dei componenti che hai dichiarato, e nient’altro. È un dettaglio importante: nel firmware finisce solo il codice dei componenti che usi. Un device con due sensori è più piccolo e più veloce di uno con dieci, e non paga per le funzioni che non ha.
  3. Compilazione. Il progetto C++ viene passato a PlatformIO, che invoca il compilatore del framework scelto (ESP-IDF o Arduino). Questo è il passaggio lento: 5-10 minuti per un chip nuovo, 30-60 secondi per una ricompilazione dopo una modifica minore, grazie alla cache. È anche il passaggio che consuma CPU e disco, ed è il motivo per cui compilare su un Raspberry con scheda SD è una pessima idea.
  4. Upload. Il binario risultante finisce sul chip: la prima volta via USB, tutte le volte successive via OTA sul Wi-Fi. Ne parliamo in dettaglio in 6 Il primo device.
  5. Runtime. Il chip si riavvia col nuovo firmware, si connette al Wi-Fi, e apre la connessione verso Home Assistant.

Il punto chiave è che il chip non interpreta niente a runtime. Non c’è un YAML dentro l’ESP32, non c’è un interprete: c’è codice macchina compilato per quella configurazione specifica. È il motivo per cui ESPHome è veloce e affidabile su hardware con 400 KB di RAM, ed è anche il motivo per cui ogni singola modifica richiede una ricompilazione.

Anatomia di un file di configurazione

Un file ESPHome è fatto di blocchi di primo livello, ognuno dei quali configura un pezzo del sistema. Questo è lo scheletro minimo che ottieni creando un device nuovo:

esphome:
  name: sensore-cucina
  friendly_name: Sensore Cucina
 
esp32:
  board: esp32-c3-devkitm-1
  framework:
    type: esp-idf
 
logger:
 
api:
  encryption:
    key: "chiave-generata-automaticamente"
 
ota:
  - platform: esphome
    password: "password-generata-automaticamente"
 
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: "Sensore Cucina Fallback"
    password: "12345678"
 
captive_portal:

Blocco per blocco:

  • esphome:: l’identità del device. Il name diventa l’hostname sulla rete (sensore-cucina.local) e il prefisso di tutte le entità; il friendly_name è quello che vedi in Home Assistant. Il name deve essere minuscolo con trattini, e cambiarlo dopo è fastidioso perché rinomina tutte le entità: sceglilo bene alla prima (vedi le convenzioni in 14 Troubleshooting e pratiche di buon uso).
  • esp32:: quale chip e quale framework. Su board metti il modello esatto della board; il Device Builder ha un catalogo da cui scegliere, così non devi indovinare la stringa.
  • logger:: attiva i log. Vuoto va benissimo. È la tua unica finestra su cosa succede dentro il chip, non toglierlo mai.
  • api:: la connessione nativa verso Home Assistant, cifrata. È il canale principale.
  • ota:: abilita gli aggiornamenti wireless. Senza questo blocco, ogni modifica richiede di riprendere in mano il cavo USB.
  • wifi:: le credenziali, lette da secrets.yaml con la sintassi !secret. Il sottoblocco ap: crea un access point di emergenza se il Wi-Fi di casa non risponde.
  • captive_portal:: la paginetta di configurazione che appare collegandosi a quell’access point di emergenza.

Sotto questo scheletro si aggiungono i componenti veri: sensor:, binary_sensor:, switch:, light:, display:, e via dicendo. Tutti i capitoli dal 9 in poi sono, in sostanza, un catalogo di cosa si può scrivere là sotto.

I secrets

Il file secrets.yaml sta a fianco delle configurazioni e contiene le cose che non vuoi ripetere (o pubblicare):

wifi_ssid: "CasaMia"
wifi_password: "password-del-wifi"

Ogni !secret wifi_ssid viene sostituito al momento della compilazione. Usalo sempre: quando avrai dodici device e cambierai la password del Wi-Fi, la modificherai in un posto solo invece che in dodici.

API nativa o MQTT

ESPHome può parlare con Home Assistant in due modi, e la scelta di default è quasi sempre quella giusta.

L’API nativa è un protocollo binario di ESPHome, cifrato, in cui Home Assistant si connette direttamente al chip. È veloce (latenze di pochi millisecondi), non richiede altri servizi, supporta la scoperta automatica e permette al chip di chiamare servizi di Home Assistant e viceversa. È quella che vuoi nel 95% dei casi.

MQTT aggiunge un broker in mezzo: il chip pubblica su dei topic, Home Assistant (o chiunque altro) si iscrive. Costa un servizio in più da mantenere e qualche millisecondo di latenza, ma serve quando il device deve parlare con qualcosa che non è Home Assistant (Node-RED, un dashboard esterno, un altro sistema), o quando vuoi che i dati sopravvivano al riavvio del server. Il protocollo è già spiegato in MQTT (Message Queuing Telemetry Transport).

Si possono anche tenere entrambi accesi, ma raddoppia il traffico radio e non serve quasi mai. Parti con l’API nativa; se un giorno ti serve MQTT, aggiungerlo è cinque righe.

Perché non stai scrivendo C

Vale la pena soffermarsi su cosa ESPHome ti sta risparmiando, perché rende chiaro quando invece conviene abbandonarlo.

Se scrivessi lo stesso device in Arduino IDE dovresti: gestire a mano la connessione Wi-Fi con la riconnessione automatica, implementare il protocollo di comunicazione con Home Assistant (o l’MQTT con la sua discovery), scrivere o adattare il driver del BME280, implementare gli aggiornamenti OTA, gestire il watchdog, e scrivere un sistema di log. Sono qualche centinaio di righe di C++ che vanno mantenute e debuggate, prima ancora di arrivare alla logica che ti interessa.

ESPHome fa tutto questo, per tutti i device, allo stesso modo, e lo aggiorna quando cambia qualcosa a monte. Le venti righe di YAML che scrivi sono solo la parte specifica del tuo progetto.

Il rovescio è che sei dentro il modello di ESPHome: componenti dichiarativi, un ciclo di loop gestito da lui, e se ti serve qualcosa che nessun componente copre devi scrivere una lambda (un frammento di C++ dentro il YAML) o un componente custom. Per il 95% dei progetti domotici non capita mai.

Le alternative, e quando hanno senso

ESPHome non è l’unica strada, ed essere onesti su questo aiuta a capire dove sta.

StrumentoQuando ha senso
ESPHomeSensori e attuatori integrati in Home Assistant. Il default di questo corso
TasmotaDispositivi commerciali da riflashare (prese Sonoff, lampadine Tuya): ha firmware precompilati e si configura da web senza compilare niente
Arduino IDE / PlatformIOLogica complessa, timing stretto, protocolli custom, o quando stai imparando l’elettronica e vuoi capire cosa succede
MicroPythonPrototipazione rapidissima, chi conosce già Python, progetti non domotici
ESP-IDF puroProdotti veri, controllo totale su consumi e memoria. Non è terreno da hobby

Il caso più frequente in cui non userai ESPHome è il riflash di un dispositivo commerciale: se hai una presa Sonoff, Tasmota ha il firmware già pronto e ci metti cinque minuti, mentre con ESPHome dovresti scrivere la configurazione del pinout a mano (anche se esistono repository con le configurazioni già fatte per i modelli più diffusi).

L’altro caso è quando il progetto ha esigenze di timing stretto: ESPHome esegue un loop generale e non garantisce microsecondi. Per leggere un encoder veloce o pilotare un protocollo custom bit a bit, il C nudo è la strada.

Ricapitolando

  • ESPHome traduce il YAML in C++, lo compila e produce un firmware: nel chip non c’è nessun interprete.
  • Nel firmware finisce solo il codice dei componenti dichiarati: device semplici sono più leggeri e più stabili.
  • La catena è valida → genera → compila → carica → esegue; sapere in quale passaggio sei dimezza i tempi di diagnosi.
  • Lo scheletro minimo è esphome: + chip + logger: + api: + ota: + wifi:. Non togliere mai logger: e ota:.
  • Usa sempre !secret per le credenziali: cambiare la password del Wi-Fi con dodici device deve essere una modifica sola.
  • API nativa come default (veloce, cifrata, zero dipendenze); MQTT solo se serve parlare con qualcosa oltre a Home Assistant.
  • ESPHome ti risparmia Wi-Fi, OTA, driver, log e protocollo: qualche centinaio di righe di C++ per ogni device.
  • Non è sempre la scelta giusta: per riflashare dispositivi commerciali c’è Tasmota, per timing stretto c’è il C nudo.