[Mon Dashboard] - @kaoru

Merci c’est mieux, ci-dessous ma capture :


mais j’ai pas l’animation curieusement dont tu as parlé; l’appui long fonctionne ma card se retourne

Merci, je devais le faire mais j’ai complètement oublié. Je viens de le faire du coup

c’est normal que tu n’as plus l’animation de chargement sur le button-card. C’est juste ce que fait le template base

Par contre la question : Pourquoi loader fait bugger le button-card ? :thinking:

Tu peux m’envoyer le contenu du button_card_templates.yaml, stp ?

merci de ton aide, j’avoue que je suis un peu dépassé :slight_smile:

ci-joint le code du button_card_templates.yaml :

  base:
    aspect_ratio: 1/1
    show_state: true
    show_icon: false
    state:
      - value: 'on'
        styles:
          card: [background-color: 'rgba(255, 255, 255, 0.8)']
          name: [color: 'rgba(0, 0, 0, 0.6)']
          state: [color: 'rgba(0, 0, 0, 0.6)']
    tap_action:
      ui_sound: |
        [[[ if (entity.state === 'off' && states['switch.fullykiosk_screensaver'].state === 'off') {
        hass.callService('media_player', 'play_media', {entity_id: 'media_player.tablet', media_content_id: '/local/sound/on.m4a', media_content_type: 'music'}); }
        else if (entity.state === 'on' && states['switch.fullykiosk_screensaver'].state === 'off') {
        hass.callService('media_player', 'play_media', {entity_id: 'media_player.tablet', media_content_id: '/local/sound/off.m4a', media_content_type: 'music'}); } ]]]
      action: toggle
      haptic: light
    styles:
      name:
        [top: 57.7%, left: 11%, line-height: 2vw, position: absolute]
      state:
        [top: 74%, left: 11%, line-height: 2vw, position: absolute]
      card:
        [font-family: Sf Display, letter-spacing: 0.05vw, font-weight: 400, color: 'rgba(255, 255, 255, 0.3)', font-size: 1.34vw, 
        background-color: 'rgba(115, 115, 115, 0.2)', border-radius: 0.8vw, box-shadow: none, transition: none]
      custom_fields:
        circle:
          [top: 8.5%, left: 56.2%, width: 3.5vw, position: absolute, letter-spacing: 0.03vw]

  loader:
    custom_fields:
      loader: >
        [[[ if (states[entity.entity_id.replace(entity.entity_id.split('.')[0], 'input_boolean')].state === 'on') { 
        return '<img src="/local/loader.svg" width="100%">'; } ]]]
    styles:
      custom_fields:
        loader:
          [filter: "[[[ return entity.state === 'off' ? 'invert(1)' : 'none'; ]]]", 
           top: 3%, left: 60%, width: 3.7vw, position: absolute, opacity: 0.6]

  person:
    template: ['base']
    show_entity_picture: true
    state_display: >
      [[[ return entity.state === 'home' ? 'Ja' : 'Nej'; ]]]
    state:
      - value: 'home'
        styles:
          card: [background-color: 'rgba(255, 255, 255, 0.8)']
          name: [color: 'rgba(0, 0, 0, 0.6)']
          state: [color: 'rgba(0, 0, 0, 0.6)']
    styles:
      entity_picture: 
        [clip-path: circle(50% at center), top: 7.5%, left: 11.2%, width: 3vw, position: absolute]
    custom_fields:
      circle: >
        [[[ function time(c) {
        var s = (c / 1000); var m = (c / (1000 * 60)); var h = (c / (1000 * 60 * 60)); var d = (c / (1000 * 60 * 60 * 24));
        if (s < 60) { return parseInt(s) + 's'; } else if (m < 60) { return parseInt(m) + 'm'; }
        else if (h < 24) { return parseInt(h) + 'h'; } else { return parseInt(d) + 'd'; }
        }
        const last_changed = time(Date.now() - Date.parse(states[entity.entity_id].last_changed));
        const stroke_color = entity.state === 'home' ? '#b2b2b2' : '#313638'; 
        const fill_color = entity.state === 'home' ? 'none' : '#FFFFFF08';
        return `<svg viewBox="0 0 50 50"><circle cx="25" cy="25" r="20.5" stroke="${stroke_color}" stroke-width="1.5" fill="${fill_color}" />
        <text x="50%" y="54%" fill="#8d8e90" font-size="14" text-anchor="middle" alignment-baseline="middle">${last_changed}</text></svg>`; ]]]

  light:
    template: ['base']
    custom_fields:
      circle: >
        [[[ if (entity.state === 'on' && entity.attributes.brightness) {
        const brightness = Math.round(entity.attributes.brightness / 2.54);
        const radius = 20.5; const circumference = radius * 2 * Math.PI; 
        return `<svg viewBox="0 0 50 50"><circle cx="25" cy="25" r="${radius}" stroke="#b2b2b2" stroke-width="1.5" fill="none" style="
        transform: rotate(-90deg); transform-origin: 50% 50%; stroke-dasharray: ${circumference}; stroke-dashoffset: ${circumference - brightness / 100 * circumference};" />
        <text x="50%" y="54%" fill="#8d8e90" font-size="14" text-anchor="middle" alignment-baseline="middle">${brightness}<tspan font-size="10">%</tspan></text></svg>`; } ]]]
    hold_action:
      action: call-service
      service: browser_mod.popup
      service_data:
        title: '[[[ return entity.attributes.friendly_name ]]]'
        deviceID: this
        card:
          type: entities
          entities:
            - type: custom:light-popup-card
              entity: '[[[ return entity.entity_id ]]]'
              icon: none
              fullscreen: false
              brightnessWidth: 130px
              brightnessHeight: 360px
              borderRadius: 1.7em
              sliderColor: '#c7c7c7'
              sliderTrackColor: rgba(25, 25, 25, 0.9)
              actionSize: 4.5em
              actionsInARow: 2
              actions:
                - service: light.turn_on
                  service_data:
                    entity_id: '[[[ return entity.entity_id ]]]'
                    color_temp: 153
                  color: "#d8d9e1"
                - service: light.turn_on
                  service_data:
                    entity_id: '[[[ return entity.entity_id ]]]'
                    color_temp: 326
                  color: "#d5b08d"
                - service: light.turn_on
                  service_data:
                    entity_id: '[[[ return entity.entity_id ]]]'
                    color_temp: 500
                  color: "#ce944b"
                - service: browser_mod.popup
                  service_data:
                    title: '[[[ return entity.attributes.friendly_name ]]]'
                    deviceID: this
                    card:
                      type: entities
                      show_header_toggle: false
                      entities:
                        - entity: '[[[ return entity.entity_id ]]]'
                          secondary_info: last-changed
                        - type: custom:light-entity-card
                          entity: '[[[ return entity.entity_id ]]]'
                          brightness: false
                          color_temp: true
                          full_width_sliders: true
                          hide_header: true
                          show_slider_percent: true
                          smooth_color_wheel: true
                          consolidate_entities: true

  shared_media:
    tap_action:
      action: >
        [[[ if (entity.state === 'off' || entity.state === 'idle' || entity.state === 'standby') {
        return 'none'; } else { return 'call-service'; } ]]]
      service: media_player.media_play_pause
      service_data:
        entity_id: '[[[ return entity.entity_id ]]]'
    double_tap_action:
      action: call-service
      service: >
        [[[ if (entity.state === 'off' || entity.state === 'idle' || entity.state === 'standby') {
        return 'media_player.turn_on'; } else { return 'media_player.turn_off'; } ]]]
      service_data:
        entity_id: '[[[ return entity.entity_id ]]]'
    styles:
      card:
        [color: "[[[ if (entity.state === 'off' || entity.state === 'idle' || entity.state === 'standby' || 
        entity.state === 'unknown' || entity.state === 'unavailable') { return 'rgba(255, 255, 255, 0.3)'; }
        if ((entity.state != 'off' && entity.state != 'idle' && entity.state != 'standby') && (entity.attributes.entity_picture == null)) {
        return 'rgba(0, 0, 0, 0.6)'; } else { return '#efefef'; } ]]]", 
        text-shadow: "[[[ if (entity.attributes.entity_picture == null) return 'none'; 
        else return '1px 1px 5px rgba(18, 22, 23, 0.9)' ; ]]]"]

  media:
    template: ['base', 'shared_media']
    styles:
      custom_fields:
        icon:
          [opacity: "[[[ return entity.attributes.entity_picture == null ? 1 : 0; ]]]", 
          top: 11.5%, left: 11.5%, width: 2.9vw, position: absolute, fill: '#9da0a2']
      card:
        [background-color: none, background-size: cover,
        background-image: 
        "[[[ if (entity.state === 'off' || entity.state === 'idle' || entity.state === 'standby' || 
        entity.state === 'unknown' || entity.state === 'unavailable') {
        return 'linear-gradient(0deg, rgba(115, 115, 115, 0.2) 0%, rgba(115, 115, 115, 0.2) 100%)'; }
        if ((entity.state != 'off' && entity.state != 'idle' && entity.state != 'standby') && (entity.attributes.entity_picture == null)) {
        return 'linear-gradient(0deg, rgba(255, 255, 255, 0.8) 0%, rgba(255, 255, 255, 0.8) 100%)'; }
        else { return 'linear-gradient(0deg, rgba(0,0,0,.8) 0%, rgba(0,0,0,0) 100%), url(' + entity.attributes.entity_picture + ')'; } ]]]"]

  conditional_media:
    template: ['base', 'shared_media']
    state_display: >
      [[[ if (entity.attributes.media_title === 'Nothing playing' || entity.attributes.media_title === 'No title' && entity.state === 'paused' ) { return 'Inget spelas'; }
      if (entity.attributes.media_title === 'No title' && entity.state === 'playing') { return 'Ingen titel'; }
      else { return entity.attributes.media_title; } ]]]
    custom_fields:
      media_image: >
        <svg viewBox="0 0 50 50" />
      blur: >
        [[[ if (entity.attributes.entity_picture != null) {
        return '<svg viewBox="0 0 50 50" />'; } ]]]
      overlay: >
        [[[ if (entity.state != 'off' && entity.state != 'idle' && entity.state != 'standby' && entity.state != 'unavailable') {
        return '<svg viewBox="0 0 50 50" />'; } ]]]
      play_pause: >
        [[[ const style = `<style>.scale-up { animation: scale-up 0.3s; cubic-bezier(.05,.5,.3,1) 1; transform-origin: center center; }
        @keyframes scale-up { 0% { opacity: 0; transform: scale(0); } 100% { opacity: 1; transform: scale(1); } }</style>`;
        if (entity.state === 'playing') { return `<svg viewBox="0 0 166 166">${style}<path class="scale-up" d="M0 0h59.9v166H0zm106.1 0H166v166h-59.9z"/></svg>`; }
        if (entity.state === 'paused') { return `<svg viewBox="0 0 166 166">${style}<path class="scale-up" d="M0 0l166 83L0 166z"/></svg>`; } ]]]
    styles:
      custom_fields:
        media_image:
          [background-image:
          "[[[ return entity.attributes.entity_picture == null ? 'linear-gradient(0deg, rgba(115, 115, 115, 0.2) 0%, rgba(115, 115, 115, 0.2) 100%)' 
          : 'linear-gradient(0deg, rgba(13,17,19,0.9) 0%, rgba(13,17,19,0) 50%), url(' + entity.attributes.entity_picture + ')'; ]]]", 
          background-size: cover, top: 0%, left: 0%, width: 100%, position: absolute]
        blur:
          [background-image:
          "[[[ return entity.attributes.entity_picture == null ? 'none' : 'url(' + entity.attributes.entity_picture + ')'; ]]]", 
          background-size: cover, top: 0%, left: 0%, width: 100%, filter: blur(4px), clip-path: inset(16vw 0 0 0), position: absolute]
        overlay:
          [background:
          "[[[ return entity.attributes.entity_picture == null ? 'rgba(255, 255, 255, 0.8)' : 'rgba(0, 0, 0, 0.4)'; ]]]", 
          background-size: cover, z-index: 0, top: 16vw, left: 0%, width: 100%, opacity: 1, position: absolute]
        play_pause:
          [filter: 
          "[[[ return entity.attributes.entity_picture == null ? 'none' : 'drop-shadow(0 0 1.3vw rgba(0,0,0,0.7))'; ]]]", 
          fill: '#dedede', top: 0, right: 0, bottom: 0, left: 0, margin: auto, width: 21%, height: 21%, position: absolute]
        icon:
          [fill:
          "[[[ if (entity.state === 'off' || entity.state === 'idle' || entity.state === 'standby' || 
          entity.state === 'unknown' || entity.state === 'unavailable') return '#9da0a2'; 
          else return 'rgba(255, 255, 255, 0.8)'; ]]]", 
          top: 5.35%, left: 5.35%, width: 2.95vw, position: absolute]
      name:
        [top: 79.8%, left: 5.3%, position: absolute, line-height: 2vw, z-index: 10]
      state:
        [top: 87.5%, left: 5.3%, position: absolute, line-height: 2vw, z-index: 10, 
        white-space: nowrap, overflow: hidden, text-overflow: ellipsis, max-width: 90%]

  icon_action:
    color: '#9da0a2'
    styles:
      card:
        [background: '#FFFFFF10', border-radius: 0.6em, box-shadow: none, 
        transition: none, width: 4em, height: 3.7em]

  name_action:
    styles:
      name:
        [display: flex, align-items: center, justify-content: center, margin-top: 0.5px]
      card:
        [background: '#FFFFFF10', color: '#9da0a2', border-radius: 0.6em, box-shadow: none, 
        transition: none, width: 100%, padding: 1em 1.4em 1em 1.2em, font-size: 1.06em, 
        font-weight: 500, letter-spacing: 0.015em]
    style: '#name > ha-icon {width: 1.4em; margin-right: 0.3em; }'

  thermometre:
    template:
    aspect_ratio: 1/1
    show_state: true
    show_icon: false
    state:
      - value: 'on'
        styles:
          card: [background-color: 'rgba(255, 255, 255, 0.8)']
          name: [color: 'rgba(0, 0, 0, 0.6)']
          state: [color: 'rgba(0, 0, 0, 0.6)']
    tap_action:
      ui_sound: |
        [[[ if (entity.state === 'off' && states['switch.fullykiosk_screensaver'].state === 'off') {
        hass.callService('media_player', 'play_media', {entity_id: 'media_player.tablet', media_content_id: '/local/sound/on.m4a', media_content_type: 'music'}); }
        else if (entity.state === 'on' && states['switch.fullykiosk_screensaver'].state === 'off') {
        hass.callService('media_player', 'play_media', {entity_id: 'media_player.tablet', media_content_id: '/local/sound/off.m4a', media_content_type: 'music'}); } ]]]
    styles:
      custom_fields:
        icon:
          [top: 11.5%, left: 11.5%, width: 2.9vw, position: absolute, ]
        circle:
          [top: 8.5%, left: 56.2%, width: 3.5vw, position: absolute, letter-spacing: 0.03vw, fill: '#9da0a2']
      name:
        [top: 57.7%, left: 11%, line-height: 2vw, position: absolute]
      state:
        [top: 74%, left: 11%, line-height: 2vw, position: absolute]
      card:
        [font-family: Sf Display, letter-spacing: 0.05vw, font-weight: 400, color: 'rgba(255, 255, 255, 0.3)', font-size: 1.34vw, 
        background-color: 'rgba(115, 115, 115, 0.2)', border-radius: 0.8vw, box-shadow: none, transition: none]

