Casa Sin Nube

ESPHome y Home Assistant: 3 automatizaciones locales con YAML listo para copiar

Las automatizaciones en la nube funcionan hasta que dejan de funcionar: cada vez que un fabricante decide cobrar, cerrar el servicio o cambiar el protocolo, tu casa deja de hacer lo que hacía. La alternativa local no es más cara ni mucho más difícil de mantener: es elegir un hardware y un firmware que hablen directamente con tu servidor, sin esperar a que ningún servicio externo esté en línea.

Estos tres ejemplos usan ESPHome para el firmware y Home Assistant como cerebro. Todo el YAML que ves aquí se puede copiar, adaptar y flashear en un ESP32. No hay cuenta, ni suscripción, ni conexión obligatoria a internet.

Qué necesitas

Antes de empezar: seguridad

Trabaja en bajo voltaje y con la alimentación desconectada al soldar. Si un relé va a manipular un aparato conectado a la red eléctrica, hazlo con componentes certificados y, si no estás seguro, que lo haga una persona cualificada. Esto es información general, no un plano de instalación eléctrica.

Ejemplo 1: sensor de puerta con aviso local

El caso más sencillo que te enseña el patrón completo: un ESP32 con un reed switch en el marco de la puerta, un imán en la hoja y una automatización que te avisa si la puerta se queda abierta.

YAML de ESPHome (firmware del dispositivo):

esphome:
  name: puerta-patio

esp32:
  board: esp32dev
  framework:
    type: arduino

wifi:
  ssid: "MiRedLocal"
  password: "cambia-esta-clave"
  manual_ip:
    static_ip: 192.168.1.50
    gateway: 192.168.1.1
    subnet: 255.255.255.0

api:
  encryption:
    key: "base64:genera-la-tuya-con-esphome-wizard"

logger:

ota:
  platform: esphome
  password: "cambia-esta-ota"

binary_sensor:
  - platform: gpio
    pin:
      number: GPIO26
      mode: INPUT_PULLUP
    name: "Puerta del patio"
    device_class: door
    filters:
      - delayed_on: 50ms
      - delayed_off: 50ms

Detalle de proceso: el reed switch con INPUT_PULLUP y cables largos da falsos positivos por rebote de contactos. Los filtros delayed_on y delayed_off de 50 ms se comen ese ruido. Es el fallo más común, no lo saltes.

Automatización en Home Assistant:

alias: "Aviso puerta abierta"
triggers:
  - trigger: state
    entity_id: binary_sensor.puerta_del_patio
    to: "on"
    for: "00:01:00"
conditions: []
actions:
  - action: notify.persistent_notification
    data:
      title: "Casa sin nube"
      message: "La puerta del patio lleva más de 1 minuto abierta."
mode: single

La notificación persistente aparece en tu panel local. Si usas la app de Home Assistant, puedes llevarla al móvil; eso depende de cómo tengas montada tu instalación y la app, no del fabricante del sensor.

Ejemplo 2: ventilador gobernado por temperatura

Un DS18B20 (muy fiable, admite cable largo, usa un solo hilo de datos) más un relé. La regla es simple: si la temperatura del salón supera 28 °C, enciende; si baja de 26 °C, apaga. Si a tu proveedor de internet se le ocurre caerse, el ventilador sigue funcionando.

YAML de ESPHome:

esphome:
  name: salon-clima

esp32:
  board: esp32dev
  framework:
    type: arduino

wifi:
  ssid: "MiRedLocal"
  password: "cambia-esta-clave"

api:
  encryption:
    key: "base64:genera-la-tuya-con-esphome-wizard"

logger:

ota:
  platform: esphome
  password: "cambia-esta-ota"

sensor:
  - platform: dallas_temp
    pin: GPIO25
    name: "Temperatura salon"

switch:
  - platform: gpio
    pin: GPIO26
    name: "Ventilador salon"
    id: ventilador_salon

Automatizaciones en Home Assistant:

alias: "Ventilador: encender por calor"
triggers:
  - trigger: numeric_state
    entity_id: sensor.temperatura_salon
    above: 28
actions:
  - action: switch.turn_on
    target:
      entity_id: switch.ventilador_salon
mode: single

---

alias: "Ventilador: apagar al enfriar"
triggers:
  - trigger: numeric_state
    entity_id: sensor.temperatura_salon
    below: 26
actions:
  - action: switch.turn_off
    target:
      entity_id: switch.ventilador_salon
mode: single

Detalle de proceso: el DS18B20 necesita una resistencia de pull-up de 4.7 kΩ entre el pin de datos y 3.3 V. El clásico "no lee nada" casi siempre es "me falta una resistencia", no un sensor roto.

Ejemplo 3: pantalla OLED con el estado de casa

Una pantalla SSD1306 de 128x64 en la cocina muestra la temperatura y si la puerta sigue abierta. En ESPHome:

esphome:
  name: pantalla-casa

esp32:
  board: esp32dev
  framework:
    type: arduino

wifi:
  ssid: "MiRedLocal"
  password: "cambia-esta-clave"

api:
  encryption:
    key: "base64:genera-la-tuya-con-esphome-wizard"

logger:

ota:
  platform: esphome
  password: "cambia-esta-ota"

font:
  - file: "fonts/roboto.ttf"
    id: fuente1
    size: 14

sensor:
  - platform: dallas_temp
    pin: GPIO25
    name: "Temperatura salon"
    id: temperatura

binary_sensor:
  - platform: homeassistant
    id: puerta
    entity_id: binary_sensor.puerta_del_patio

display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    address: 0x3C
    lambda: |-
      it.printf(0, 0, id(fuente1), "Temp: %.1f C", id(temperatura).state);
      if (id(puerta).state) {
        it.printf(0, 24, id(fuente1), "PUERTA ABIERTA");
      } else {
        it.printf(0, 24, id(fuente1), "TODO CERRADO");
      }

Detalle de proceso: sube antes un archivo de fuente TTF a la carpeta fonts de tu configuración de ESPHome; sin fuente, la pantalla no imprime nada. El componente binary_sensor.homeassistant necesita que el dispositivo ESPHome esté conectado a Home Assistant por la API local.

Lo que me falló la primera vez

Estos tres montajes son el arranque de una casa local. Cada decisión de hardware y firmware la documentaré en el diario de guerra. La newsletter avisa cuando hay una guía nueva; el contenido que recibes es el mismo que publico aquí, sin trucos de registro.