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’uninput_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
avecborder: none
). - Polices larges : entre
2rem
et5rem
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 !
Derniers commentaires
# Le 19 octobre 2024 à 13:09, par nico
En réponse à : MagicMirror², ma configuration personnalisée
# Le 25 septembre 2024 à 12:01, par Teddy Payet
En réponse à : Un Nouveau Chapitre : Mon Admission dans un MBA en Intelligence Artificielle et Data Innovation
# Le 25 septembre 2024 à 11:20, par vY
En réponse à : Un Nouveau Chapitre : Mon Admission dans un MBA en Intelligence Artificielle et Data Innovation
# Le 21 juin 2024 à 13:49, par Teddy Payet
En réponse à : Home Assistant : Routine le matin avant l’école
# Le 21 juin 2024 à 10:47, par Teddy Payet
En réponse à : Ma domotique open source
# Le 16 juin 2024 à 17:15, par Eric
En réponse à : Ma domotique open source