Saltar al contenido
Volver a Artículos Publicados
Home Assistant

Cómo construí todo mi Home Assistant con Claude Code ejecutándose dentro

El detrás de las cámaras de mi serie sobre Home Assistant. Claude Code ejecutándose dentro de la caja, las skills en las que se apoya, un panel generado con Python, tarjetas animadas hechas en casa y un recorrido por todas las páginas.

Cómo construí todo mi Home Assistant con Claude Code ejecutándose dentro
Publicado originalmente en Dev.to. Lee reacciones y participa en la conversación en Dev.to →
Contenido 100% autoral: Todos los artículos, desafíos técnicos y código fueron escritos por Marcelo Costa sin el uso de IA en la redacción. La inteligencia artificial se utilizó exclusivamente para ayudar con la traducción a múltiples idiomas.

En mi serie de tres partes te enseñé las puertas, la alarma y el coche, la guerra del suelo radiante y el diagnóstico de CO₂ y las automatizaciones aburridas que de verdad protegen la casa.

Lo que no te conté es cómo se construyó.

Te lo confieso: apenas escribí yo ese YAML. Casi todas las líneas (las automatizaciones, el panel, las tarjetas animadas, los scripts que emparejan y renombran dispositivos) las escribió Claude Code, ejecutándose dentro de la propia caja de Home Assistant. Le hablo en portugués, casi siempre desde el móvil. Edita /config, valida, recarga, comprueba que la cosa de verdad funcionó y apunta todo lo que le mordió por el camino.

Así que este es el detrás de las cámaras: cómo está conectado, las skills en las que se apoya, cómo el panel pasó de YAML a código, de dónde salieron las animaciones, cómo se emparejan dispositivos cuando tu asistente no tiene manos y, al final, un recorrido por todas las páginas del panel, directo desde mi móvil.

La casa, en números

Desde junio de 2026
Commits 580
Automatizaciones · scripts 129 · 73
Dispositivos · entidades 147 · 1.163
Panel 10 pestañas, 60 ventanas emergentes, generado por 7.600 líneas de Python
Tarjetas hechas en casa 17 custom elements, sin librerías
Notas que escribió para sí mismo 25 archivos, ~105.000 palabras

Paso cero: Claude Code vive en un add-on

La casa funciona con un Home Assistant Green con Home Assistant OS, lo que significa que no puedes ponerte a instalar cosas en el host sin más. Lo que sí puedes hacer es usar el add-on Advanced SSH & Web Terminal: un pequeño contenedor Alpine con /config montado, la CLI ha y un token del Supervisor. Resulta que no necesita nada más.

Claro que hay una pega (siempre la hay): los contenedores de los add-ons se reconstruyen. Todo lo que instalas con npm, apk o pip desaparece tras un reinicio del add-on, y tu sesión se va con ello. La solución está en la propia configuración del add-on: reinstalar en cada arranque y guardar la carpeta de Claude dentro de /config, que sobrevive a todo.

# Settings → Add-ons → Advanced SSH & Web Terminal → Configuration
packages:
  - nodejs
  - npm
  - git
init_commands:
  - mkdir -p /config/.claude-box
  - ln -sfn /config/.claude-box /root/.claude
  - "[ -f /config/.claude-box/claude.json ] || echo '{\"hasCompletedOnboarding\": true}' > /config/.claude-box/claude.json"
  - ln -sf /config/.claude-box/claude.json /root/.claude.json
  - npm i -g @anthropic-ai/claude-code >/dev/null 2>&1 || true

Básicamente, cada arranque vuelve a poner Node y Claude Code, y los symlinks apuntan Claude a una carpeta que nunca desaparece. La sesión, la configuración, la memoria y las skills viven en /config/.claude-box (que está en el .gitignore, obviamente). Abro el Terminal desde la barra lateral de Home Assistant, en el portátil o en el móvil, escribo claude y listo.

Cómo está conectado