en espérant que ce soit lisible pour toi sinon dis moi si je dois le poster sur le pastebin après je ne sais pas comment partager avec toi …

Utilise la balise 3xaccents grave pour le code :+1:

A copier directement pour le coller dans un post :

```
Code ici
```

Ce qui va donner au final

Code ici
1 « J'aime »

Merci pour l’info :slight_smile: et de l’avoir modifié :slight_smile:

1 « J'aime »

je viens de regarder button_card_templates.yaml et c’est propre pour moi. Il ressemble à quoi ton switch.yaml et ton input.yaml ? Je regarde un peu toutes les hypothèses.

pas de soucis, ci-joint mon switch.yaml:
https://pastebin.com/mehpTqkj

ci-joint mon input.yaml :
https://pastebin.com/Qfqab0YG

Merci

C’est embetant, rien ne me saute aux yeux.

On va faire un truc. Tu sais utiliser le DevTool sur chrome ou firefox ?

ha ok c’est le inspect sur chrome, pas de soucis tu veux que je l’ouvre à quel moment là ou j’ai l’erreur en rouge ?

exact ! reproduis l’erreur et regarde si tu peux récupérer tout le texte du carré rouge. Tu devrais peut être aussi avoir des erreurs dans la console

T’as essayé d’avoir le code affiché par ton button-card qui pose soucis ? Il est visible dans le code html. Il devrait te retourner en première ligne le pourquoi de l’erreur, sauf qu’il retourne aussi le code de la carte en plus, ce qui peut te faire une carte rouge immense.

j’ai effectivement une carte rouge immense et j’ai l’erreur suivante :

ButtonCardJSTemplateError: TypeError: Cannot read property 'state' of undefined in 'if (states[entity.entity_id.replace(entity.entity_id.split('.')[0], 'input_boolean')].state === 'o...'

Et j’ai ça dans mon button card template du coup :

  loader:
    custom_fields:
      loader: >
        [[[ if (states[entity.entity_id.replace(entity.entity_id.split('.')[0], 'input_boolean')].state === 'on') { 
        return '<img src="/local/loader.svg" width="100%">'; } ]]]

@kaoru Merci pour ton aide et de m’avoir fait allé aussi loin mais ne t’embête pas avec ça au final j’ai avancé sur d’autres points mais avec des questions que j’ai posté

J’aurais également une autre question comment tu as fait pour le badge de présence pour que tu sois reconnu présent via le wifi de la maison je ne vois pas de sensor que tu aurais pu créér : binary_sensor.oneplus_8_pro_etat_du_wi_fi dans ton sensor yaml

je me retrouve avec une card de présence qui ne sait pas que je suis à la maison et qui au lieu de donner mon état de présence j’ai le prénom de ma conjointe bizarre :

erreurprésence2


Pour Spotify :

J’ai bien l’intégration spotify, quand je lance spotify à partir de mon tél, j’ai bien le player qui se met à jour et la pochette via HA, j’ai mes 3 google home reconnu dans le media swipe card, j’appuie dessus je peux les passer en idle ou off (d’ailleurs je préfererais inactif que off, si tu pouvais m’indiquer ou le modifier) mais après je ne peux pas lancer de playlist à partir de spotify via HA et rediriger le son sur une de mes Google Home, tu aurais une idée du souci ?

j’ai également une erreur en bas entouré en bleu qui me dit Google Home Indisponible là je ne sais pas ou se situe le problème et à quoi il sert ?

maj : Pour la partie présence mon prob est réglé j’avais pas bien renseigné ma zone Home du coup j’ai mis les mêmes coordonnées GPS que j’ai lorsque je suis chez moi par contre je ne sais toujours pas comment tu as fait pour le sensor wifi de ton tél, il me manque cette méthode pour la détection de ma présence

Merci

Pour le soucis du loader, je dois creuser.

Concernant l’intégration des présences. C’est normal pour les sensor. J’utilise l’application officiel de home assistant sur mes téléphones et l’app créer elle-même un sensor gps de mon téléphone. Le système de présence ce fait pas avec le wifi mais en fonction des coordonnées gps.
Par contre j’ai un problème avec le wifi sur le popup. Dans la même optique que le gps, l’app de home assistant peut te créer un sensor, si le wifi de ton téléphone est allumé mais je trouve cele pas fiable pour deux raisons : un temps de latence pour l’update des données et la deuxième concerne plus si tu utilise le wifi ailleurs, ça te remonte l’activation du wifi parce que ça passe l’accès extérieur de home assistant, via internet.
La solution pour faire un capteur qui fonctionne seulement quand le téléphone est connecté en wifi en réseau local, c’est d’utilise l’intégration ping avec le device tracker. Je mettrai ça bientôt en place dans ma configuration.

