🎹 [Mon Dashboard] - @Clemalex

:no_mouth: c’est l’interface Lovelace qui le fait quand tu retourne sur l’édition
 (je suis en storage, pas en yaml) :wink:

C’est quoi le « storage » ?

Le mode par dĂ©faut : gestion des tableaux de bord par l’interface graphique :

https://www.home-assistant.io/lovelace/dashboards-and-views/

qu’est ce qui justifie ce choix au juste ?
Dsl je fais un peu l’enfant :rofl: « pourquoi ?? », « parce que », « parce que quoi ? » :grimacing:

Quel choix ?

Pas de soucis, ca permet d’approfondir

Au contraire, j’aime bien
 :innocent:

Le choix d’ĂȘtre en storage plutĂŽt qu’en yaml ?

C’est plutĂŽt Ă  toi de me dire pourquoi t’es passĂ© en yaml :stuck_out_tongue_winking_eye:

:rofl:

Edit : @Pierre_Ma es-tu seulement en mode Yaml ?

Le mode yaml est fait pour structurer finement les tableaux de bord et permet lutilisation de modùle
 :innocent:

Si tu veux approfondir, regarde la configuration de @Sylvain_G prĂ©sente dans l’awesome list :

J’en ai aucune idĂ©e
 j’ai gardĂ© la configuration par default.
Il faut que j’approfondisse le sujet effectivement. Mais il faut que je me fasse un liste des prioritĂ©s ^^ je pars dans tout les sens lĂ  :sweat_smile:

Moi aussi au début
 :innocent:

Je me servais de la shopping list pour garder en mémoire ce que je voyais et voulais approfondir


TrĂšs bonne idĂ©e, je viens de l’installer !

Si une de mes enceintes diffuse de la musique (button-card + card-mod) :

animate

code de la carte
name: Sonorisation
show_name: true
icon: 'mdi:speaker'
styles:
  custom_fields:
    wave:
      - background-color: 'rgba(0, 0, 0, 0)'
      - position: absolute
      - right: 5%
      - top: 5%
      - font-size: 13px
      - line-height: 20px
      - display: |
          [[[
            if (states["input_boolean.test2"].state == 'on') return '';
            else return 'none';
          ]]] 
      - '--icon-color': |
          [[[
            if (states["input_boolean.test2"].state == 'on') return 'var(--mail-color)';
            else return 'var(--primary-color)';
          ]]]
  card:
    - border: 2px solid var(--primary-color)
    - border-radius: 10px
  icon:
    - color: var(--primary-color)
  name:
    - font-variant: small-caps
    - color: var(--primary-color)
custom_fields:
  wave: |
    [[[
     return `
       <div class="loader-container">
         <div class="loader-3">
          <div class="item-1"></div>
          <div class="item-2"></div>
          <div class="item-3"></div>
          <div class="item-4"></div>
          <div class="item-5"></div>
         </div>
       </div>`
    ]]]   
type: 'custom:button-card'
style: |
  .loader-3{
    width: 40px;
    height: 40px;
  }

  .loader-3 div {
    height: 100%;
    width: 3px;
    display: inline-block;
  }
  .loader-3 div .item-1{
    height: 50%;
  }
  .loader-3 .item-1 {
    animation: loader-3-first-div 1.2s infinite linear;
    background-color: red;
  }

  .loader-3 .item-2 {
    animation: loader-3-second-div 1.2s infinite linear;
    animation-delay: -1.1s;
    background-color: darkorange;

  }

  .loader-3 .item-3 {
    animation: loader-3-third-div 1.2s infinite linear;
    animation-delay: -1.0s;
    background-color: gold;

  }

  .loader-3 .item-4 {
    animation: loader-3-fourth-div 1.2s infinite linear;
    animation-delay: -0.9s;
    background-color: green;
  }

  .loader-3 .item-5 {
    animation: loader-3-last-div 1.2s infinite linear;
    animation-delay: -0.8s;
    background-color: DarkOrchid;
  }

  @keyframes loader-3-first-div {
    25%,75% {
      transform: scaleY(0.2);
    }
    0%,50%,100%{
      transform: scaleY(0.6);
    }
  }  
  @keyframes loader-3-second-div {
    25%,75% {
      transform: scaleY(0.4);
    }
    0%,50%,100%{
      transform: scaleY(1);
    }
  }  
  @keyframes loader-3-third-div {
    25%,75% {
      transform: scaleY(0.4);
    }
    0%,50%,100%{
      transform: scaleY(1);
    }
  }  
  @keyframes loader-3-fourth-div {
    25%,75% {
      transform: scaleY(0.4);
    }
    0%,50%,100%{
      transform: scaleY(1);
    }
  }  
  @keyframes loader-3-last-div {
    25%,75% {
      transform: scaleY(0.2);
    }
    0%,50%,100%{
      transform: scaleY(0.6);
    }
  }