Desde ahí llega a Home Assistant por cuatro puertas:

  • Archivos. /config es el repositorio git. Lo que está en el repo es lo que se ejecuta.
  • La CLI ha. ha core check antes de nada, recargar siempre que se pueda, reiniciar solo cuando no queda otra.
  • El websocket. Paneles, el registro de entidades, el renderizado de plantillas. El cliente es tools/haws.py, un cliente websocket solo con la librería estándar. Lo escribió después de que las primeras herramientas, hechas sobre aiohttp, dejaran de funcionar el día que se reinició el add-on (¿te acuerdas de la pega?). Por el mismo motivo, todas las herramientas del repo usan solo la librería estándar.
  • MCP. La integración oficial MCP Server de Home Assistant, para el estado en vivo.

El secreto está en lo que lee primero

Cada sesión empieza cargando CLAUDE.md, las reglas que valen para toda la casa. Cada regla ahí dentro costó al menos un diagnóstico, y el archivo apunta lo que costó. Dos de mis favoritas (la primera todavía escuece):

condition: dentro de then: / choose: NO detiene el script — solo aborta ese bloque, y la siguiente acción se ejecuta igualmente. Las guardas que tienen que pararlo todo van en el nivel superior, o usan stop:. Esto costó 5 desarmados de la alarma con la casa vacía.

Mejor recargar. Cada reinicio deja las lámparas Govee sin conexión un par de minutos.

Los detalles viven en docs/notas/: 25 notas, una por tema (alarma, suelo radiante, TV, Zigbee, energía, riego…), todas escritas por Claude sobre la marcha. La regla es sencilla: "antes de tocar un tema, lee su nota". Por eso una sesión en noviembre no repite los errores que cometió una sesión en agosto.

Además, Claude Code guarda su propia memoria: 47 archivitos sobre cómo trabajo yo. Algunos existen solo porque me enfadé:

  • Siempre portugués de Brasil, nunca el de Portugal. No paraba de escribir telemóvel en lugar de celular.
  • Información no es una petición de cambio. Una vez le expliqué cómo se comunican entre sí los termostatos de pared, solo para que entendiera la casa, y fue y editó dos packages. Ahora, cuando le explico algo, lo asimila y se queda ahí.
  • Lo visual se decide mirando. Más sobre eso abajo.

El ciclo por el que pasa cada cambio

El paso 7 es el que da intereses: una trampa encontrada hoy se convierte en una línea de una nota, y la siguiente sesión empieza sabiéndolo ya.


Las skills

Las skills son instrucciones empaquetadas que Claude carga cuando la tarea encaja. Estas son las que hicieron el trabajo pesado:

  • home-assistant-manager de komal-SkyNET — la disciplina de despliegue: editar → ha core check → recargar o reiniciar → demostrarlo con logs, trazas y el estado de las entidades. Con diferencia la más usada (85 veces y subiendo). Da por hecho que entras por SSH desde fuera, así que mi CLAUDE.md sobrescribe esa parte: ya estamos dentro.
  • artifact-design, dataviz y artifact-diagramming — cuando digo "ponlo más bonito", Claude ya no aplica sin más su mejor apuesta. Monta una página privada con 2–4 opciones lado a lado, usando los botones reales, y yo elijo desde el móvil ("me gusta la B"). Lo aprendió por las malas: una paleta ajustada "por los números" se llevó un "no veo ningún cambio significativo" de mi parte.
  • security-review — una auditoría de los cambios pendientes antes de que pasen a producción. Después de eso, la seguridad se volvió costumbre: la última revisión cerró los puertos MQTT en la red local, eliminó una página HTML antigua que era accesible públicamente en /local/ (ups) e hizo que los inicios de sesión fallidos y los baneos de IP me avisen en el móvil.

El panel ahora es código

El panel se llama Prisma. 10 pestañas, 60 ventanas emergentes, y nadie lo edita desde la interfaz. Lo genera tools/build_prisma_dashboard.py (unas 7.600 líneas, con el razonamiento de cada decisión escrito en comentarios) y se envía directamente a Home Assistant por el websocket. Sin reiniciar.

python3 tools/conferir_prisma.py        # does the generator still match what is live? exits 1 with a diff
python3 tools/build_prisma_dashboard.py # rebuilds the whole dashboard
cd i18n && python3 gerar.py             # Spanish version, must print "sem tradução: 0"
python3 publicar.py                     # pushes them all over the websocket