Idle ou off, c’est un comportement propre au google home, il se met en idle un certain temps et après il se met en off, il me semble.
Pour lancer les playlist depuis HA, est-ce que tu as installé le custom components spotcast via hacs ? Si tu regarde la doc de Home Assistant Spotify Lovelace Card, c’est un élément requis.

Le Google home indisponible, c’est pour les minuteurs du google home en cours, je te laisse lire ce post pour son intégration. Tu n’es pas obligé de l’utilise, c’est juste mon besoin.

J’ai besoin de plus d’information pour creuse le truc. Le template loader est strictement identique au miens, rien n’a changé.

Est-ce que tu pourrais me dire ta version de HA.
Et une autre petite action, tu peux pourrais faire la commande tree dans le répertoire de ta config ha. Tu devras surement installé le paquet tree. apt install tree && cd /chemin/config/ha/ && tree
C’est pour voir l’arborescence de tes fichiers et répertoires.

Merci pour les infos, entre mon dernier et celui-ci j’ai avancé pour la partie présence tout est rentré dans l’ordre j’utilise nmap pour info si ça peut te servir avec le paramètre host qui spécifie l’ip de mon téléphone donc au final je combine MobileApp + nmap.
Pour le minuteur Google home effectivement j’en ai pas besoin j’ai mis un sensor sur le nombre de décès du coronavirus en France par ex par car j’arrive pas à trouver des icônes à la place de l’icône mdi alarm je voulais genre une tête de mort.
Pour la playlist spotify effectivement j’ai compris après et je l’ai intégré dans une deuxième view ce qui donne ça :