Inspiré par https://codepen.io/ruslan_khomiak/pen/MbqWaK

Toujours dans les animations :

Si le facteur est passĂ©, une automatisation met Ă  Vrai un boolĂ©en (l’animation de la porte se fait si une ouverture (porte,fenetre,garage,cagibi) est ouverte et n’est normalement pas la mĂȘme entitĂ© que l’entrĂ©e boolĂ©enne)

animate

Code de la carte
entity: input_boolean.test2
name: Ouvertures
show_name: true
state:
  - icon: 'mdi:door-open'
    value: 'on'
  - icon: 'mdi:door'
    value: 'off'
styles:
  custom_fields:
    courrier:
      - border-radius: 50%
      - position: absolute
      - right: 5%
      - top: 5%
      - font-size: 13px
      - line-height: 20px
      - display: |
          [[[
            if (states["input_boolean.test2"].state == 'on') return '';
            else return 'none';
          ]]] 
      - '--icon-color': |
          [[[
            if (states["input_boolean.test2"].state == 'on') return 'var(--mail-color)';
          ]]]
  card:
    - border-radius: 10px
    - border: 2px solid var(--primary-color)
  icon:
    - color: var(--primary-color)
  name:
    - font-variant: small-caps
    - color: var(--primary-color)
custom_fields:
  courrier: |
    [[[
     return `
     <ha-icon
       icon="mdi:mail"
       style="width: 30px; height: 30px; color: var(--icon-color);">
       </ha-icon>`
    ]]]   
type: 'custom:button-card'
style: |
  @keyframes pulsation {
    0% {
      box-shadow: var(--shadow-mail-color-hidden);
    }
    50% {
      transform: scale(1);
      box-shadow: var(--shadow-mail-color-hidden);
    }      
    25%,75% {
      transform: scale(1.2);
      box-shadow: var(--shadow-mail-color-visible);
    }    
    100% {
      box-shadow: var(--shadow-mail-color-hidden);
      transform: scale(1);
    }
  }
  #courrier{
   animation:
    {% if is_state('input_boolean.test2', 'on') %}
      pulsation 1.3s ease infinite
    {% else %}
      none
    {% endif %}
    ;

Les variables Ă  ajouter au thĂšme :

      mail-color: "rgba(247, 193, 57)"
      shadow-mail-color-visible: "0px 0px 0px 20px rgba(247, 193, 57, 0.3) inset, 0px 0px 0px 20px rgba(247, 193, 57, 0.3)"
      shadow-mail-color-hidden: "0px 0px 0px 20px transparent inset, 0px 0px 0px 20px 

Tes boutons sont trĂšs bien fait et super pratiques. Beau travail!

Merci. Ça fait plaisir. Si c’est possible c’est grñce aux superbes cartes :blush::star_struck::heart_eyes:.

Le but premier n’est pas forcĂ©ment d’utiliser ce que je montre (vous pouvez bien sĂ»r) mais c’est surtout de donner des exemples concrets de ce que l’on peux faire :wink: (et on peut en faire :yum: :sweat_smile:)

Mise à jour de l’animation :

animate

Code de la carte
style: |
  @keyframes pulsation {
    25% {
      transform: scale(1.3);

    }  
    100% {
      box-shadow: 0 0 0 40px rgba(128, 0, 128, 0), 0 0 0 6px rgba(128, 0, 128, 0) inset;
      transform: scale(1)
    } 
  }
  #courrier{
   animation:
    {% if is_state('input_boolean.test2', 'on') %}
      pulsation 1s infinite ease-in;
    {% else %}
      None
    {% endif %}
    ;
