Construire les pages Lovelace du Magic Mirror

Une fois HACS installé et les cartes nécessaires ajoutées, l’étape suivante a été de concevoir l’interface du tableau de bord affiché sur mon écran mural. C’est dans ce troisième article que je vous présente la structure de mon dashboard, les vues que j’ai mises en place et les choix esthétiques pour une lisibilité optimale.

Une interface pensée pour un affichage vertical

Le tableau de bord que j’ai créé dans Home Assistant est nommé Magic Mirror. Il utilise un fichier Lovelace dédié (layout-magicmirror.yaml) avec l’intégration de la carte custom:masonry-layout afin de gérer précisément le placement et la largeur des éléments.

L’objectif : optimiser la lisibilité depuis une certaine distance, sur un écran vertical accroché au mur.

Chaque page ou « vue » affiche un type d’information bien spécifique. Pour éviter la surcharge, j’ai fait en sorte que chaque vue tourne automatiquement toutes les 30 secondes (on verra cela dans un prochain article).

Page 1 : heure, météo, fuseaux horaires et présence

La première vue est affichée le plus souvent dans la journée. Elle rassemble les informations de base du quotidien.

  • 🕒 Heure, date et semaine : avec better-moment-card, dans un design sobre et épuré.
  • 🌍 Fuseaux horaires : j’affiche également l’heure à La Réunion et en Guadeloupe, deux lieux qui me sont chers. Chacun a sa propre better-moment-card.
  • 🌦️ Météo actuelle à Andrésy : carte weather-forecast, sans prévisions, juste l’info du jour avec une température affichée en grand.
  • 👥 Présence des membres de la famille : une simple carte entities qui affiche si les enfants et moi sommes à la maison, en lien avec nos trackers.
  • 💬 Compliment du jour : un button-card qui affiche dynamiquement le contenu d’un input_text.

Chaque élément utilise card-mod pour harmoniser les tailles de police, les alignements et supprimer tout encadrement visuel superflu. Résultat : une page lisible, aérée, élégante.

Structure de la page 1 (extrait YAML)