¿Por qué la primera línea? Porque el generador borró en silencio una edición hecha desde la interfaz cinco veces antes de que añadiéramos esa comprobación.

El mismo panel también sale en español e inglés, generado a partir de un diccionario de fragmentos. Las capturas de abajo son de la versión en inglés, por eso algunos estados en vivo todavía aparecen en portugués: el generador traduce las tarjetas, nunca el estado de una entidad.

Las piezas son Bubble Card (las ventanas emergentes), Mushroom, navbar-card (la barra inferior), kiosk-mode (sin cabecera), un tema propio con cambio claro/oscuro y las tarjetas que escribió desde cero. Lo que me lleva a la parte divertida.


Animaciones: dibujar lo que nadie había dibujado

El Marketplace tiene tarjetas animadas para lavadoras, el tiempo, la energía y ventiladores. ¿Algo que dibuje una tele, un altavoz o un PC? Nada. Así que Claude escribió casa-media-cards.js: 17 custom elements en ~4.800 líneas de JavaScript puro. Sin librerías, sin llamadas de red.

La tele se ilumina al encenderse, toma el color de la entrada activa y hace un barrido lento:

La tarjeta de la tele: apagada, luego el sintonizador de TV, luego HDMI 1

El PC abre la pantalla como un monitor CRT antiguo y la vuelve a cerrar al apagarse. El truco es que el SVG nunca se reconstruye, solo cambia una clase, así que la transición CSS funciona en los dos sentidos (si lo reconstruyes, el apagado se convierte en un corte seco):

La tarjeta del PC encendiéndose y apagándose

El Music Frame (un altavoz con forma de marco de fotos) muestra la portada del álbum dentro de un marco de madera, con un ecualizador de 7 barras cuya altura sigue al volumen:

La tarjeta del Music Frame sonando, con el volumen subiendo

La lavadora-secadora y el lavavajillas usan la washing-machine-card de la comunidad, parcheada por Claude para que el anillo cuente desde el inicio real del ciclo y muestre el tiempo como 1h47. Cada actualización del Marketplace sobrescribe ese parche, así que una automatización lo vuelve a aplicar sin hacer ruido.

La lavadora-secadora en marcha

El lavavajillas en marcha

(Estos GIFs se grabaron en un navegador headless, con los estados simulados solo en esa pestaña del navegador. Mi tele de verdad estuvo apagada todo el rato.)

Y algunos detalles más pequeños, porque quería que el panel se sintiera más vivo: cada botón lleva un degradado suave del color de su icono, y los botones de las puertas vibran al tocarlos y otra vez cuando responde la API del edificio, terminando en Abierta o No se abrió. Las secuencias a pie hacen una cuenta atrás en vivo hasta la siguiente puerta.

Te estarás preguntando: ¿cómo prueba una IA una animación? De dos formas. El bundle de las tarjetas se ejecuta en Node con linkedom, así que puede llamar a setConfig() con la configuración real y leer lo que calculó la tarjeta. Y para la prueba de verdad, arranca un Chromium headless, inicia sesión en el frontend real y hace capturas. Exactamente así se hicieron todas las imágenes de este post.


Emparejar dispositivos cuando tu IA no tiene manos

Yo pulso el botón del dispositivo. Claude hace todo lo demás.

Los sensores de CO₂ (Matter). Primero añadí el AirGuard a la app SmartThings, y apareció en Home Assistant a través de la nube de Samsung. A Claude no le gustó nada: ese sensor alimenta el suelo radiante del salón, así que si la nube se cae, el salón se queda sin termómetro. Descubrió que Matter estaba desactivado por configuración (integración ignorada, sin el add-on Matter Server), instaló el add-on y me guio por el Matter multi-admin: la app SmartThings te da un código para compartir (válido durante 15 minutos, con la pantalla abierta), y Home Assistant se une como un segundo "fabric". El dispositivo ya estaba en el Wi-Fi, así que se comisionó por IP. Y eso importa, porque el Green no tiene Bluetooth en absoluto.