entity: input_boolean.test2
name: Ouvertures
show_name: true
state:
  - icon: 'mdi:door-open'
    value: 'on'
  - icon: 'mdi:door'
    value: 'off'
styles:
  custom_fields:
    courrier:
      - border-radius: 50%
      - box-shadow: >-
          rgb(247 193 57 / 60%) 0px 0px 0px 0px, rgb(247 193 57 / 60%) 0px 0px
          0px 6px inset
      - position: absolute
      - right: 5%
      - top: 5%
      - font-size: 13px
      - line-height: 20px
      - display: |
          [[[
            if (states["input_boolean.test2"].state == 'on') return '';
            else return 'none';
          ]]] 
      - '--icon-color': |
          [[[
            if (states["input_boolean.test2"].state == 'on') return 'var(--mail-color)';
          ]]]
  card:
    - border-radius: 10px
    - border: 2px solid var(--primary-color)
  icon:
    - color: var(--primary-color)
  name:
    - font-variant: small-caps
    - color: var(--primary-color)
custom_fields:
  courrier: |
    [[[
     return `
     <ha-icon
       icon="mdi:mail"
       style="width: 30px; height: 30px; color: var(--icon-color);">
       </ha-icon>`
    ]]]   
type: 'custom:button-card'

Inspiration : https://codepen.io/matchboxhero/pen/pWLOQb?editors=1100

Apparemment, je n’ai jamais publiĂ© ma carte pour l’aspirateur (je ne l’utilise quasiment jamais, car la commande vocale est plus rapide) :

Code du premier bouton
color: auto
color_type: icon
confirmation:
  text: Nettoyage de la Maison
entity: input_select.vacuum_aspiro_in_progress
icon: 'mdi:home'
name: Maison
show_icon: true
show_label: false
show_last_changed: false
show_name: true
show_state: false
state:
  - styles:
      icon:
        - animation: blink 0.9s ease infinite
      name:
        - animation: blink 0.9s ease infinite
    value: Maison
styles:
  card:
    - border-radius: 10px
    - border: '2px solid #257236'
    - height: 75px
    - width: 75px
    - margin: 5px 5px 0px 11px
    - padding: 0px 0px
    - background-color: '#319847'
  grid:
    - position: relative
  icon:
    - position: absolute
    - left: 2px
    - top: '-15px'
    - color: var(--light-text-color)
  name:
    - position: absolute
    - left: 5px
    - bottom: 10px
    - font-variant: small-caps
    - font-size: 14px
    - color: var(--light-text-color)
tap_action:
  action: call-service
  service: script.aspiro_maison
type: 'custom:button-card'

pour le rendu sur mon tĂ©lĂ©phone j’ai du mettre un margin de 11px sur la gauche pour le premier bouton :

card:
  - margin: 5px 5px 0px 11px

Les trois boutons suivant sur la ligne n’en ont pas :

card:
  - margin: 5px 5px 0px 0px

la programmation du chauffage :

Affichage d’un timer directement sur la carte :

animate

(on peut imaginer un changement de couleur de l’enceinte, du nom, etc. suivant l’état du timer)

Code de la carte
name: |
  [[[
    var finishes_at = new Date(states['timer.hacf_timer'].attributes.finishes_at);
    var remaining = states['timer.hacf_timer'].attributes.remaining;
    if (finishes_at == 'Invalid Date') {
      if (remaining) {
        var remaining_first_element = remaining.split(':');
        if (remaining_first_element[0].length < 2 ) {
          if (remaining_first_element[0] == '0' ) {
            remaining_first_element = remaining_first_element.splice(1);
          } else {
            remaining_first_element[0] = '0' + remaining_first_element[0];
          }

        }
          result = remaining_first_element.toString().replaceAll(',',':');

      } else {
        result = 'Sonorisation';
      }
    } else {
      var timestamp = finishes_at.getTime();
      var timestamp_now = Date.now();
      var difference_between = timestamp - timestamp_now
      var time_remaining = new Date(difference_between).toUTCString();
      var hours = time_remaining.split(' ');
      var hours_split = hours[4].split(':');
      if (parseInt(hours_split[0]) == 0 ) {
        hours_split = hours_split.splice(1);
      }
      var result = hours_split.toString().replaceAll(',',':');;
    }
    return result;
  ]]]
