Sommaire

HA Floorplan : contrôle domotique sur plan

Prologue

Sur la page de démo d’Home Assistant, on peut voir un plan interactif d’une maison.
C’est un “Picture Elements” avec le plan en fond de carte et des icônes positionnées aux endroits adéquats.

Petar Kožul est allé un peu plus loin en proposant le module ha-floorplan qui s’utilise avec des images au format SVG. Ce dernier a ensuite été refait en gardant le même nom.
Nous avons donc Floorplan for Home Assistant qui fait suite à Floorplan for Home Assistant.

Afin de faire le mien, je me suis donc penché sur cette solution qui s’installe avec HACS.
Je vais donc vous expliquez comment vous pouvez faire pour vous lancer dans ce chantier.

Scrampletionary

Scalable Vector Graphics

Le Scalable Vector Graphics, ou SVG, est un format de données ASCII conçu pour décrire des ensembles de graphiques vectoriels et basés sur XML. Ce format inspiré directement du VML et du PGML est spécifié par le World Wide Web Consortium.
Wikipedia

Ce qu’il faut retenir c’est qu’un fichier SVG définit des éléments comme une droite ou un cercle ce qui est différent d’une image classique où l’on définit la couleur de chaque pixel (pour fait simple).
Difficile à comprendre ? Ouvrons un SVG avec un éditeur de texte (oui c’est possible).
Voici un exemple d’image SVG (crédit : monkik) :

1
2
3
4
5
<svg xmlns="http://www.w3.org/2000/svg" height="575pt" version="1.1" viewBox="0 -192 575.96956 575" width="575pt">
<g id="surface1">
<path d="M 555.839844 44.203125 C 554.492188 41.507812 551.957031 39.605469 548.996094 39.058594 L 450.539062 20.816406 L 363.421875 4.691406 C 346.101562 1.894531 328.585938 0.492188 311.042969 0.496094 L 296.769531 0.496094 C 257.761719 0.46875 219.066406 7.453125 182.53125 21.117188 L 121.851562 43.789062 L 120.601562 44.03125 L 81.972656 51.777344 C 50.957031 57.964844 22.90625 74.355469 2.292969 98.335938 C -0.101562 101.148438 -0.671875 105.082031 0.824219 108.457031 L 6.496094 121.253906 C 8.804688 128.722656 9.855469 136.527344 9.609375 144.339844 C 9.523438 149.640625 13.75 154.007812 19.054688 154.09375 C 19.105469 154.09375 19.15625 154.09375 19.207031 154.09375 L 51.445312 154.09375 C 61.929688 184.003906 94.675781 199.75 124.585938 189.269531 C 141.046875 183.496094 153.992188 170.554688 159.757812 154.09375 L 416.238281 154.09375 C 426.722656 184.003906 459.46875 199.75 489.378906 189.269531 C 505.839844 183.496094 518.785156 170.554688 524.554688 154.09375 L 537.601562 154.09375 C 539.496094 154.089844 541.347656 153.53125 542.929688 152.480469 L 571.726562 133.28125 C 574.398438 131.5 576 128.503906 576 125.292969 L 576 86.894531 C 576.015625 85.410156 575.6875 83.941406 575.039062 82.601562 Z M 64.328125 94.976562 L 44.964844 94.976562 L 44.964844 114.175781 L 51.925781 114.175781 C 49.347656 120.78125 48.019531 127.804688 48.007812 134.894531 L 28.492188 134.894531 C 28.167969 127.5625 26.671875 120.332031 24.054688 113.476562 L 20.898438 106.351562 C 38.300781 88.027344 60.945312 75.527344 85.726562 70.574219 L 121.535156 63.394531 L 134.40625 68.789062 L 134.40625 85.109375 C 111.574219 71.777344 82.578125 75.871094 64.328125 94.996094 Z M 143.230469 142.574219 C 138.984375 163.351562 118.695312 176.753906 97.917969 172.507812 C 77.140625 168.261719 63.738281 147.976562 67.984375 127.195312 C 72.230469 106.417969 92.515625 93.015625 113.296875 97.261719 C 131.171875 100.917969 144.007812 116.644531 144.003906 134.894531 C 144.003906 137.472656 143.746094 140.046875 143.230469 142.574219 Z M 311.042969 19.695312 C 327.472656 19.695312 343.878906 21.011719 360.097656 23.621094 L 381.21875 27.527344 L 310.410156 34.777344 L 308.105469 19.695312 Z M 351.457031 89.160156 L 384.730469 87.710938 L 378.710938 96.734375 L 349 98.15625 Z M 189.222656 39.097656 C 221.097656 27.207031 254.734375 20.71875 288.742188 19.894531 L 291.269531 36.746094 L 159.527344 50.183594 Z M 182.820312 96.496094 L 331.308594 90.042969 L 328.832031 99.125 L 181.953125 106.09375 L 182.855469 125.292969 L 323.523438 118.574219 L 319.070312 134.894531 L 163.207031 134.894531 C 163.214844 123.585938 159.875 112.527344 153.605469 103.117188 L 153.605469 70.113281 L 341.992188 50.847656 L 336.609375 70.574219 L 181.992188 77.292969 Z M 508.023438 142.574219 C 503.777344 163.351562 483.492188 176.753906 462.714844 172.507812 C 441.933594 168.261719 428.53125 147.976562 432.777344 127.195312 C 437.027344 106.417969 457.3125 93.015625 478.089844 97.261719 C 495.96875 100.917969 508.804688 116.644531 508.800781 134.894531 C 508.800781 137.472656 508.539062 140.046875 508.023438 142.574219 Z M 501.820312 86.675781 C 475.238281 69.277344 439.585938 76.726562 422.191406 103.308594 C 416.050781 112.695312 412.785156 123.675781 412.804688 134.894531 L 338.96875 134.894531 L 343.683594 117.613281 L 384.453125 115.695312 C 387.5 115.550781 390.296875 113.96875 391.988281 111.433594 L 411.1875 82.632812 C 413.195312 79.625 413.339844 75.742188 411.5625 72.589844 C 409.828125 69.402344 406.414062 67.496094 402.789062 67.695312 L 356.710938 69.691406 L 362.46875 48.734375 L 448.351562 39.953125 L 540.75 57.058594 L 545.664062 66.890625 Z M 556.800781 120.15625 L 534.722656 134.894531 L 528 134.894531 C 527.996094 122.683594 524.085938 110.792969 516.847656 100.957031 L 554.285156 84.082031 L 556.828125 89.160156 Z M 556.800781 120.15625 " style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" />
</g>
</svg>