views:
  - title: '1'
    type: custom:masonry-layout
    layout:
      width: 700
      max_cols: 1
    path: page-1
    theme: dark-mode
    cards:
      - type: horizontal-stack
        cards:
          - type: custom:better-moment-card
            parentStyle: |
              line-height:normal;
              padding-bottom:0em;
              display: grid;
              grid-template-columns: 1fr 1fr;
              grid-template-rows: 1fr 1fr;
              gap: 0px;
              grid-template-areas:
                'date date'
                'heure seconde'
                'semaine semaine';
            moment:
              - format: cccc, DD
                locale: fr
                timezone: Europe/Paris
                parentStyle: |
                  font-size: 2rem;
                  font-weight: 400;
                  line-height: 1;
                  margin:0;
                  padding: 0;
                  opacity: 0.5;
                  grid-area: date;
                template: |
                  {{moment}}
              - format: HH:mm
                timezone: Europe/Paris
                template: |
                  {{moment}}
                parentStyle: |
                  font-size: 5rem;
                  font-weight: 300;
                  line-height: 0.65;
                  text-align: left;
                  margin:0;
                  margin-left: 0rem;
                  padding: 0;
                  grid-area: heure;
              - format: ss
                timezone: Europe/Paris
                template: |
                  {{moment}}
                parentStyle: |
                  font-size: 2.5rem;
                  font-weight: 200;
                  line-height: 0.65;
                  text-align: left;
                  margin:0;
                  margin-left: -3rem;
                  padding: 0;
                  opacity: 0.5;
                  grid-area: seconde;
              - format: W
                timezone: Europe/Paris
                parentStyle: |
                  font-size: 2.15rem;
                  font-weight: 400;
                  line-height: 2;
                  margin:0;
                  padding: 0;
                  opacity: 0.5;
                  grid-area: semaine;
                template: |
                  Semaine {{moment}}
            card_mod:
              style: |
                ha-card {
                  border: none !important;
                  background: transparent;
                  border-width: 0;
                }
                #moment-0 {
                  opacity: 1 !important;
                }
                #moment-2 {
                  margin-left: 0.5rem !important;
                }
          - type: vertical-stack
            cards:
              - show_current: true
                show_forecast: false
                type: weather-forecast
                entity: weather.ma_ville
                forecast_type: daily
                forecast_slots: 5
                card_mod:
                  style: |
                    ha-card {
                      border: none !important;
                      background: transparent;
                      border-width: 0;
                    }
                    .temp-attribute .temp {
                      font-size: 5rem !important;
                      font-weight: 300 !important;
                      text-align: right !important;
                      line-height: 1 !important;
                    }
                    .info {
                      flex-direction: column !important;
                      align-items: flex-start;
                    }
                    .name-state, .temp-attribute {
                      width: 100%;
                      text-align: left;
                    }
      - type: horizontal-stack
        cards:
          - type: vertical-stack
            cards:
              - type: custom:better-moment-card
                parentStyle: |
                  line-height:normal;
                  padding-bottom:0em;
                  display: grid;
                  grid-template-columns: 1fr 1fr;
                  grid-template-rows: 1fr 1fr;
                  gap: 0px;
                  grid-template-areas:
                    'time region'
                    'time fuseaux';
                moment:
                  - format: HH:mm
                    timezone: Indian/Reunion
                    parentStyle: |
                      text-align:left;
                      line-height:1.25;
                      padding-top:0.2em;
                      font-size:5rem;
                      font-weight: 200;
                      grid-area: time;
                    template: |
                      {{moment}}
                  - format: HH:mm
                    timezone: Indian/Reunion
                    parentStyle: |
                      text-align:left;
                      line-height:1;
                      padding-top:0.75em;
                      margin-bottom:0;
                      font-size:2rem;
                      font-weight: 300;
                      grid-area: region;
                    template: |
                      Réunion
                  - format: HH:mm
                    timezone: Indian/Reunion
                    parentStyle: |
                      text-align:left;
                      line-height:0.5;
                      padding-top:0.2em;
                      font-size:1.5rem;
                      font-weight: 100;
                      margin-bottom:0;
                      grid-area: fuseaux;
                    template: |
                      +2:00
                card_mod:
                  style: |
                    #moment-0 {
                      font-size: 4rem !important;
                    }
              - type: custom:better-moment-card
                parentStyle: |
                  line-height:normal;
                  padding-bottom:0em;
                  display: grid;
                  grid-template-columns: 1fr 1fr;
                  grid-template-rows: 1fr 1fr;
                  gap: 0px;
                  grid-template-areas:
                    'time region'
                    'time fuseaux';
                moment:
                  - format: HH:mm
                    timezone: America/Guadeloupe
                    parentStyle: |
                      text-align:left;
                      line-height:1.25;
                      padding-top:0.2em;
                      font-size:5rem;
                      font-weight: 200;
                      grid-area: time;
                    template: |
                      {{moment}}
                  - format: HH:mm
                    timezone: America/Guadeloupe
                    parentStyle: |
                      text-align:left;
                      line-height:1;
                      padding-top:0.75em;
                      margin-bottom:0;
                      font-size:2rem;
                      font-weight: 300;
                      grid-area: region;
                    template: |
                      Guadeloupe
                  - format: HH:mm
                    timezone: America/Guadeloupe
                    parentStyle: |
                      text-align:left;
                      line-height:0.5;
                      padding-top:0.2em;
                      font-size:1.5rem;
                      font-weight: 100;
                      margin-bottom:0;
                      grid-area: fuseaux;
                    template: |
                      -6:00
                card_mod:
                  style: |
                    ha-card {
                      border: none !important;
                      background: transparent;
                      border-width: 0;
                    }
                    #moment-0 {
                      font-size: 4rem !important;
                    }
          - type: entities
            title: Présence
            entities:
              - entity: person.teddy
              - entity: person.alexandre
              ...
      - type: custom:button-card
        name: |
          [[[ return states['input_text.compliments'].state ]]]
        card_mod:
          style: |
            * {
              font-size: 1.43rem;
            }
            ha-card {
              border: none;
              background: transparent;
            }
            #name {
              width: 90%;
              font-weight: 100;
              font-size: 4.7rem !important;
              text-align: center;
              text-wrap: balance;
              overflow-wrap: break-word;
            }
    subview: false
    icon: ''
    badges: []

🧩 Le fichier complet sera détaillé en fin de série, une fois toutes les pages abordées.

Choix esthétiques

Voici les quelques règles que je me suis imposées :

  • Aucune bordure sur les cartes (card_mod avec border: none).
  • Polices larges : entre 2rem et 5rem selon le type d’information.
  • Opacité modulée : les éléments moins importants sont en gris clair.
  • Alignement à gauche pour l’heure et la météo, centré pour les compliments.

Et la suite ?

Dans le prochain article, je vous présenterai la deuxième vue de mon Magic Mirror, dédiée à l’organisation familiale : calendriers, routines, événements importants. L’objectif étant que chacun, en passant devant l’écran, sache ce qui est prévu aujourd’hui ou cette semaine.

À bientôt pour la suite de cette série domotique  !

 
Environnement de développement
VSCode
Catégorie
Home Assistant, MagicMirror, Domotique
Statut
Personnel