Hello,
Après avoir passé pas mal de temps sur des dashbords « classiques » j’ai voulu voir ce que donnait picture element et grand bien m’en fasse parce que c’est assez génial. Attention dès le départ suivant la complexité du plan, c’est très clairement un gros investissement temps. Et vu que je fais rarement dans la finesse, après un test en plan 2D, je suis finalement passé à la « 3D ».
Etant donné que j’ai creusé pas mal la question ces temps-ci. Je vais mettre ici quelques pistes de réflexion, photos, tutos, bloc code qui pourrait éventuellement vous donner des idées ou être utilisable directement. Mon travail n’est pas fini non plus pour le moment.
Clairement, je n’aurai pas réponse à tout parce que j’en suis loin d’en avoir fait le tour. Donc mon plan se décompose en un plan général, et en un plan de chaque pièce avec navigation entre le plan principal et les « sous plans ».
En chiffre, on est sur:
- machine de prod raspberrypi 5 8Go
- 23 plans
- 621 fichiers png et gif
- 47500 lignes de code pour le plan 3D et uniquement lui ( mon menu est en test sur un deuxième et fait environ 1000 lignes ).
- en heures … j’ai arrété de compter il y a longtemps.
Et maintenant pour vous mettre en appétit
menu en cours de codage / test
La charge du pi5 actuellement
voilà pour le début
Les codes des cartes en rafale:
Carte départ et arrivée du véhicule
Comme toutes les cartes avec des images à afficher suivant l’état, pour le moment imparfait mais je m’en contente, arrivée et départ véhicule.
- type: image
entity: binary_sensor.esp3_veranda_clio_ibeacon_presence
style:
top: 50%
left: 50%
width: 100%
state_image:
"off": /local/plan3D/descente.gif
"on": /local/plan3D/montee.gif
Carte section dépliable
La carte section dépliable, je met le code mais je vais passer sous bubble popup ou sans popup, je ne sais pas encore.
- type: custom:vertical-stack-in-card
style:
left: 86%
top: 63%
width: 22%
height: 5%
z-index: 8
cards:
- type: custom:fold-entity-row
head:
type: section
label: Rpi5 Home Assistant
entities:
- entity: sensor.system_monitor_utilisation_du_processeur
- entity: sensor.system_monitor_espace_libre
- entity: sensor.system_monitor_memoire_libre
- entity: sensor.system_monitor_temperature_du_processeur
- type: custom:fold-entity-row
head:
type: section
label: Rpi2 labo
entities:
- entity: binary_sensor.pi2_labo
- entity: sensor.pi2_labo_cpu_utilise
- entity: sensor.pi2_labo_memoire_utilisee
- entity: sensor.pi2_labo_cpu_temperature
- entity: sensor.pi2_labo_uptime
Carte conditionnelle affichage de flux video live sur detection
Affichage des flux vidéos en live uniquement sur detection, à améliorer encore
- type: conditional
conditions:
- entity: binary_sensor.garage_person_lens_0
state: "on"
elements:
- type: custom:stack-in-card
mode: vertical
style:
left: 35%
top: 93%
width: 14%
heigth: 14%
cards:
- type: horizontal-stack
cards:
- type: picture-entity
entity: camera.garage_fluent_lens_0
show_state: false
show_name: false
camera_view: live
Zone cliquable et multi picture element
Ici entre 2 cartes picture element, mais dans l’absolu on peut linker n’importe quoi du plan de départ.
Prérequis, tout en double, suivant ce qu’on veut afficher, 2 dashbords, 2 images 2 fond, 2 éclairages …
On commence par créer une zone cliquable sur le plan de départ, choix perso j’entoure cette zone de clic en jaune, c’est plus facile de voir ce qu’on fait, pour le reste pas le choix il faut tester pour trouver la bonne position. Attention en mode édition on a pas le même rendu que sur le plan ( il faut toujours penser que le centre de la zone cliquable sera au centre et en édition et en plan final, ça facilite le placement )
Edition vs plan final
- type: conditional
conditions:
- entity: light.lampe_labo
state: "on"
elements:
- type: image
image: /local/plan3D/piece mini/allume/labo1 allume mini.png
style:
top: 50.2%
left: 49.7%
width: auto
height: auto
transform: translate(-50%, -50%) scale(0.87)
tap_action:
action: navigate
navigation_path: /dashboard-1/labo2
- type: conditional
conditions:
- entity: light.lampe_labo
state: "off"
elements:
- type: image
image: /local/plan3D/piece mini/eteint/labo eteint mini.png
style:
top: 50.2%
left: 49.5%
width: 100px
transform: translate(-50%, -50%) rotate(-25deg)
border: 2px solid yellow
tap_action:
action: navigate
navigation_path: /dashboard-1/labo2
le centrage se fait avec le style:
top: xx%
left: xx%
ça c’est ce qui permet de déformer la zone
transform: translate(-50%, -50%) rotate(-25deg)
et la couleur
border: 2px solid yellow
le lien vers le 2eme dashboard
tap_action:
action: navigate
navigation_path: /dashboard-1/labo2
Dashbord2 j’ajoute un retour vers le plan principal
- type: image
image: /local/plan3D/piece maxi/transparent/fleche retour.png
style:
top: 45%
left: 89%
width: 15%
height: 30%
transform: translate(-50%, -50%)
tap_action:
action: navigate
navigation_path: /dashboard-1/home1
Voilà comment faire une navigation entre 2 plans
et en poussant plus loin la réflexion, je peux allumer un appareil sur le dashbord 2 et l’éteindre sur le plan principal ou l’inverse
Auto popup bubble
Perso j’utilise ça pour me prévenir visuellement (en plus d’autres alertes sonore et telegram) que je sois sur n’importe quel plan qu’une ouverture est ouverte, vous l’utiliserez pour ce bon vous semble.
On commence par créer l’entrée qui va servir à ouvrir le popup
Appareils et services > Entrées > Créer une entrée > groupe > groupe de capteurs binaires et dedans on ajoute tout ce qu’on veut surveiller ( ici tous mes ouvrants )
Attention ça peut rapidement devenir lourd, parce qu’il faut mettre le code partout ou vous voulez qu’il apparaisse, pour le moment pas trouvé d’autre moyen, c’est sans doute plus facile à gérer avec browsermod que je n’utilise pas.
le code
- type: custom:mod-card
style:
left: 17.5%
top: 20%
height: 52%
z-index: 12
card:
type: vertical-stack
cards:
- type: custom:bubble-card
card_type: pop-up
icon: mdi:security
hash: "#securite"
card_layout: normal
width_desktop: 400px
name: Securite
trigger_entity: binary_sensor.ouvrants_maison
trigger_state: "on"
trigger_close: true
close_by_clicking_outside: false
- type: custom:bubble-card
card_type: separator
name: RDC
- type: custom:bubble-card
card_type: button
button_type: name
card_layout: large-1-rows
sub_button:
- entity: binary_sensor.porte_entree_contact
name: P entree
icon: mdi:door-closed
show_name: true
show_state: false
show_background: false
- entity: binary_sensor.porte_salon_contact
name: P salon
icon: mdi:door-closed
show_name: true
show_state: false
show_background: false
- entity: binary_sensor.porte_labo_labopi2
name: P labo
icon: mdi:door-closed
show_name: true
show_state: false
show_background: false
card_mod:
style: |
ha-card {
background: {% if
is_state('binary_sensor.porte_entree_contact', 'on') or
is_state('binary_sensor.porte_salon_contact', 'on') or
is_state('binary_sensor.porte_labo_labopi2', 'on')
%} rgba(255, 0, 0, 0.2)
{% else %} rgba(180, 255, 180, 0.15)
{% endif %} !important;
}
styles: |
.bubble-button-card-container {
background: rgba(var(--rgb-secondary-text-color), 0.2) !important;
box-shadow: none;
border-radius: 15px !important; # Ajustez la valeur ici
}
.bubble-sub-button-1 > ha-icon {
color: ${hass.states['binary_sensor.porte_entree_contact'].state === 'on' ? 'red'
: 'green'} !important;
}
.bubble-sub-button-2 > ha-icon {
color: ${hass.states['binary_sensor.porte_salon_contact'].state === 'on' ? 'red'
: 'green'} !important;
}
.bubble-sub-button-3 > ha-icon {
color: ${hass.states['binary_sensor.porte_labo_labopi2'].state === 'on' ? 'red'
: 'green'} !important;
}
.card-content {
width: 100%;
margin: 0 !important;
}
.bubble-sub-button {
height: 30px !important;
width: 63px !important;
}
.bubble-sub-button-container {
width: 100% !important; # Étend la largeur sur toute la carte
display: flex !important;
justify-content: center !important; # Centre les sous-boutons horizontalement
align-items: center !important; # Aligne les boutons verticalement
}
.bubble-sub-button-icon {
--mdc-icon-size: 18px !important;
}
.bubble-name-container {
margin-right: -10px !important;
}
show_icon: false
scrolling_effect: false
- type: custom:bubble-card
card_type: separator
name: Veranda
- type: custom:bubble-card
card_type: button
button_type: name
card_layout: large-1-rows
sub_button:
- entity: binary_sensor.fenetre1_verandapi2
name: F1
icon: mdi:window-closed
show_name: true
show_state: false
show_background: false
- entity: binary_sensor.fenetre2_verandapi2
name: F2
icon: mdi:window-closed
show_name: true
show_state: false
show_background: false
- entity: binary_sensor.fenetre3_verandapi2
name: F3
icon: mdi:window-closed
show_name: true
show_state: false
show_background: false
- entity: binary_sensor.porte1_verandapi2
name: P1
icon: mdi:door-closed
show_name: true
show_state: false
show_background: false
- entity: binary_sensor.porte2_verandapi2
name: P2
icon: mdi:door-closed
show_name: true
show_state: false
show_background: false
- entity: binary_sensor.fenetre4_verandapi2
name: F4
icon: mdi:window-closed
show_name: true
show_state: false
show_background: false
- entity: binary_sensor.fenetre5_verandapi2
name: F5
icon: mdi:window-closed
show_name: true
show_state: false
show_background: false
- entity: binary_sensor.fenetre6_verandapi2
name: F6
icon: mdi:window-closed
show_name: true
show_state: false
show_background: false
card_mod:
style: |
ha-card {
background: {% if
is_state('binary_sensor.fenetre1_verandapi2', 'on') or
is_state('binary_sensor.fenetre2_verandapi2', 'on') or
is_state('binary_sensor.fenetre3_verandapi2', 'on') or
is_state('binary_sensor.porte1_verandapi2', 'on') or
is_state('binary_sensor.porte2_verandapi2', 'on') or
is_state('binary_sensor.fenetre4_verandapi2', 'on') or
is_state('binary_sensor.fenetre5_verandapi2', 'on') or
is_state('binary_sensor.fenetre6_verandapi2', 'on')
%} rgba(255, 0, 0, 0.2)
{% else %} rgba(180, 255, 180, 0.15)
{% endif %} !important;
}
styles: |
.bubble-button-card-container {
background: rgba(var(--rgb-secondary-text-color), 0.2) !important;
box-shadow: none;
border-radius: 15px !important; # Ajustez la valeur ici
}
.bubble-sub-button-1 > ha-icon {
color: ${hass.states['binary_sensor.fenetre1_verandapi2'].state === 'on' ? 'red'
: 'green'} !important;
}
.bubble-sub-button-2 > ha-icon {
color: ${hass.states['binary_sensor.fenetre2_verandapi2'].state === 'on' ? 'red'
: 'green'} !important;
}
.bubble-sub-button-3 > ha-icon {
color: ${hass.states['binary_sensor.fenetre3_verandapi2'].state === 'on' ? 'red'
: 'green'} !important;
}
.bubble-sub-button-4 > ha-icon {
color: ${hass.states['binary_sensor.porte1_verandapi2'].state === 'on' ? 'red'
: 'green'} !important;
}
.bubble-sub-button-5 > ha-icon {
color: ${hass.states['binary_sensor.porte2_verandapi2'].state === 'on' ? 'red'
: 'green'} !important;
}
.bubble-sub-button-6 > ha-icon {
color: ${hass.states['binary_sensor.fenetre4_verandapi2'].state === 'on' ? 'red'
: 'green'} !important;
}
.bubble-sub-button-7 > ha-icon {
color: ${hass.states['binary_sensor.fenetre5_verandapi2'].state === 'on' ? 'red'
: 'green'} !important;
}
.bubble-sub-button-8 > ha-icon {
color: ${hass.states['binary_sensor.fenetre6_verandapi2'].state === 'on' ? 'red'
: 'green'} !important;
}
.card-content {
width: 100%;
margin: 0 !important;
}
.bubble-sub-button {
height: 30px !important;
width: 63px !important;
}
.bubble-sub-button-container {
width: 100%;
justify-content: space-between !important;
}
.bubble-sub-button-icon {
--mdc-icon-size: 18px !important;
}
.bubble-name-container {
margin-right: -10px !important;
}
show_icon: false
scrolling_effect: false
cdt