Comme vous pouvez le voir (si vous vous donné la peine de copier ce code dans un fichier et de l’enregistré au format .svg) cette suite de valeur définit l’image.
Ce qui est intéressant dans ce format, c’est qu’il est éditable : on peut changer la couleur ou y ajouter des effets par exemple.

Cascading Style Sheets

Les CSS (Cascading Style Sheets en anglais, ou « feuilles de style en cascade ») sont le code utilisé pour mettre en forme une page web.
[…]
De la même façon que HTML, CSS n’est pas vraiment un langage de programmation. C’est un langage de feuille de style, c’est-à-dire qu’il permet d’appliquer des styles sur différents éléments sélectionnés dans un document HTML. Par exemple, on peut sélectionner tous les éléments d’une page HTML qui sont paragraphes et afficher leurs textes en rouge.
MDN Web Docs

C’est le CSS qui est utilisé aujourd’hui pour mettre en forme les contenus des sites web (police, couleur …).
Pourquoi j’en parle ici ? Parce que les fichiers SVG peuvent être customisés par du CSS. Cela veut donc dire que l’on peut par exemple changer la couleur d’un icône SVG.

Principe

Dans un premier temps, on va réaliser notre fichier SVG. Il sera constitué d’une image représentant le logement et d’icônes illustrant les différents éléments domotisés de notre installation.

Ensuite, on va faire le nécessaire pour que le résultat apparaisse sur HA. On configurera donc les actions sur les éléments ajoutés.

Dans la dernière partie, on ajoutera le CSS qui permettra aux icônes de changer d’apparence en fonction de l’état de l’entité ciblé.

Application

Fichier SVG

Plan de base

Pour faire notre fichier SVG, nous allons utiliser le logiciel Inkscape.

Installation
choco install inkscape
Ou inkscape.org/release

Une fois le logiciel ouvert, il faut éditer le format du fichier.
On ouvre donc les Propriétés du document… depuis le menu Fichier ou on utilise le raccourci Maj+Ctrl+D.

/ha-floorplan/img/Screenshot_1.webp
Accès aux propriétés du document

Ainsi, on édite les propriétés en précisant les éléments suivants :

  • Général
    • Unité par défaut : px
  • Dimensions personnalisées
    • Largeur : 1920 (à adapter en fonction de votre support)
    • Hauteur : 1080 (à adapter en fonction de votre support)
    • Unités : px
  • Échelle
    • Échelle x : 1
    • Zone de vue…
      • Largeur : identique à celle des dimensions personnalisées
      • Hauteur : identique à celle des dimensions personnalisées
/ha-floorplan/img/Screenshot_2.webp
Propriétés du document

Vous avez donc la base pour faire votre plan.
À partir de là, vous avez plusieurs choix dont deux principaux :

  • Faire votre plan avec les outils de construction de Inkscape
  • Importer une image existante

Ayant un plan de chez moi, j’ai opté pour la seconde option. J’ai donc fait un glisser-déposer de mon image et je l’ai redimensionné pour qu’elle s’intègre bien au cadre. Si vous faites pareil, je vous conseille de verrouiller cette dernière sur la feuille (clic droit + Verrouiller les objets sélectionnés) afin de ne pas la déplacer par erreur plus tard.
Sachez que vous pouvez faire de joli plan avec le logiciel SweetHome3D.

Ajout des éléments

Maintenant que notre base est prête, on va pouvoir ajouter les éléments que l’on souhaite voir/contrôler sur le plan. Pour cela, il vous faut des images au format SVG.
Pour trouver vos icônes, je vous conseille le site Flaticon ainsi que TheNounProject (un compte est nécessaire sur ce dernier).

Lors de l’insertion des icônes, il vous est demandé de choisir le type d’importation. Il faut alors laisser le choix pas défaut :

/ha-floorplan/img/Screenshot_3.webp
Importation SVG
Astuce
Pour redimensionner vos icônes, maintenez la touche Ctrl afin d’en conserver les proportions.

Après avoir placé vos icônes sur le plan, il va falloir leur attribuer un ID. La méthode la plus simple est de faire que cet ID corresponde au nom de l’entité ciblé sur Home Assistant.
Pour éditer cet ID, on fait un clic droit sur l’icône et on sélectionne Propriétés de l’objet… (ou on utilise le raccourci Maj+Ctrl+O).

/ha-floorplan/img/Screenshot_4.webp
Menu contextuel d’icône SVG

Dans le menu qui s’ouvre à droite, on remplace donc l’ID :

/ha-floorplan/img/Screenshot_5.webp
Mise en place de l’ID
Attention !
Une fois toutes vos icônes traitées, refaites un tour sur les IDs. Quelques fois, j’en ai eu certains qui n’ont pas été appliqués.
Vous pouvez utiliser la touche tab pour passer rapidement d’un objet à l’autre.

J’ai aussi ajouté des champs texte qui me permettront d’afficher les températures remontées par mes capteurs pour chaque pièce.
De la même manière que pour les icônes, il faut spécifier l’ID du champ (par exemple : sensor.salon_temperature).

Dans cet article, je prendrais en exemple le cas des sensor et des light.

Enregistrez donc votre fichier final au format SVG.

Intégration à HA

Installation

On installe donc le composant “Ha Floorplan” depuis le menu Frontend du Home Assistant Community Store (HACS).
Normalement, le module JavaScript s’ajoute tout seul aux ressources. Si ce n’est pas le cas, il suffit d’y ajouté /hacsfiles/ha-floorplan/floorplan.js.
https://my.home-assistant.io/badges/lovelace_resources.svg

Copie du fichier

Maintenant il va falloir copier notre SVG sur HA.
J’ai choisi de le copier dans le dossier www situé à la racine du dossier de configuration. Afin de structurer un peu mieux la chose, je l’ai placé dans un dossier floorplan.

Mon fichier est donc dans la localisation suivante :
<dossier de configuration d'HA>/www/floorplan/floorplan.svg
Dans HA, cela se traduira par :
/local/floorplan/floorplan.svg

Ajout du plan sur HA

Nous allons intégrer notre plan avec un nouveau type de carte que nous allons installer. Cette dernière sera mise sur une vue dédiée à cela.

Pour créer une vue, sur l’interface d’HA, on clique sur l’icône  en haut à droite et on clique sur Modifier le tableau de bord.
On clique alors sur le  au niveau des vues pour en créer une nouvelle.

Pour la création de la vue, il faut que vous choisissiez le mode panneau afin que la carte créer prenne toute la largeur.

/ha-floorplan/img/Screenshot_6.webp
Création d’une vue

Sur notre vue, on clique sur AJOUTER UNE CARTE et on sélectionne une carte de type Manuel (tout en bas).

On va donc y coller le code d’une carte de type custom:floorplan-card.
Dans l’exemple ci-dessous, j’ajoute la lumière d’entité light.suspension_cuisine ainsi que le capteur de température sensor.salon_temperature.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
type: 'custom:floorplan-card'
full_height: true
config:
  image: /local/floorplan/floorplan.svg
  stylesheet: /local/floorplan/floorplan.svg
  defaults:
    hover_action: hover-info
    tap_action: more-info
  rules:
    - entity: light.suspension_cuisine
      element: light.suspension_cuisine
      tap_action:
        action: call-service
        service: homeassistant.toggle
    - entity: sensor.salon_temperature
      state_action:
        - service: floorplan.text_set
          service_data: '${entity.state ? entity.state + "°C" : "??"}'

N’ayant pas encore réalisé la partie CSS, j’ai remis le SVG en tant que stylesheet car c’est la seule méthode qui ne génère pas d’erreur sur Lovelace.

La clé entity définie l’entité sur HA et element l’ID du SVG.

Par défaut, le survol de chaque entité va dévoiler des informations dessus (hover_action: hover-info). Le clic quant a lui ouvrira les détails de l’entité (tap_action: more-info).
Sur la lumière, le clic changera l’état de cette dernière (allumer/éteindre).
La zone de texte dédié à la température affichera la valeur actuelle en ajoutant l’unité °C pour plus de commodité. En cas de valeur inconnue (ex: capteur HS), la valeur inscrite sera ??.

Information sur la syntaxe de service_data
On utilise ici l' opérateur ternaire pour réduire l’écriture conditionnelle.

Complétez donc la liste des rules avec toutes vos entités.

À ce moment-là, vous devriez donc avoir un plan fonctionnel.
Cependant, il est difficile de connaitre l’état de vos lumières d’un simple coup d’œil. Pour y remédier, je vous invite à regarder la partie suivante.

Tunning (CSS)

À la manière du couple HTML/CSS, on précise des classes aux éléments HTML dont on précise le format en CSS.

Nous allons donc ici devoir éditer notre définition des éléments de la carte afin de pouvoir les customiser en CSS.
Le gros point à noter ici est que cette configuration sera dynamique (en fonction de l’état de l’entité).
On revoit donc la définition de notre entité light.suspension_cuisine :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[...]
  rules:
    - entity: light.suspension_cuisine
      element: light.suspension_cuisine
      state_action:
        action: call-service
        service: floorplan.class_set
        service_data: 'lum-${entity.state}'
      tap_action:
        action: call-service
        service: homeassistant.toggle
[...]

Les changements d’état vont donc appeler le service floorplan.class_set avec lum-${entity.state} comme données. Sur une lumière, l’état de l’entité étant soit on, soit off. En fonction de ces états, la lumière appartiendra donc respectivement à la classe lum-on ou bien lum-off.

À partir des exemples présents dans la documentation officielle, j’ai construit le fichier CSS (que j’ai appelé floorplan.css) suivant :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
svg * {
  vector-effect: non-scaling-stroke !important;
}

/* Hover over */
.floorplan-shape:hover,
g.floorplan-hover > :not(text):hover,
g.floorplan-click > :not(text):hover,
g.floorplan-long-click > :not(text):hover,
:not(text).floorplan-hover:hover,
:not(text).floorplan-click:hover,
:not(text).floorplan-long-click:hover {
  stroke: #03a9f4 !important;
  stroke-width: 1px !important;
  stroke-opacity: 1 !important;
}

/* Lights */
.lum-on, .lum-on * {
    fill: #ffee00 !important;
    stroke: #ddbc90 !important;
}
.lum-off, .lum-off * {
    fill: #000000 !important;
    stroke: #000000 !important;
}

Les lignes [6-16] font en sorte que lorsque l’on survole les icônes, une lueur bleue apparait aux contours de ces dernières. Les lignes au-dessus font en sorte que ne résultat soit propre.
En dessous, on voit la définition des classes liées aux lumières. Lorsque la lumière est allumée, l’icône prend une couleur jaune et les contours une couleur plus foncée. À l’inverse, le noir est de mise.

On copie donc ce nouveau fichier sur HA est on remplace

1
2
3
4
5
[...]
config:
  image: /local/floorplan/floorplan.svg
  stylesheet: /local/floorplan/floorplan.css
[...]

On teste :

/ha-floorplan/img/Screenshot_7.webp
Changement visuel en fonction de l’état de l’entité

👏🎉㊗️ !!!

Epilogue

Vous arrivez à la fin de l’article, mais vous n’avez toujours pas vu mon plan…
Désolé de vous décevoir, mais je ne souhaite pas afficher publiquement le plan de mon logement, je pense que vous comprendrez. 🥺

La découverte de cet outil m’a remis un peu dans le CSS (bien que je ne m’y suis jamais vraiment intéressé). On a vu ici comment avoir un résultat convenable avec les exemples de base.
On y comprend bien que les possibilités sont immenses : je vois bien mon aspirateur robot ou mon imprimante 3D qui vibre sur le plan quand elles sont en fonctionnement.

Si vous voulez découvrir ou voir d’autre possibilité je vous invite a regarder les quelques exemples de la documentation officielle et aussi de consulter le fil de discussion sur le forum d’HA.