Après je t’avoue que je galère pour avoir un nom sur ma view et sur l’icône, comme sur la capture ci-dessus

j’ai bien splitté mon ui-lovelace.yaml en pointant sur par ex :
views:

  • !include /config/lovelace/views/01-view_home.yaml
  • !include /config/lovelace/views/02-view_music.yaml

et à l’intérieur je commence avec le code suivant :

views:
  - id: 1
    icon: 'mdi:music'
    name: Home
    panel: true
    path: home
    title: SAMCHA
    cards:

ou le fichier 02-view_music.yaml :

views:
  - panel: true
    title: Music
    name: Music
    icon: 'mdi:music'    
#  - id: 2

le hic c’est qu’après il ne reconnait pas ces bout de code :

            <<: *title
            <<: *title-style

je peux les mettre en commentaire mais je ne sais pas à quoi ça sert
et autre point comme mes fichiers views sont dans les répertoires suivants :
/config/lovelace/views/
il ne trouve plus les fichiers popup car je lui indique par défaut qu’ils sont par ex dans :
!include popup/computer_sam.yaml

et comme je suis positionné dans le répertoire /config/lovelace/views/ au moment ou il lit mes fichiers views, il faudrait que je remonte l’arboresence à la racine, j’ai essayé ceci mais ça marche pas :
!include ./popup/computer_sam.yaml

A moins de copier toutes mes fichiers popup dans le répertoire views mais ça sera moins propre niveau structure des dossiers, je trouve. Tu serais comment je pourrais faire ?
est-ce que tu envisageais de créér plusieurs views ?

Merci

As tu essayé mdi:coffin ?

Moi, c’est l’étiquette (tag) que le créateur a mis qui me fait peur :scream: :sweat_smile:

1 « J'aime »