Zigbee. Aquí la regla es renombrar el día del emparejamiento. Los nombres de fábrica se cortan a los 32 caracteres, y renombrar un dispositivo no renombra sus entidades, así que Claude renombra ambos desde el registro, siguiendo un esquema de nombres que el panel escanea. Ponle a un termómetro nuevo termometro_<estancia> → aparece solo en la pestaña Sensores, en el informe diario de baterías y en la tarjeta de Home. Ni una edición en el panel.

Las sondas de tubería en el colector de la bomba de calor. Antes incluso de que llegaran, me escribió una guía de montaje con fotos, en una página privada. Una vez instaladas, le mandé fotos y confirmó cuál era la ida y cuál el retorno. También rebatió (¡con razón!) un análisis externo que decía que una sonda estaba suelta: la otra simplemente seguía caliente de mi mano, y se enfrió 8 minutos después.

También emparejados así: contactos de puerta y un detector de humo (Zigbee), una válvula de riego Zigbee, el estor enrollable de la cocina, los relés Shelly de las persianas y del suelo radiante, y un Samsung SmartTag en mis llaves, a través de un fork comunitario de SmartThings Find que también tuvo que parchear.


Todos los escenarios que se me ocurrieron

Las partes 1–3 profundizan en la mayoría. Aquí están todos en una tabla:

Escenario Qué pasa La trampa que encontró
Llegar a casa La alarma se desarma por el Wi-Fi de casa, por una puerta + presencia, o por GPS con la aproximación detectada El GPS a secas una vez la desarmó sin que llegara nadie
Salir La alarma se arma y las lámparas se apagan La presencia necesita person.*, no device_tracker.*: su last_changed se reescribe con cada ping de GPS
Noche Las luces se encienden si alguien se levanta, y un barrido después de medianoche apaga lo que se quedó olvidado Un disparador de movimiento tiene que ser from: "off", o un sensor que vuelve de unavailable dispara la alarma
Suelo radiante Home Assistant solo puede restar: un Shelly corta el cable de demanda El termostato de pared siempre gana, así que HA detecta cuándo lo están pasando por encima
Electrodomésticos Cada ciclo de lavado se reconstruye a mano: duración, energía, coste Samsung informa los kWh acumulados de toda la vida y Bosch no informa nada
Riego El tiempo de riego sigue la evapotranspiración, y se salta cuando llueve La válvula se cierra sola a los 10 minutos
Tendedero y toldo Un toque: una foto de la cámara + Gemini responde "¿hay ropa fuera, y va a llover?" La cámara no dice nada mientras su detección de movimiento está apagada, así que el script la enciende solo para la foto
Trayecto El estado de la línea 3 del metro en la pestaña Home, días laborables de 07:30 a 08:30 No hay API, así que lee la web, que bloquea bots salvo que parezcas un navegador
Facturas Las facturas de la luz se importan solas; la del agua entra por un bookmarklet El captcha es cosa mía, el resto es cosa de la casa
Voz Assist funciona con Gemini Mi suscripción de Claude no cubre llamadas a la API, y la clave de Google ya estaba pagada

Y el mejor bug de todos: "certificado no fiable" en el móvil con 4G, solo a ciertas horas, mientras que con Wi-Fi todo iba bien. Parecía un problema de Home Assistant. No lo era. Mi operador intercepta rangos de IP de Cloudflare durante las franjas de partidos de fútbol, con un certificado falso. Sí, fútbol. La solución es un DNS rewrite en el móvil apuntando a otro edge de Cloudflare. Y la regla que guardó en memoria: apunta la hora antes de empezar a teorizar.


El recorrido: todas las páginas, desde el móvil

Los gastos, las imágenes de las cámaras, los mapas y las caras están difuminados. Todo lo demás es exactamente lo que veo.

Home

El tiempo, presencia, alarma, climatización, luces, persianas, TV y música, PC, electrodomésticos y sensores. Cada sección abre su propia ventana emergente.

Pestaña Home

Climatización

Los tres termostatos con sus presets, la temperatura del agua en el colector, el aire de cada estancia y los controles.

Pestaña Climatización

Acceso

Todas las puertas del edificio, las secuencias a pie con los tiempos ajustados con cronómetro, el garaje y las zonas comunes.

