🎹 [Mon Dashboard] - @Clemalex

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

4 « J'aime »

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 
1 « J'aime »

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

1 « J'aime »

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:)

1 « J'aime »

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

1 « J'aime »

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:

Superbe taf, felicitations

Peux-tu donner plus de détails sur la carte aspirateur avec les boutons sur les differentes pieces ? Merci :slight_smile:

Tu peux le faire avec un peu de sorcellerie sans avoir besoin de sensor random qui se met Ă  jour :wink:

type: custom:button-card
variables:
  update: |
    [[[
      if (CONDITION POUR DECLANCHER LE REFRESH TOUS LES X) {
        if (this._myTimer === undefined) {
          this._myTimer = window.setInterval(() => { this.update() }, 1000 * 10) // 1000 * 10 = Temps entre les refresh en millisecondes
        }
      } else {
        if (this._myTimer !== undefined) {
          window.clearInterval(this._myTimer);
          delete this._myTimer;
        }
      }
    ]]]
xxx: RESTE DE LA CONFIG...
1 « J'aime »

J’ai mis à jour le post :+1:

https://forum.hacf.fr/t/mon-dashboard-clemalex/737/36?u=clemalex

Tu as corrigĂ© n’est ce pas ? sinon je commence a devenir fou
 :wink:

Merci pour le partage (de tes cartes, de tes réponses ici et là-bas, du temps passé !).

:heart_eyes:

C’est clair que c’est beaucoup plus sympa comme ceci :+1:

1 « J'aime »

C’est documentĂ© et je ne le trouve pas ou tu le sors de ton chapeau (d’oĂč la sorcellerie :wink: ) ?

Non, pas documentĂ©, c’est juste du pur javascript :slight_smile:

Oui, j’ai edit le post :wink:

1 « J'aime »