Themes personalizados en Home Assistant

Themes personalizados en Home Assistant

En esta entrada vamos a aprender a instalar Themes personalizados en Home Assistant, para darle un toque de estilo a tu panel!

¿Qué es un theme y cómo se instalan?

Un «theme» o tema es una combinación de colores, tipos de fuente y estilos de otros elementos (botones, bordes, fondos, etc.) que puedes aplicar sobre el «esqueleto» o estructura de Home Assistant para personalizarlo. Es decir, son cambios puramente estéticos para que el aspecto de tu interfaz refleje tu estilo.

La diferencia entre instalar Themes personalizados en Home Assistant e ir personalizando tarjeta a tarjeta, es que de esta forma puedes elegir o definir un estilo uniforme que se va a aplicar a todos los elementos de tu panel, incluso aquellos que vayas añadiendo.

Es una técnica que te aporta eficiencia y homogeneidad en el diseño de tu panel. Además, es muy fácil instalar temas desde HACS, donde tienes montones de opciones disponibles.

Temas HACS

Crear o modificar tus propios temas

Si eres de los que disfruta personalizando al máximo tu interfaz, es posible que quieras ir un paso más allá creando Themes personalizados en Home Assistant.

Como te decía, en definitiva un tema no es más que una combinación de estilos que se almacenan en un fichero ‘.yaml’. Por lo tanto, nada te impide que crees tu propia combinación o que cambies algo en el tema que tienes instalado.

Para explicarte cómo hacerlo vamos a utilizar el tema BWHOUSE (diseñado, como no, por nuestro amigo BWHOUSE de la comunidad de Aguacatec 😊), que combina un diseño moderno y minimalista, con paletas de colores adaptativas para modos claro y oscuro, fondos transparentes y suaves bordes redondeados.

Código YAML del tema

Tanto si has creado tu propio tema, como si estás usando alguno de la comunidad, al final debes tener un código con la siguiente estructura.

  • Si quieres instalar el magnífico tema de BWHOUSE (o usarlo como base para crear el tuyo), crea un fichero con cualquier editor de texto, copia el siguiente código y dale el nombre del tema (en este caso, ‘bwhouse.yaml’). Luego accede a config > themes, crea la carpeta de tu tema (por ejemplo, ‘bwhouse’) y coloca dentro el fichero.
  • Si quieres modificar un tema que ya tengas instalado, busca el código en config > themes, dentro de la carpeta correspondiente.
💡 En ambos casos te recomiendo que utilices el complemento Samba Share para acceder al almacenamiento de Home Assistant.
Bwhouse:                                                                        # Nombre del tema (así se selecciona en Home Assistant)

  # ==== COLORES PRINCIPALES DE LA INTERFAZ ====
  primary-color: var(--background)                                              # Color principal (usado para iconos, botones, acentos básicos)
  accent-color: var(--gray800)                                                  # Color de acento (detalles destacados o resaltados)
  primary-background-color: var(--background-image)                             # Fondo principal de toda la interfaz (puede ser una imagen)
  divider-color: var(--gray800)                                                 # Color de los divisores o líneas separadoras

  # ==== TEXTO ====
  primary-text-color: var(--gray800)                                            # Color principal del texto
  secondary-text-color: var(--gray800)                                          # Color de texto secundario o menos importante
  text-primary-color: var(--gray800)                                            # Color principal del texto (algunas tarjetas usan esta variable)
  disabled-text-color: var(--gray800)                                           # Color del texto cuando un elemento está desactivado
  text-accent-color: var(--gray800)                                             # Color del texto de acento
  warning-color: var(--gray800)                                                 # Color usado para advertencias
  gauge-color: var(--gray800)                                                   # Color de los medidores o gauge
  success-color: var(--gray800)                                                 # Color usado para mensajes o íconos de éxito

  # ==== ENCABEZADO (HEADER / TOP BAR) ====
  app-header-background-color: var(--ha-card-background)                                # Fondo del encabezado superior
  app-header-text-color: var(--gray800)                                         # Color del texto en el encabezado
  app-header-selection-bar-color: transparent                                   # Quita la barra de selección debajo del encabezado
  app-header-edit-text-color: var(--gray800)                                    # Color del texto cuando se edita el encabezado
  app-header-backdrop-filter: var(--background)                                 # Filtro de fondo (transparencia o desenfoque)
  app-header-edit-background-color: transparent                                 # Fondo transparente al editar el encabezado

  # ==== TARJETAS (CARDS) ====
  card-background-color: var(--ha-card-background)                                      # Fondo de las tarjetas (cards)
  ha-card-border-color: var(--background)                                       # Color del borde de las tarjetas
  paper-listbox-background-color: var(--background)                             # Fondo de listas tipo "listbox"
  rgb-card-background-color: var(--background)                                  # Fondo de tarjetas RGB
  ha-card-border-width: 0                                                       # Elimina el borde (0 píxeles)
  ha-card-backdrop-filter: blur(8px)                                            # Aplica desenfoque al fondo de las tarjetas
  ha-card-box-shadow: >                                                         # Sombra y efecto de luz en las tarjetas (multi-línea)
    3px 3px 0.5px -3.5px rgba(255, 255, 255, 0.30) inset,
    -2px -2px 0.5px -2px rgba(255, 255, 255, 0.30) inset,
    0 0 8px 1px rgba(255, 255, 255, 0.10) inset,
    0 0 2px 0 rgba(0, 0, 0, 0.10)

  # ==== MENÚ LATERAL (SIDEBAR) ====
  sidebar-icon-color: var(--gray800)                                            # Color de los íconos del menú lateral
  sidebar-text-color: var(--gray800)                                            # Color del texto del menú lateral
  sidebar-background-color: var(--background)                                   # Fondo del menú lateral
  sidebar-selected-icon-color: var(--blue)                                      # Color del ícono cuando está seleccionado
  sidebar-selected-text-color: var(--blue)                                      # Color del texto cuando está seleccionado

  # ==== SELECTORES, LISTAS Y MENÚS (mwc-select, mwc-list, mwc-menu) ====
  mdc-select-fill-color: var(--ha-card-background)                              # Fondo del selector (desplegable)
  mdc-select-ink-color: var(--primary-text-color)                               # Color del texto dentro del selector
  mdc-select-dropdown-icon-color: var(--primary-text-color)                     # Color del ícono del desplegable
  mdc-select-label-ink-color: var(--secondary-text-color)                       # Color del texto de la etiqueta del selector
  mdc-select-idle-line-color: var(--secondary-text-color)                       # Línea base del selector cuando está inactivo
  mdc-select-hover-line-color: var(--primary-text-color)                        # Línea base del selector al pasar el cursor
  mdc-menu-background-color: var(--background)                                  # Fondo del menú desplegable
  mdc-list-item-graphic-color: var(--primary-text-color)                        # Color del ícono en los elementos de lista
  mdc-list-item-text-color: var(--primary-text-color)                           # Color del texto de los ítems de lista
  mdc-list-item-hover-background-color: rgba(255, 255, 255, 0.08)               # Fondo al pasar el cursor por un ítem

  # ==== FUENTE TIPOGRÁFICA ====
  primary-font-family: 'Raleway, sans-serif'                                    # Fuente principal usada en todo el tema
  paper-font-common-base_-_font-family: "var(--primary-font-family)"            # Asigna fuente base a componentes Paper
  paper-font-common-code_-_font-family: "var(--primary-font-family)"            # Fuente para textos tipo código
  paper-font-body1_-_font-family: "var(--primary-font-family)"                  # Fuente del cuerpo del texto
  paper-font-subhead_-_font-family: "var(--primary-font-family)"                # Fuente de subtítulos
  paper-font-headline_-_font-family: "var(--primary-font-family)"               # Fuente de títulos grandes
  paper-font-caption_-_font-family: "var(--primary-font-family)"                # Fuente de subtítulos pequeños
  paper-font-title_-_font-family: "var(--primary-font-family)"                  # Fuente de títulos medios
  ha-card-header-font-family: "var(--primary-font-family)"                      # Fuente para encabezados de tarjetas
  ha-font-family-body: "var(--primary-font-family)"                             # Fuente global del cuerpo
  ha-font-family-heading: "var(--primary-font-family)"                          # Fuente para encabezados
  ha-font-family-code: "var(--primary-font-family)"                             # Fuente para texto en formato código
  ha-font-family-longform: "var(--primary-font-family)"                         # Fuente para textos largos o párrafos

  # ==== GLOBAL ====
  lovelace-background: var(--background-image)                                  # Fondo general del dashboard Lovelace (imagen o color)

  # ==== ENERGÍA ====
  energy-grid-consumption-color: var(--ha-card-background)                      # Color del consumo eléctrico desde la red
  energy-grid-return-color: var(--background)                                   # Color del retorno de energía a la red
  energy-solar-color: var(--background)                                         # Color de la energía solar
  energy-non-fossil-color: var(--background)                                    # Color de energías no fósiles
  energy-battery-out-color: var(--background)                                   # Color de descarga de batería
  energy-battery-in-color: var(--background)                                    # Color de carga de batería
  energy-gas-color: var(--background)                                           # Color del gas natural

  # ==== MODO CLARO Y OSCURO ====
  modes:                                                                        # Define los ajustes específicos para modo claro y oscuro

    light:                                                                      # Modo claro
      background-image: "url('/local/fondos/claro.jpg') center/cover no-repeat fixed"                        # Imagen de fondo
      background: "url('/local/fondos/claro.jpg') center/cover no-repeat fixed"                              # Color base de fondo
      ha-card-background: "#d2e3f4"                                             # Fondo de las tarjetas
      primary-background-color: "#d2e3f4"                                       # Fondo principal
      secondary-background-color: "#d2e3f4"                                     # Fondo secundario
      primary-text-color: "#000000"                                             # Texto principal oscuro
      popup-img: "url('/local/fondos/claro.jpg')"
      popup-size: "cover"
      popup-pos: "center"
      popup-repeat: "no-repeat"
      popup-surface: "#d2e3f4"                                                  # Color de los desplegables
      gray000: "#edeff2"                                                        # Escala de grises (más claro)
      gray100: "#e9eaec"
      gray200: "#d6d7d9"
      gray300: "#b6b7b9"
      gray400: "#909193"
      gray500: "#707173"
      gray600: "#494a4c"
      gray700: "#313233"
      gray800: "#0f0f10"                                                        # Gris más oscuro
      input-fill-color: "#e9efff"                                               # Fondo de campos de entrada
      input-ink-color: "#0f0f10"                                                # Texto dentro de inputs
      input-label-ink-color: "#0f0f10"                                          # Texto de las etiquetas en inputs
      mdc-select-fill-color: "#e9efff"                                          # Fondo de los selects
      mdc-select-ink-color: "#0f0f10"                                           # Texto dentro de selects
      paper-dialog-background-color: rgba(50,50,60,0.85)                        # Fondo de diálogos (ligeramente transparente)
      ha-dialog-surface-background: "#d2e3f4"                                   # Fondo del área principal del diálogo
      dialog-background-color: "#d2e3f4"                                        # Fondo general de diálogos
      mdc-theme-surface: "#d2e3f4"                                              # Superficie principal de Material Design
      mdc-theme-background: "#d2e3f4"                                           # Fondo de Material Design
      mdc-theme-on-surface: "#d2e3f4"                                           # Color sobre la superficie
      mdc-theme-text-primary-on-background: var(--gray800)                      # Texto principal sobre fondo
      mdc-theme-text-secondary-on-background: var(--gray000)                    # Texto secundario sobre fondo
      --text-field-cursor-color: "#ff6600"                                      # Color del cursor en campos de texto
      --mdc-theme-primary: "#ff6600"                                            # Color primario del tema (naranja)
      --mdc-text-field-ink-color: "#ff6600"                                     # Color del texto en campos
      --mdc-text-field-caret-color: "#ff6600"                                   # Color del cursor
      slider1: "#c8daf2"                                                        # Slider color inferior
      slider2: "#cccee5"                                                        # Slider color superior

    dark:                                                                       # Modo oscuro
      background-image: "url('/local/fondos/oscuro.jpg') center/cover no-repeat fixed"                       # Imagen de fondo
      background: "url('/local/fondos/oscuro.jpg') center/cover no-repeat fixed"                             # Fondo general muy oscuro
      ha-card-background: "#030b16"                                             # Fondo de tarjetas oscuro
      primary-background-color: "#041226"                                       # Fondo principal oscuro
      secondary-background-color: "#041226"                                     # Fondo secundario oscuro
      primary-text-color: "#ffffff"                                             # Texto blanco
      popup-img: "url('/local/fondos/oscuro.jpg')"
      popup-size: "cover"
      popup-pos: "center"
      popup-repeat: "no-repeat"
      popup-surface: "#041226"                                                  # Color de los desplegables
      gray000: "#3a3b3d"                                                        # Escala de grises (más oscuro)
      gray100: "#353637"
      gray200: "#404142"
      gray300: "#555658"
      gray400: "#737476"
      gray500: "#939496"
      gray600: "#c8c9cb"
      gray700: "#eff0f2"
      gray800: "#ffffff"                                                        # Blanco puro como gris más alto
      input-fill-color: "#041226"                                               # Fondo de inputs oscuro
      input-ink-color: "#ffffff"                                                # Texto dentro de inputs
      input-label-ink-color: "#ffffff"                                          # Etiquetas en inputs
      mdc-select-fill-color: "#041226"                                          # Fondo de selects
      mdc-select-ink-color: "#ffffff"                                           # Texto de selects
      paper-dialog-background-color: "#041226"                                  # Fondo de diálogos semitransparente claro
      ha-dialog-surface-background: "#041226"                                   # Fondo principal de los diálogos
      dialog-background-color: "#041226"                                        # Fondo de diálogo
      mdc-theme-surface: "#041226"                                              # Superficie principal
      mdc-theme-background: "#041226"                                           # Fondo general
      mdc-theme-on-surface: "#041226"                                           # Color sobre superficie
      mdc-theme-text-primary-on-background: var(--gray800)                      # Texto principal sobre fondo
      mdc-theme-text-secondary-on-background: var(--gray000)                    # Texto secundario sobre fondo
      --text-field-cursor-color: "#ff6600"                                      # Color del cursor
      --mdc-theme-primary: "#ff6600"                                            # Color primario (naranja)
      --mdc-text-field-ink-color: "#ff6600"                                     # Texto en campos
      --mdc-text-field-caret-color: "#ff6600"                                   # Cursor de texto
      slider1: "#474955"                                                        # Slider color inferior
      slider2: "#21242d"                                                        # Slider color superior

  # ==== CARD-MOD (PERSONALIZACIONES CSS AVANZADAS) ====
  card-mod-theme: "BWHOUSE"                                                     # Asocia las modificaciones CSS al tema
  card-mod-card-yaml: |                                                          # Inicia bloque CSS dentro del tema
    .: |
      ha-card {                                                                 # Estilo general para todas las tarjetas
        backdrop-filter: unset !important;                                      # Elimina filtros previos
        font-family: 'Raleway, sans-serif' !important;                          # Usa la fuente definida
      }
      ha-card::before {                                                         # Capa antes del contenido (efecto vidrio)
        content: '';
        position: absolute;
        inset: 0;                                                               # Ocupa toda la tarjeta
        backdrop-filter: var(--ha-card-backdrop-filter);                        # Aplica desenfoque
        z-index: -1;                                                            # Se coloca detrás del contenido
        pointer-events: none;                                                   # No interfiere con clics
        border-radius: inherit;                                                 # Mantiene esquinas redondeadas
        box-shadow: var(--ha-card-box-shadow);                                  # Aplica la sombra definida arriba
      }

      /* Popups, selects y calendarios */
      mwc-menu,
      mwc-list,
      ha-date-picker,
      ha-date-picker-dialog,
      ha-select {
        background: var(--ha-card-background) !important;                                  # Fondo de menús y diálogos
        color: var(--gray800) !important;                              # Color del texto
        font-family: 'Raleway, sans-serif' !important;                          # Fuente
        z-index: 1000 !important;                                               # Asegura que aparezcan sobre otros elementos
      }

      /* Ajustes móviles y tamaño de fuente */
      ha-date-picker mwc-textfield,
      ha-date-picker mwc-icon-button,
      ha-select mwc-textfield,
      ha-select mwc-icon-button {
        font-size: 12px !important;                                             # Tamaño de fuente reducido en móviles
      }

      /* Para cards tipo Mushroom, Bubble y Glance */
      :host(mushroom-title-card) ha-card,
      :host(mushroom-chips-card) ha-card,
      ha-card.type-custom-bubble-card,
      :host(hui-glance-card) ha-card,
      :host(hui-heading-card) ha-card {
        background: none !important;                                            # Sin fondo
        backdrop-filter: none !important;                                       # Sin desenfoque
        box-shadow: none !important;                                            # Sin sombras
        font-family: 'Raleway, sans-serif' !important;                          # Mantiene la fuente
      }

      /* Ajustes para stack-in-card (cartas anidadas) */
      :host([type="custom:stack-in-card"]) ha-card {
        overflow: visible !important;                                           # Permite que elementos sobresalgan
        z-index: 50 !important;                                                 # Se asegura de que esté sobre otras tarjetas
        position: relative !important;                                          # Posicionamiento relativo
      }
      :host([type="custom:stack-in-card"]) * {
        font-family: 'Raleway, sans-serif' !important;                          # Fuente uniforme dentro de stack-in-card
      }

      /* Tablas de energía: sin bordes y con fondo transparente */
      .mdc-data-table,
      .mdc-data-table__table,
      .mdc-data-table__table-container,
      .mdc-data-table__row,
      .mdc-data-table__cell,
      .mdc-data-table__header-cell,
      .bullet,
      ha-card h1,
      ha-card h2,
      ha-card h3 {
        font-family: 'Raleway, sans-serif' !important;                          # Usa Raleway
        background: transparent !important;                                     # Sin fondo
        font-family: 'Raleway, sans-serif' !important;                          # Usa Raleway
        background: transparent !important;                                     # Sin fondo
        border: none !important;                                                # Sin bordes
      }

      .mdc-data-table__header-cell {
        border-bottom: 1px solid transparent !important;                        # Sin línea inferior visible
      }
      .mdc-data-table__row {
        border-bottom: 1px solid transparent !important;                        # Sin línea entre filas
      }

Por cierto, si es la primera vez que instalas un tema personalizado, debes incluir la siguiente línea en tu fichero ‘configuration.yaml’ y reiniciar Home Assistant. Esto le dice a Home Assistant que cargue todos los temas de la carpeta ‘themes’.

frontend:
  themes: !include_dir_merge_named themes

Hecho esto, solo queda que accedas a tu perfil de usuario en Home Assistant y lo selecciones en el desplegable «Tema».

Crea tu propio estilo!

Si observas el código anterior (o el del tema correspondiente), encontrarás que cada línea corresponde a un elemento o propiedad concreta. A partir de aquí la forma de trabajar para crear themes personalizados en Home Assistant va a depender de tu experiencia:

  • Si estás acostumbrado a trabajar con CSS y el inspector de tu navegador, este código no tiene secretos para ti. Sólo tienes que identificar el elemento que quieres modificar y buscarlo en el fichero.
  • Si no tienes experiencia pero no le tienes miedo, lánzate! Recuerda que son cambios estéticos y que no vas a «romper» nada. Eso sí, si eres nuevo te aconsejo que trabajes con copias de seguridad (para no perder los avances) y que si no sabes qué código corresponde al efecto que estás buscando lo consultes algún manual de CSS.
  • Si no te interesa aprender, pero aun así quieres tu tema personalizado, también puedes. Basta con que le copies el código de tu tema a una IA especializada en programación (te recomiendo Claude) y le pidas que haga los cambios.

Cambia la imagen de fondo

Si quieres dar un golpe de efecto al estilo de tu panel, sin necesidad de explorar en profundidad themes personalizados en Home Assistant, también puedes cambiar la imagen de fondo. Es algo muy sencillo, pero muy efectivo:

  1. Selecciona alguna imagen con un formato adecuado para tu panel (por ejemplo, 1920×1080px). También puedes usar una de las imágenes del tema BWHOUSE, que puedes guardar a continuación.
  1. Guarda la imagen con un nombre fácil de recordar (por ejemplo, ‘claro.jpg’ u ‘oscuro.jpg’). Por cierto, presta atención al formato de la imagen (‘.jpg’, ‘.png’, …) ya que es el típico detalle que te puede «volver loco» si no visualizas tu imagen.
  2. Accede de nuevo al almacenamiento de Home Assistant, a la ruta config > www. Esta es la carpeta donde puedes almacenar contenido que será accesible desde tu navegador. Por ejemplo, si creas una carpeta llamada «fondos» y dentro guardas el fichero ‘claro.jpg’, podrás visualizarlo introduciendo esta URL en tu navegador:
http://homeassistant.local:8123/local/fondos/claro.jpg
  1. Por último, tienes que abrir el código YAML de tu tema como te he indicado antes, y buscar la propiedad ‘background-image’ o ‘background’. Es aquí donde tienes que indicar la ruta a tu imagen. Por ejemplo, en el tema de BWHOUSE lo encontrarás en la siguiente parte:
  # ==== MODO CLARO Y OSCURO ====
  modes:                                                                        # Define los ajustes específicos para modo claro y oscuro

    light:                                                                      # Modo claro
      background-image: "url('/local/fondos/claro.jpg') center/cover no-repeat fixed"                        # Imagen de fondo
      background: "url('/local/fondos/claro.jpg') center/cover no-repeat fixed"                              # Color base de fondo
🛟 ¿Dudas? Si necesitas ayuda entra aquí 👈 🎁 Y si te ha gustado y quieres más... 🥑

¡Copiado!
20%
Descuento en todos los productos que funcionan con Curve
¡Copiado!
12%
Descuento en todos los productos de la tienda de Zemismart
¡Copiado!
10%
Descuento en todos los productos de la tienda de Shelly Spain
¡Copiado!
10%
Descuento en todos los productos probados por Aguacatec
¡Copiado!
10%
Descuento en todos los productos de Home Assistant
¡Copiado!
10%
Descuento en todos los productos de la tienda.
¡Copiado!
5%
Descuento en las pantallas de la serie CrowPanel
¡Copiado!
5%
Descuento en todos los productos de la tienda de Lilygo