Carte des jours Tempo avec prévisions pour la semaine

Bonjour,

Je travaille à une amélioration de l’intégration RTE Tempo pour intégrer les prévisions de couleur des prochains jours Tempo.
On peut également accéder à ces prévisions en scrapant la page web de Selectra ou en récupérant le json de (Open DPE, ce que j’utilise pour l’intégration.

Pour l’affichage des données, j’ai créé une carte Lovelace qui affiche le jour actuel et le suivant en provenance des capteurs de l’intégration RTE Tempo (sensor.rte_tempo_couleur_actuelle et sensor.rte_tempo_prochaine_couleur). Les jours suivants (J+2 à J+6) sont affichés avec les informations de Open DPE à venir et montrent le pourcentage de fiabilité provenant de la source.

Afin d’améliorer la pertinence des informations affichées, j’ai rajouté en dessous le nombre de jours rouges et blancs restants.

Voici ce que ça donne :

Et voici le code :

type: custom:vertical-stack-in-card
title: Prévisions Tempo
cards:
  - type: horizontal-stack
    cards:
      - type: custom:button-card
        entity: sensor.rte_tempo_couleur_actuelle
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const today = new Date();          // Date actuelle du navigateur
            return days[today.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - display: none
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = (entity.state || '').toLowerCase();
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ return ' '; ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.rte_tempo_prochaine_couleur
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date();
            date.setDate(date.getDate() + 1);  // +1 jour
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - display: none
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = (entity.state || '').toLowerCase();
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ return ' '; ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.rte_tempo_forecast_opendpe_j2
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = (entity.state || '').toLowerCase();
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.rte_tempo_forecast_opendpe_j3
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = (entity.state || '').toLowerCase();
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.rte_tempo_forecast_opendpe_j4
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = (entity.state || '').toLowerCase();
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.rte_tempo_forecast_opendpe_j5
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = (entity.state || '').toLowerCase();
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.rte_tempo_forecast_opendpe_j6
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = (entity.state || '').toLowerCase();
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
  - type: custom:button-card
    show_name: false
    show_state: false
    show_icon: false
    styles:
      card:
        - background-color: transparent
        - border: none
        - box-shadow: none
        - padding: 18px 2px 12px 12px
      grid:
        - grid-template-areas: "\"label rouge rouge_color blanc blanc_color\""
        - grid-template-columns: auto auto 30px auto 30px
        - column-gap: 8px
        - justify-content: start
      custom_fields:
        label:
          - font-size: 12px
          - color: var(--secondary-text-color)
          - white-space: nowrap
          - align-self: center
        rouge:
          - font-size: 12px
          - color: var(--secondary-text-color)
          - text-align: right
          - align-self: center
        rouge_color:
          - width: 22px
          - height: 22px
          - align-self: center
        blanc:
          - font-size: 12px
          - color: var(--secondary-text-color)
          - text-align: right
          - align-self: center
        blanc_color:
          - width: 22px
          - height: 22px
          - align-self: center
    custom_fields:
      label: |
        [[[
          return 'Nombre de jours restants :';
        ]]]
      rouge: |
        [[[
          const ent = states['sensor.rte_tempo_cycle_jours_restants_rouge'];
          if (!ent || !ent.state || ent.state === 'unknown') return '?';
          return ent.state;
        ]]]
      rouge_color: |
        [[[
          return `<div style="width: 20px; height: 20px; background-color: #E5543A; border-radius: 4px; border: 1px solid #777777;"></div>`;
        ]]]
      blanc: |
        [[[
          const ent = states['sensor.rte_tempo_cycle_jours_restants_blanc'];
          if (!ent || !ent.state || ent.state === 'unknown') return '?';
          return ent.state;
        ]]]
      blanc_color: |
        [[[
          return `<div style="width: 20px; height: 20px; background-color: #F7F7F7; border-radius: 4px; border: 1px solid #777777;"></div>`;
        ]]]
    tap_action:
      action: none
card_mod:
  style: |
    .card-header {
      padding-bottom: -40px !important;
    }

Autre exemple de carte :

Et son code :

type: custom:vertical-stack-in-card
title: Couleur Tempo
cards:
  - type: grid
    columns: 2
    square: false
    cards:
      - type: custom:button-card
        entity: sensor.rte_tempo_couleur_actuelle
        name: Aujourd'hui
        styles:
          name:
            - font-size: 16px
            - color: white
          card:
            - height: 45px
            - background-color: var(--disabled-text-color)
            - margin-top: "-10px"
        show_label: true
        show_icon: false
        color: white
        state:
          - value: Bleu
            styles:
              card:
                - background-color: "#1958C4"
          - value: Blanc
            styles:
              card:
                - background-color: White
              name:
                - color: Black
          - value: Rouge
            styles:
              card:
                - background-color: "#E5543A"
      - type: custom:button-card
        entity: sensor.rte_tempo_prochaine_couleur
        name: Demain
        styles:
          name:
            - font-size: 16px
            - color: white
          card:
            - height: 45px
            - background-color: var(--disabled-text-color)
            - margin-top: "-10px"
        show_label: true
        show_icon: false
        color: white
        state:
          - value: Bleu
            styles:
              card:
                - background-color: "#1958C4"
          - value: Blanc
            styles:
              card:
                - background-color: White
              name:
                - color: Black
          - value: Rouge
            styles:
              card:
                - background-color: "#E5543A"
  - type: horizontal-stack
    cards:
      - type: custom:button-card
        entity: sensor.rte_tempo_forecast_opendpe_j2
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 16px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = (entity.state || '').toLowerCase();
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.rte_tempo_forecast_opendpe_j3
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 16px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = (entity.state || '').toLowerCase();
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.rte_tempo_forecast_opendpe_j4
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 16px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = (entity.state || '').toLowerCase();
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.rte_tempo_forecast_opendpe_j5
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 16px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = (entity.state || '').toLowerCase();
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.rte_tempo_forecast_opendpe_j6
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 16px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = (entity.state || '').toLowerCase();
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.rte_tempo_forecast_opendpe_j7
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 16px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = (entity.state || '').toLowerCase();
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
  - type: custom:button-card
    show_name: false
    show_state: false
    show_icon: false
    styles:
      card:
        - background-color: transparent
        - border: none
        - box-shadow: none
        - padding: 18px 2px 12px 12px
      grid:
        - grid-template-areas: "\"label rouge rouge_color blanc blanc_color\""
        - grid-template-columns: auto auto 30px auto 30px
        - column-gap: 8px
        - justify-content: start
      custom_fields:
        label:
          - font-size: 12px
          - color: var(--secondary-text-color)
          - white-space: nowrap
          - align-self: center
        rouge:
          - font-size: 12px
          - color: var(--secondary-text-color)
          - text-align: right
          - align-self: center
        rouge_color:
          - width: 22px
          - height: 22px
          - align-self: center
        blanc:
          - font-size: 12px
          - color: var(--secondary-text-color)
          - text-align: right
          - align-self: center
        blanc_color:
          - width: 22px
          - height: 22px
          - align-self: center
    custom_fields:
      label: |
        [[[
          return 'Nombre de jours restants :';
        ]]]
      rouge: |
        [[[
          const ent = states['sensor.rte_tempo_cycle_jours_restants_rouge'];
          if (!ent || !ent.state || ent.state === 'unknown') return '?';
          return ent.state;
        ]]]
      rouge_color: |
        [[[
          return `<div style="width: 20px; height: 20px; background-color: #E5543A; border-radius: 4px; border: 1px solid #777777;"></div>`;
        ]]]
      blanc: |
        [[[
          const ent = states['sensor.rte_tempo_cycle_jours_restants_blanc'];
          if (!ent || !ent.state || ent.state === 'unknown') return '?';
          return ent.state;
        ]]]
      blanc_color: |
        [[[
          return `<div style="width: 20px; height: 20px; background-color: #F7F7F7; border-radius: 4px; border: 1px solid #777777;"></div>`;
        ]]]
    tap_action:
      action: none
card_mod:
  style: |
    .card-header {
      padding-bottom: -40px !important;
    }
    ha-card {
      padding: 0 16px !important;
    }

Suivant le format de la probabilité utilisé, vous pouvez avoir besoin de modifier une des lignes pour chaque capteur :

  • Si l’attribut renvoie « 67 » : return p + "%";
  • S’il renvoie « 0,67 » : return Math.round(p * 100) + "%";

Evidemment, tant que l’intégration n’a pas été mise à jour, cette carte n’est pas très utile, mais ça devrait changer rapidement. Sauf si vous voulez vous lancer dans la récupération des données Prévisions Tempo que j’ai décrite et qui utilise l’intégration Multiscrape…

J’ai également fait une Pull Request sur l’intégration RTE Tempo

5 « J'aime »

Salut

J’ai déjà réalisé la partie multiscrape et sensor.

afin de finaliser et tester aurais tu le code pour la carte ?

Merci

Mais quel idiot… :upside_down_face:
Bien sûr, voici le code :

type: custom:vertical-stack-in-card
title: Prévisions Tempo
cards:
  - type: horizontal-stack
    cards:
      - type: custom:button-card
        entity: sensor.rte_tempo_couleur_actuelle
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const today = new Date();          // Date actuelle du navigateur
            return days[today.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - display: none
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const ent = states['sensor.rte_tempo_couleur_actuelle'];

              // Si le capteur est absent ou inutilisable → carré gris
              if (!ent || !ent.state) {
                return `<div style="width: 100%; height: 100%; background-color: #CCCCCC; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
              }

              const color = ent.state.toLowerCase();

              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';

              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ return ' '; ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.rte_tempo_prochaine_couleur
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date();
            date.setDate(date.getDate() + 1);  // +1 jour
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - display: none
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const ent = states['sensor.rte_tempo_couleur_actuelle'];

              // Si le capteur est absent ou inutilisable → carré gris
              if (!ent || !ent.state) {
                return `<div style="width: 100%; height: 100%; background-color: #CCCCCC; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
              }

              const color = ent.state.toLowerCase();

              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';

              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ return ' '; ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.rte_tempo_forecast_opendpe_j2
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = (entity.state || '').toLowerCase();
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.rte_tempo_forecast_opendpe_j3
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = entity.state;
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.rte_tempo_forecast_opendpe_j4
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = entity.state;
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.rte_tempo_forecast_opendpe_j5
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = entity.state;
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.rte_tempo_forecast_opendpe_j6
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = entity.state;
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
  - type: custom:button-card
    show_name: false
    show_state: false
    show_icon: false
    styles:
      card:
        - background-color: transparent
        - border: none
        - box-shadow: none
        - padding: 18px 2px 12px 12px
      grid:
        - grid-template-areas: "\"label rouge rouge_color blanc blanc_color\""
        - grid-template-columns: auto auto 30px auto 30px
        - column-gap: 8px
        - justify-content: start
      custom_fields:
        label:
          - font-size: 12px
          - color: var(--secondary-text-color)
          - white-space: nowrap
          - align-self: center
        rouge:
          - font-size: 12px
          - color: var(--secondary-text-color)
          - text-align: right
          - align-self: center
        rouge_color:
          - width: 22px
          - height: 22px
          - align-self: center
        blanc:
          - font-size: 12px
          - color: var(--secondary-text-color)
          - text-align: right
          - align-self: center
        blanc_color:
          - width: 22px
          - height: 22px
          - align-self: center
    custom_fields:
      label: |
        [[[
          return 'Nombre de jours restants :';
        ]]]
      rouge: |
        [[[
          const ent = states['sensor.rte_tempo_cycle_jours_restants_rouge'];
          if (!ent || !ent.state || ent.state === 'unknown') return '?';
          return ent.state;
        ]]]
      rouge_color: |
        [[[
          return `<div style="width: 20px; height: 20px; background-color: #E5543A; border-radius: 4px; border: 1px solid #777777;"></div>`;
        ]]]
      blanc: |
        [[[
          const ent = states['sensor.rte_tempo_cycle_jours_restants_blanc'];
          if (!ent || !ent.state || ent.state === 'unknown') return '?';
          return ent.state;
        ]]]
      blanc_color: |
        [[[
          return `<div style="width: 20px; height: 20px; background-color: #F7F7F7; border-radius: 4px; border: 1px solid #777777;"></div>`;
        ]]]
    tap_action:
      action: none
card_mod:
  style: |
    .card-header {
      padding-bottom: -40px !important;
    }

La PR est créée pour l’intégration RTE Tempo pour info. Du coup j’ai supprimé le code Multiscrape de mon côté.

2 « J'aime »

Merci pour le code de la carte.

il y a une PR, mais c’est pas encore en place, c’est bien cela ?
(du coup en attendant, on peut utiliser les sensor « opendpe_forecast_jx »)

Salut

Petit correctif sur le code de la carte, Il y a une petite erreur d’entité pour le deuxième jours.

Il faut remplacer sensor.rte_tempo_couleur actuelle par sensor.rte_tempo_prochaine couleur

La solution multiscrape reste interressante pour ceux (comme moi) qui n’utilisent pas l’integration RTE (perso j’utilise mon Zlinky)…

Bonjour,

Par simple curiosité, c’est quoi l’avantage de passer par multiscrape plutôt que restfull ?

Oui, la PR est déposée. N’hésitez pas à la pousser en mettant une étoile… :wink:
Je rajoute des détails dans le post d’origine.
Et oui aussi, en attendant Multiscrape fait le job.

Aucune idée. L’IA ma proposé Multiscrape… :blush:

Saurez tu me dire pourquoi les 2 premiers carré sont incomplet ?

Quad j’édite la carte pour la corriger, je n’ai pas ce défaut dans l’aperçu.

type: custom:vertical-stack-in-card
title: Prévisions Tempo
cards:
  - type: horizontal-stack
    cards:
      - type: custom:button-card
        entity: sensor.rte_tempo_couleur_actuelle
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const today = new Date();          // Date actuelle du navigateur
            return days[today.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - display: none
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const ent = states['sensor.rte_tempo_couleur_actuelle'];

              // Si le capteur est absent ou inutilisable → carré gris
              if (!ent || !ent.state) {
                return `<div style="width: 100%; height: 100%; background-color: #CCCCCC; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
              }

              const color = ent.state.toLowerCase();

              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';

              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ return ' '; ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.rte_tempo_prochaine_couleur
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date();
            date.setDate(date.getDate() + 1);  // +1 jour
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - display: none
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const ent = states['sensor.rte_tempo_prochaine_couleur'];

              // Si le capteur est absent ou inutilisable → carré gris
              if (!ent || !ent.state) {
                return `<div style="width: 100%; height: 100%; background-color: #CCCCCC; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
              }

              const color = ent.state.toLowerCase();

              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';

              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ return ' '; ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.opendpe_forecast_j2
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = (entity.state || '').toLowerCase();
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.opendpe_forecast_j3
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = entity.state;
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.opendpe_forecast_j4
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = entity.state;
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.opendpe_forecast_j5
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = entity.state;
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
      - type: custom:button-card
        entity: sensor.opendpe_forecast_j6
        name: |
          [[[
            const days = ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'];
            const date = new Date(entity.attributes.date);
            return days[date.getDay()];
          ]]]
        show_state: false
        show_icon: false
        styles:
          card:
            - background-color: transparent
            - border: none
            - box-shadow: none
            - padding: 0px
            - margin-top: "-20px"
          grid:
            - grid-template-areas: "\"n\" \"color\" \"prob\""
            - grid-template-rows: auto 40px auto
          name:
            - font-size: 14px
            - color: var(--primary-text-color)
            - padding-top: 8px
            - padding-bottom: 2px
          custom_fields:
            color:
              - width: 35px
              - height: 35px
              - margin: 0 auto
            prob:
              - font-size: 12px
              - padding-top: 2px
              - color: var(--secondary-text-color)
        custom_fields:
          color: |
            [[[
              const color = entity.state;
              let bgColor = '#CCCCCC';
              if (color === 'bleu') bgColor = '#1958C4';
              if (color === 'blanc') bgColor = '#F7F7F7';
              if (color === 'rouge') bgColor = '#E5543A';
              return `<div style="width: 100%; height: 100%; background-color: ${bgColor}; border-radius: 6px; border: 1px solid #777777; box-sizing: border-box;"></div>`;
            ]]]
          prob: |
            [[[ 
              const p = entity.attributes.probability;
              if (p === null || p === undefined || p === "") {
                return "?";
              }
              return Math.round(p * 100) + "%";
            ]]]
        tap_action:
          action: none
  - type: custom:button-card
    show_name: false
    show_state: false
    show_icon: false
    styles:
      card:
        - background-color: transparent
        - border: none
        - box-shadow: none
        - padding: 18px 2px 12px 12px
      grid:
        - grid-template-areas: "\"label rouge rouge_color blanc blanc_color bleu bleu_color\""
        - grid-template-columns: auto auto 30px auto 30px
        - column-gap: 8px
        - justify-content: start
      custom_fields:
        label:
          - font-size: 12px
          - color: var(--secondary-text-color)
          - white-space: nowrap
          - align-self: center
        rouge:
          - font-size: 12px
          - color: var(--secondary-text-color)
          - text-align: right
          - align-self: center
        rouge_color:
          - width: 22px
          - height: 22px
          - align-self: center
        blanc:
          - font-size: 12px
          - color: var(--secondary-text-color)
          - text-align: right
          - align-self: center
        blanc_color:
          - width: 22px
          - height: 22px
          - align-self: center
        bleu:
          - font-size: 12px
          - color: var(--secondary-text-color)
          - text-align: right
          - align-self: center
        bleu_color:
          - width: 22px
          - height: 22px
          - align-self: center
    custom_fields:
      label: |
        [[[
          return 'jours restants :';
        ]]]
      rouge: |
        [[[
          const ent = states['sensor.rte_tempo_cycle_jours_restants_rouge'];
          if (!ent || !ent.state || ent.state === 'unknown') return '?';
          return ent.state;
        ]]]
      rouge_color: |
        [[[
          return `<div style="width: 20px; height: 20px; background-color: #E5543A; border-radius: 4px; border: 1px solid #777777;"></div>`;
        ]]]
      blanc: |
        [[[
          const ent = states['sensor.rte_tempo_cycle_jours_restants_blanc'];
          if (!ent || !ent.state || ent.state === 'unknown') return '?';
          return ent.state;
        ]]]
      blanc_color: |
        [[[
          return `<div style="width: 20px; height: 20px; background-color: #F7F7F7; border-radius: 4px; border: 1px solid #777777;"></div>`;
        ]]]
      bleu: |
        [[[
          const ent = states['sensor.rte_tempo_cycle_jours_restants_bleu'];
          if (!ent || !ent.state || ent.state === 'unknown') return '?';
          return ent.state;
        ]]]
      bleu_color: |
        [[[
          return `<div style="width: 20px; height: 20px; background-color: #1958C4; border-radius: 4px; border: 1px solid #777777;"></div>`;
        ]]]    
    tap_action:
      action: none
card_mod:
  style: |
    .card-header {
      padding-bottom: -40px !important;
    }