Las puertas funcionan con Alfred Smart, que no tiene integración oficial con Home Assistant (la parte 1 cuenta la historia de la ingeniería inversa). Así que creé una: ha-alfred-smart, que se instala desde HACS como repositorio personalizado. Descubre todas las puertas, garajes y accesos que tu cuenta puede usar, le da a cada uno un botón Abrir y un sensor Última apertura, y nunca reintenta una apertura. ¿Por qué no? Porque que Alfred no conteste no significa que la puerta se quedara cerrada. Si tu edificio también usa Alfred Smart, pruébala.

Pestaña Acceso

Reservas y zonas comunes

Turnos del gimnasio y del Agora Club, reservados con un toque, y las puertas de los espacios compartidos.

Pestañas Reservas y Abrir

Cámaras

Las cámaras Ring, con la detección de movimiento siguiendo a la alarma. Las imágenes en vivo están difuminadas, por motivos obvios.

Pestaña Cámaras

Coche

Combustible, autonomía, puertas y ventanillas, bloquear y desbloquear, avisos de mantenimiento y el mapa (difuminado, claro).

Pestaña Coche

Facturas

Luz, la bomba de calor del edificio y agua, mes a mes. Ves la forma, no los números.

Pestaña Facturas, valores difuminados

Sensores

Fugas, humo, temperatura, CO₂, humedad y todas las baterías de la casa.

Pestaña Sensores

Riego

El riego de hoy, la programación y la ventana emergente "ajustar al tiempo" con las cuentas de la evapotranspiración.

Pestaña Riego y la ventana emergente del tiempo

Ventanas emergentes

El estor dibujado que sigue la posición real, el tiempo, la línea de metro y mis llaves:

Ventanas emergentes: estor, tiempo, metro, llaves

El mando de la tele, el Music Frame, la lavadora-secadora y el lavavajillas:

Ventanas emergentes: mando de la tele, Music Frame, lavadora-secadora, lavavajillas

Los presets de la calefacción, quién manda ahora mismo, la calidad del aire y las baterías:

Ventanas emergentes: presets de calefacción, ahora, calidad del aire, baterías

Presencia, la alarma, las luces y las puertas del coche:

Ventanas emergentes: presencia, alarma, luces, puertas del coche


Si quieres probarlo

  1. Ponlo dentro de la caja. Como add-on, ejecuta ha core check, lee los logs y recarga por su cuenta. Sin malabares con SSH, sin copiar archivos de un lado a otro.
  2. Convierte /config en un repositorio git antes del primer prompt. Cada cambio se convierte en un diff que puedes leer y revertir.
  3. Escribe las reglas, y deja que él escriba las notas. CLAUDE.md para lo que vale en todas partes, una nota por tema para lo demás.
  4. Exige pruebas, no un "debería funcionar". Estado real, la traza de la automatización, el log en bruto. Mi regla favorita de todo el archivo: no digas "esto no tiene arreglo" antes de leer el log en bruto.
  5. Cuando el panel crezca, genéralo. Las ediciones desde la interfaz y un panel con 60 ventanas emergentes no se llevan bien (cinco ediciones borradas me lo enseñaron).
  6. Decide lo visual mirando, en el dispositivo que de verdad usas.
  7. Deja secrets.yaml fuera de su alcance. El mío lo está, por regla.

Lo curioso es que, desde hace años, mi trabajo consiste en convertir flujos manuales en algo que funciona solo y demuestra que funciona. Aquí acabé al otro lado de la mesa: yo soy quien sabe cómo debe comportarse la casa, y Claude es el ingeniero que la construye, la prueba y lleva un registro de cada bug que se ha encontrado.

La casa sigue siendo un sistema bajo prueba. Solo que ahora tiene un pair programmer muy rápido viviendo dentro.

Ejecutando Home Assistant Green, YAML-first (bueno, Claude-first), con un panel construido sobre Bubble Card, Mushroom y 17 tarjetas mías. ¿Y tú? ¿Dejarías que una IA viviera dentro de la caja de tu Home Assistant, o ni de broma? Déjame un comentario, y pregúntame lo que quieras sobre el montaje. ¡Me encantará leerte!