triggers_update:
  - sensor.aleatoire
show_name: true
icon: 'mdi:speaker'
styles:
  custom_fields:
    wave:
      - background-color: 'rgba(0, 0, 0, 0)'
      - position: absolute
      - right: 5%
      - top: 5%
      - font-size: 13px
      - line-height: 20px
      - display: |
          [[[
            if (states["input_boolean.test2"].state == 'on') return '';
            else return 'none';
          ]]] 
      - '--icon-color': |
          [[[
            if (states["input_boolean.test2"].state == 'on') return 'var(--mail-color)';
            else return 'var(--primary-color)';
          ]]]
  card:
    - border: 2px solid var(--primary-color)
    - border-radius: 10px
  icon:
    - color: var(--primary-color)
  name:
    - font-variant: small-caps
    - color: var(--primary-color)
custom_fields:
  wave: |
    [[[
     return `
       <div class="loader-container">
         <div class="loader-3">
          <div class="item-1"></div>
          <div class="item-2"></div>
          <div class="item-3"></div>
          <div class="item-4"></div>
          <div class="item-5"></div>
         </div>
       </div>`
    ]]]   
type: 'custom:button-card'
style: |
  .loader-3{
    width: 40px;
    height: 40px;
  }

  .loader-3 div {
    height: 100%;
    width: 3px;
    display: inline-block;
  }
  .loader-3 div .item-1{
    height: 50%;
  }
  .loader-3 .item-1 {
    animation: loader-3-first-last-div 1.2s infinite linear;
    background-color: red;
  }

  .loader-3 .item-2 {
    animation: loader-3-middle-div 1.2s infinite linear;
    animation-delay: -1.1s;
    background-color: darkorange;

  }

  .loader-3 .item-3 {
    animation: loader-3-middle-div 1.2s infinite linear;
    animation-delay: -1.0s;
    background-color: gold;

  }

  .loader-3 .item-4 {
    animation: loader-3-middle-div 1.2s infinite linear;
    animation-delay: -0.9s;
    background-color: green;
  }

  .loader-3 .item-5 {
    animation: loader-3-first-last-div 1.2s infinite linear;
    animation-delay: -0.8s;
    background-color: DarkOrchid;
  }

  @keyframes loader-3-first-last-div {
    25%,75% {
      transform: scaleY(0.2);
    }
    0%,50%,100%{
      transform: scaleY(0.6);
    }
  }  
  @keyframes loader-3-middle-div {
    25%,75% {
      transform: scaleY(0.4);
    }
    0%,50%,100%{
      transform: scaleY(1);
    }
  }  

Il faut ajouter une entité timer:

timer:
  hacf_timer:
    duration: "01:00:05"

Il faut ajouter une entité aléatoire (qui sert de déclencheur pour mettre à jour la carte button-card):

sensor:
  - platform: random
    name: Aléatoire
    maximum: 999

Il faut une automatisation qui s’éxĂ©cute toutes les secondes afin de mettre Ă  jour cette entitĂ© :

alias: mise a jour de sensor.aleatoire
description: Mise Ă  jour pour affichage des timers sur les cartes
trigger:
  - platform: time_pattern
    seconds: '*'
condition: []
action:
  - service: homeassistant.update_entity
    target:
      entity_id: sensor.aleatoire
mode: restart

Ah pas bien tout sa
 sa donne des ideeeeeees mais ou commencer!

Une chose m’intĂ©resse encore. J’ai vu qu’on pouvais faire un floorplan ou visuellement on peut trĂšs bien reprĂ©senter les Ă©tage et pour les lumiĂšres ou mĂȘme le chauffage par piĂšces etc etc sa serai vraiment super.
J’ai dĂ©jĂ  commencer par dessiner les floorplan, sa prend tu temps mais sa vaut le rĂ©sultat. Par contre pour l’intĂ©grer je plante complĂ©tement pour le moment.

je te conseille de te rendre dans PrĂ©sentations et de chercher une prĂ©sentation qui l’utilise
 :upside_down_face: :wink: afin de demander conseille :+1: