[AIDE] Tableau 24×7 avec cellules cliquables sans créer 168 entités

Tiens voilà de quoi jouer (ça tiens facile sur moins de 640x480px)
card

Les entités HA

input_text:
  schedule_lundi_hex:
    name: Planning Lundi (HEX)
    initial: "000000"
    max: 6
  schedule_mardi_hex:
    name: Planning Mardi (HEX)
    initial: "000000"
    max: 6
  schedule_mercredi_hex:
    name: Planning Mercredi (HEX)
    initial: "000000"
    max: 6
  schedule_jeudi_hex:
    name: Planning Jeudi (HEX)
    initial: "000000"
    max: 6
  schedule_vendredi_hex:
    name: Planning Vendredi (HEX)
    initial: "000000"
    max: 6
  schedule_samedi_hex:
    name: Planning Samedi (HEX)
    initial: "000000"
    max: 6
  schedule_dimanche_hex:
    name: Planning Dimanche (HEX)
    initial: "000000"
    max: 6

Le code de la carte

class ScheduleCard extends HTMLElement {
    constructor() {
        super();
        this.attachShadow({ mode: 'open' });
        this.render(); 
        this.isInitialized = false;
        this._hass = null;
        this._config = {}; 
    }

    setConfig(config) {
        if (!config.entities || config.entities.length !== 7) {
            throw new Error('Vous devez spécifier exactement 7 entités input_text (une par jour).');
        }
        this._config = config;
        this._cardTitle = config.title || '📅 Mon Planning Personnalisé';
        
        const titleElement = this.shadowRoot.querySelector('h1');
        if (titleElement) {
            titleElement.textContent = this._cardTitle;
        }

        if (!this.isInitialized) {
            this.initializeApp();
        }
    }

    set hass(hass) {
        this._hass = hass;
        if (this.isInitialized) {
             setTimeout(() => {
                this.loadInitialRegisters(true);
             }, 100); 
        }
    }

    getCardSize() { return 7; }

    render() {
        const initialTitle = this._cardTitle || '📅 Mon Planning Personnalisé';

        this.shadowRoot.innerHTML = `
            <style>
                .schedule-container {
                    font-family: sans-serif;
                    padding: 10px;
                    background-color: var(--ha-card-background, var(--card-background-color, #f4f7f6));
                    border-radius: var(--ha-card-border-radius, 12px);
                    box-shadow: var(--ha-card-box-shadow, 0 4px 8px 0 rgba(0,0,0,0.2));
                }
                h1 {
                    color: var(--primary-text-color);
                    font-size: 1.2em;
                    margin-top: 0;
                    margin-bottom: 10px;
                    cursor: pointer; 
                }
                h1:hover { opacity: 0.8; }
                #weekly-schedule-grid {
                    display: grid;
                    /* 🛠️ Colonnes ajustées : 50px pour le label jour + 24 colonnes égales pour les heures */
                    grid-template-columns: 50px repeat(24, 1fr); 
                    gap: 1px;
                    width: 100%;
                    /* 🛠️ Ligne max-width supprimée pour prendre toute la largeur */
                    margin: 0 auto;
                    background-color: transparent; 
                    border-radius: 4px;
                    overflow: hidden; 
                }
                .legend-hour, .legend-register {
                    background-color: var(--dark-primary-color, #333);
                    color: white;
                    padding: 0; 
                    height: 25px; 
                    line-height: 25px; 
                    font-size: 0.7em;
                    font-weight: bold;
                    text-align: center;
                }
                /* 🛠️ Suppression de .legend-register CSS */
                .day-label {
                    background-color: var(--label-badge-blue, #007bff);
                    color: white;
                    font-weight: bold;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    font-size: 0.8em; 
                    height: 25px;
                    line-height: 25px; 
                    padding: 0; 
                    grid-column: 1 / 2; 
                }
                .hour-block {
                    cursor: pointer;
                    height: 25px; 
                    line-height: 25px;
                    transition: background-color 0.1s;
                    border: 1px solid var(--divider-color, #e0e0e0); 
                    box-sizing: border-box;
                }
                .hour-block.inactive { 
                    background-color: var(--paper-card-background-color, #fcfcfc); 
                }
                
                .schedule-container #weekly-schedule-grid .hour-block.active { 
                    background-color: var(--label-badge-green, #28a745) !important; 
                }
                
                .hour-block:hover { 
                    opacity: 0.8; 
                    box-shadow: inset 0 0 0 2px var(--label-badge-yellow, #0056b3); 
                }
                /* 🛠️ Suppression des styles .register-cell et .hex-cell */

                @media (max-width: 1024px) {
                    #weekly-schedule-grid {
                         /* 🛠️ Colonnes ajustées : on retire la colonne des registres */
                        grid-template-columns: 40px repeat(24, 1fr); 
                    }
                    .day-label, .hour-block { height: 20px; line-height: 20px; }
                    .legend-hour { height: 20px; line-height: 20px; }
                    .day-label { font-size: 0.7em; }
                    .legend-hour { font-size: 0.5em; }
                    /* 🛠️ Suppression des ajustements de taille pour les éléments HEX */
                }
            </style>
            <div class="schedule-container">
                <h1>${initialTitle}</h1>
                <div id="weekly-schedule-grid"></div>
            </div>
        `;
    }

    initializeApp() {
        if (!this.shadowRoot || this.isInitialized) return;

        this.DAYS = ['Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam', 'Dim'];
        this.NUM_HOURS = 24;
        this.NUM_DAYS = 7;
        
        this.weeklyRegisters = []; 
        this.hourBlocksCache = []; 
        this.SCHEDULE_GRID = this.shadowRoot.querySelector('#weekly-schedule-grid'); 

        for (let i = 0; i < this.NUM_DAYS; i++) {
            this.weeklyRegisters.push({ reg1: 0, reg2: 0 });
            this.hourBlocksCache[i] = [];
        }
        
        this.createFullScheduleGrid();
        this.SCHEDULE_GRID.addEventListener('click', this.handleGridClick.bind(this));
        
        const titleElement = this.shadowRoot.querySelector('h1');
        if (titleElement) {
            titleElement.addEventListener('click', this.handleTitleClick.bind(this));
        }

        this.isInitialized = true;
    }
    
    loadInitialRegisters(updateGrid) {
        if (!this._hass) return;

        for (let d = 0; d < this.NUM_DAYS; d++) {
            const entityId = this._config.entities[d];
            const state = this._hass.states[entityId]; 
            
            let reg1 = 0;
            let reg2 = 0;
            let combinedHexString = '000000';

            if (state && state.state) {
                combinedHexString = state.state.toUpperCase().padStart(6, '0');
                
                const combinedValue = BigInt(`0x${combinedHexString}`);
                
                reg1 = Number(combinedValue & 0xFFFFn); 
                reg2 = Number(combinedValue >> 16n); 
            }

            this.weeklyRegisters[d].reg1 = reg1;
            this.weeklyRegisters[d].reg2 = reg2;
            
            this.updateRegisterDisplaysForDay(d, false); // Même si on n'affiche plus, la logique de conversion est utile
        }
        if (updateGrid) {
            this.synchronizeGridFromRegisters();
        }
    }
    
    writeRegisterToHomeAssistant(dayIndex, combinedHexString) {
        if (!this._hass) return; 
        
        const entityId = this._config.entities[dayIndex];
        
        this._hass.callService('input_text', 'set_value', {
            entity_id: entityId,
            value: combinedHexString
        });
    }

    handleGridClick(event) {
        const block = event.target;
        if (block.classList.contains('hour-block')) {
            const dayIndex = parseInt(block.dataset.dayIndex);
            const hourIndex = parseInt(block.dataset.hourIndex);
            this.toggleHour(dayIndex, hourIndex, block);
        }
    }
    
    handleTitleClick(event) {
        if (event.target.tagName === 'H1') {
            const confirmation = confirm("Voulez-vous vraiment définir TOUS les jours (y compris Dimanche et Lundi) à ACTIF (HEX FFFFFF) ? Cette action écrasera les états actuels dans Home Assistant.");
            if (confirmation) {
                this.setAllDaysToActive();
            }
        }
    }

    setAllDaysToActive() {
        if (!this._hass) return;
        
        const fullHexValue = 'FFFFFF';
        const reg1 = 65535;
        const reg2 = 255;

        for (let d = 0; d < this.NUM_DAYS; d++) {
            this.weeklyRegisters[d].reg1 = reg1;
            this.weeklyRegisters[d].reg2 = reg2;
            
            // 🛠️ Suppression de la mise à jour de l'affichage HEX
            
            this.writeRegisterToHomeAssistant(d, fullHexValue);
        }
        
        this.synchronizeGridFromRegisters();
    }

    updateRegisterDisplaysForDay(dayIndex, callService = true) {
        const reg = this.weeklyRegisters[dayIndex];
        
        const reg1_n = BigInt(reg.reg1);
        const reg2_n = BigInt(reg.reg2);

        const combinedValue_n = (reg2_n << 16n) | reg1_n;
        
        const combinedHexString = combinedValue_n.toString(16).toUpperCase().padStart(6, '0');
        
        if (callService) {
            this.writeRegisterToHomeAssistant(dayIndex, combinedHexString);
        }
    }

    synchronizeGridFromRegisters() {
        // 🔧 CORRECTION MAJEURE : Re-query les blocs du DOM
        for (let d = 0; d < this.NUM_DAYS; d++) {
            this.hourBlocksCache[d] = [];
            const dayBlocks = this.SCHEDULE_GRID.querySelectorAll(`[data-day-index="${d}"].hour-block`);
            for (let h = 0; h < dayBlocks.length; h++) {
                this.hourBlocksCache[d][h] = dayBlocks[h];
            }
        }
        
        // Maintenant décoder
        for (let d = 0; d < this.NUM_DAYS; d++) {
            this.decodeDaySchedule(d); 
        }
    }

    decodeDaySchedule(dayIndex) {
        const reg = this.weeklyRegisters[dayIndex];
        const dayBlocks = this.hourBlocksCache[dayIndex]; 

        for (let h = 0; h < this.NUM_HOURS; h++) {
            const block = dayBlocks[h];
            if (!block) continue;

            let isActive = false;
            
            if (h <= 15) {
                isActive = (reg.reg1 & (1 << h)) !== 0; 
            } else {
                const bitIndex = h - 16; 
                isActive = (reg.reg2 & (1 << bitIndex)) !== 0; 
            }

            block.classList.toggle('active', isActive);
            block.classList.toggle('inactive', !isActive);
        }
    }
    
    toggleHour(dayIndex, hourIndex, block) {
        const isCurrentlyActive = block.classList.contains('active');
        const targetActiveState = !isCurrentlyActive; 
        const reg = this.weeklyRegisters[dayIndex];
        let bitMask;
        let targetReg;

        if (hourIndex >= 0 && hourIndex <= 15) { 
            bitMask = 1 << hourIndex; 
            targetReg = 'reg1';
        } else { 
            const bitIndex = hourIndex - 16;
            bitMask = 1 << bitIndex; 
            targetReg = 'reg2';
        }

        if (targetActiveState) {
            reg[targetReg] |= bitMask; 
        } else {
            reg[targetReg] &= ~bitMask; 
        }

        block.classList.toggle('active', targetActiveState);
        block.classList.toggle('inactive', !targetActiveState);

        this.updateRegisterDisplaysForDay(dayIndex, true); 
    }
    
    createFullScheduleGrid() {
        this.SCHEDULE_GRID.innerHTML = ''; 
        
        // 1. Ligne de Légende
        this.SCHEDULE_GRID.innerHTML += '<div></div>'; 
        for (let h = 0; h < this.NUM_HOURS; h++) {
            this.SCHEDULE_GRID.innerHTML += `<div class="legend-hour">${h.toString().padStart(2, '0')}</div>`;
        } 

        // 2. Lignes de Jours
        for (let d = 0; d < this.NUM_DAYS; d++) {
            this.SCHEDULE_GRID.innerHTML += `<div class="day-label">${this.DAYS[d]}</div>`;

            for (let h = 0; h < this.NUM_HOURS; h++) {
                const block = document.createElement('div');
                block.className = 'hour-block inactive'; 
                block.dataset.dayIndex = d;
                block.dataset.hourIndex = h;
                block.title = `${this.DAYS[d]} : ${h.toString().padStart(2, '0')}h`; 
                
                this.SCHEDULE_GRID.appendChild(block);
            }
        }
        
        // 🔧 Re-remplir le cache depuis le DOM réel
        this.synchronizeGridFromRegisters();
    }
}

customElements.define('schedule-card', ScheduleCard);

La déclaration de la carte, une fois collée dans /config/www/schedule-card/schedule-card.js

La config de la carte

type: custom:schedule-card
title: Mon Planning Personnalisé
entities:
  - input_text.schedule_lundi_hex
  - input_text.schedule_mardi_hex
  - input_text.schedule_mercredi_hex
  - input_text.schedule_jeudi_hex
  - input_text.schedule_vendredi_hex
  - input_text.schedule_samedi_hex
  - input_text.schedule_dimanche_hex
2 « J'aime »

Ouaw :exploding_head:

T’as carrément fait une carte perso ! Je ne m’y serais jamais aventuré !
Finalement c’est peut-être plus simple que s’embêter à comprendre toutes les options de la button-card…

Tu fais avec ChatGPT ? Car quand j’ai essayé de lui demander comment faire avec mon problème il s’est perdu avec des trucs impossibles, je crois que j’ai plus perdu du temps qu’autre chose, j’ai continué à chercher seul au final.

Merci beaucoup en tout cas, je vais essayer d’intégrer ta solution :+1:

Oui, ça fait des années que je code plus du frontend donc j’ai largement perdu la main, je suis passé par ClaudeAI et Gemini qui donnent sur ce sujet des trucs meilleurs que Chatgpt.

Il faut les guider, et bien utiliser le prompt sinon, on crame le quota gratuit mais ça passe assez bien au final.

Taille mini 317x232


Au dessous c’est dur de cliquer et mes vieux yeux sont à la peine aussi

2 « J'aime »

Du coup il manque quoi, puisque tu as une carte qui depuis une valeur du registre remplie les bonnes cases et quand tu cliques sur ces cases ajuste la nouvelle valeur tout en ce mettant à jour visuellement ?

Juste à faire le lien entre l’input_text et l’esp…
A mon avis l’input_text doit être coté ESP, il remonte dans HA, on l’exploite dans la carte et c’est fini (et un nettoyage sur les valeurs unitaires)

Après faire une combinaison de cartes (swipe par exemple) pour se balader entre les planning.

Dans les options pas indispensables : gestion du thème, trad …

Tu fais comment pour tester tes modis ? tu édites chaque fois le js dans /config/www/schedule-card/schedule-card.js et c’est pris en compte automatiquement ?

Pour le swipe, tu penses qu’il vaut mieux le gérer dans le js ou c’est plus simple de mettre une input_select qui change le contenu de la carte ?

A chaque modif de la carte, il faut vider les caches sinon ça tourne pas avec la dernière version.

A mon avis, il faut garder une carte minimaliste, si tu as 3 plannings d’autres peuvent en avoir 1 comme 15. Donc un swipe comme ha sait le faire (comme les regroupements H/V/Grille évoqués hier), et on peut exploiter X fois la carte comme chacun à envie

Suite à un échange avec djtef je poste une solution avec des cartes basiques et scripts HA

Je n’ai fait qu’une journée pour la démo sachant que je me suis concentré juste sur la logique d’affichage et non sur la carte elle même.

L’affichage est à base de carte mushroom template car c’est ce que j’avais sous la main mais la logique derrière est transposable à des custom-button-card.

J’ai un input_number par registre et 2 templates sensors (binaire, hex) qui ne sont la que pour le visuel et aider à la compréhension du fonctionnement et 1 script qui gère l’ensemble.

L’input number des registres :

Les templates sensor binaire et hexa :

Binaire

{{ "{:0=16b}".format(states('input_number.test_registre_31200')|int(0))|batch(1)|map('join')|join(' ') }}

Hexa

{{ '%02x'%  states('input_number.test_registre_31200')|int }}

Le rendu et fonctionnement :

registre pac

Le détail d’une carte :

type: custom:mushroom-template-card
icon: >-
  {% set registre_binary =
  "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
  ') %} {% if registre_binary.split(" ")[15] |int == 1 %}
    mdi:checkbox-blank
  {% else %}
    mdi:checkbox-blank-outline
  {% endif %}
features_position: bottom
color: >-
  {% set registre_binary =
  "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
  ') %} {% if registre_binary.split(" ")[15] |int == 1 %} green {% endif %}
tap_action:
  action: perform-action
  perform_action: script.test_registre
  target: {}
  data:
    num_registre: 31201
    valeur: 1
    split_value: 15
Le code complet de la page
type: sections
title: Test registre
cards: []
max_columns: 4
sections:
  - type: grid
    cards:
      - type: tile
        entity: input_number.test_registre_31201
        vertical: false
        features_position: bottom
        grid_options:
          columns: 8
          rows: 1
      - type: tile
        entity: sensor.test_registre_31201_hex
        vertical: false
        features_position: bottom
        grid_options:
          columns: 8
          rows: 1
      - type: custom:mushroom-empty-card
        grid_options:
          columns: 16
          rows: 1
      - type: tile
        entity: input_number.test_registre_31200
        vertical: false
        features_position: bottom
        grid_options:
          columns: 8
          rows: 1
      - type: tile
        entity: sensor.test_registre_31200_hex
        vertical: false
        features_position: bottom
        grid_options:
          columns: 8
          rows: 1
      - type: tile
        entity: sensor.test_registre_31201_binaire
        vertical: false
        features_position: bottom
        grid_options:
          columns: 8
          rows: 1
      - type: custom:mushroom-empty-card
        grid_options:
          columns: 24
          rows: 1
      - type: tile
        entity: sensor.test_registre_31200_binaire
        vertical: false
        features_position: bottom
        grid_options:
          columns: 8
          rows: 1
      - square: true
        type: grid
        cards:
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              00h
              01h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              01h
              02h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              02h
              03h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              03h
              04h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              04h
              05h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              05h
              06h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              06h
              07h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              07h
              08h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              08h
              09h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              09h
              10h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              10h
              11h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              11h
              12h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              12h
              13h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              13h
              14h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              14h
              15h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              15h
              16h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              16h
              17h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              17h
              18h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              18h
              19h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              19h
              20h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              20h
              21h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              21h
              22h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              22h
              23h
            multiline_secondary: true
          - type: custom:mushroom-template-card
            features_position: bottom
            secondary: |-
              23h
              00h
            multiline_secondary: true
        columns: 24
        grid_options:
          columns: full
      - square: true
        type: grid
        cards:
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[15] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[15] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31201
                valeur: 1
                split_value: 15
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[14] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[14] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31201
                valeur: 2
                split_value: 14
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[13] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[13] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31201
                valeur: 4
                split_value: 13
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[12] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[12] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31201
                valeur: 8
                split_value: 12
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[11] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[11] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31201
                valeur: 16
                split_value: 11
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[10] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[10] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31201
                valeur: 32
                split_value: 10
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[9] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[9] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31201
                valeur: 64
                split_value: 9
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[8] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[8] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31201
                valeur: 128
                split_value: 8
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[7] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[7] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31201
                valeur: 256
                split_value: 7
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[6] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[6] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31201
                valeur: 512
                split_value: 6
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[5] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[5] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31201
                valeur: 1024
                split_value: 5
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[4] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[4] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31201
                valeur: 2048
                split_value: 4
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[3] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[3] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31201
                valeur: 4096
                split_value: 3
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[2] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[2] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31201
                valeur: 8192
                split_value: 2
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[1] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[1] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31201
                valeur: 16384
                split_value: 1
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[0] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[0] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31201
                valeur: 32768
                split_value: 0
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31200')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[15] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31200')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[15] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31200
                valeur: 1
                split_value: 15
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31200')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[14] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31200')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[14] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31200
                valeur: 2
                split_value: 14
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31200')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[13] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31200')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[13] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31200
                valeur: 4
                split_value: 13
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31200')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[12] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31200')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[12] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31200
                valeur: 8
                split_value: 12
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31200')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[11] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31200')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[11] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31200
                valeur: 16
                split_value: 11
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31200')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[10] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31200')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[10] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31200
                valeur: 32
                split_value: 10
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31200')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[9] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31200')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[9] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31200
                valeur: 64
                split_value: 9
          - type: custom:mushroom-template-card
            icon: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31200')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[8] |int == 1 %}
                mdi:checkbox-blank
              {% else %}
                mdi:checkbox-blank-outline
              {% endif %}
            features_position: bottom
            color: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_31200')|int(0))|batch(1)|map('join')|join('
              ') %} {% if registre_binary.split(" ")[8] |int == 1 %} green {%
              endif %}
            tap_action:
              action: perform-action
              perform_action: script.test_registre
              target: {}
              data:
                num_registre: 31200
                valeur: 128
                split_value: 8
        columns: 24
        grid_options:
          columns: full
    column_span: 4

Le script qui gère l’affichage et le calcul :

sequence:
  - choose:
      - conditions:
          - condition: template
            value_template: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_'~num_registre)|int(0))|batch(1)|map('join')|join('
              ') %} {{ registre_binary.split(" ")[split_value] |int == 0 }}
        sequence:
          - action: input_number.set_value
            target:
              entity_id: input_number.test_registre_{{num_registre}}
            data:
              value: >-
                {{states('input_number.test_registre_'~num_registre)|int +
                valeur}}
      - conditions:
          - condition: template
            value_template: >-
              {% set registre_binary =
              "{:0=16b}".format(states('input_number.test_registre_'~num_registre)|int(0))|batch(1)|map('join')|join('
              ') %} {{ registre_binary.split(" ")[split_value] |int == 1 }}
        sequence:
          - action: input_number.set_value
            target:
              entity_id: input_number.test_registre_{{num_registre}}
            data:
              value: >-
                {{states('input_number.test_registre_'~num_registre)|int -
                valeur}}
description: ""
fields:
  valeur:
    selector:
      number:
        min: 1
        max: 65535
  split_value:
    selector:
      number:
        min: 0
        max: 15
  num_registre:
    selector:
      text: null
    name: num_registre
    required: true
alias: test - registre


Je suis parti d’une valeur décimale pour les inputs mais on peut très bien partir avec une valeur hexa. Pareil j’ai pris un input par registre mais on peut très bien concaténé tout pour avoir un input par journée (soit 2 registres).

3 « J'aime »

Bravo ! ça permet de décliner avec plein d’autres choses et d’exploiter cardmod ou streamline par dessus

2 « J'aime »

Oui j’avais déjà un truc semblable qui tourne mais avec bien moins de valeurs

Top ! :+1:
Merci pour ta proposition, c’est cool d’avoir plusieurs façons de faire, c’est un bon cas d’usage.
C’est une bonne idée d’avoir joué sur l’icone, j’avais eu cette idée avec les cartes de bases c’est pas possible.
La partie que j’avais pas réussi avec des cartes individuelles c’est la partie adaptation de l’écran, que se passe-t-il sur un téléphone ou si tu rétrécies la fenêtre ? Arrives-tu à afficher le titre de la ligne « Lundi » toujours en début de ligne ?

J’ai joué sur l’icone mais j’aurai très bien pu le faire sur le background en rajoutant du card_mod c’est que c’etait plus simple pour tester.

Alors tel quel si je rétréci c’est tout pété

J’ai laissé la carte binaire pour que tu te rendes compte de la largeur reelle en comparant avec mon premier gif.

Par contre ca fonctionne toujours et on peut virer l’icone et colorer le fond à la place mais faut passer par du card_mod. (3eme ligne j’ai pas virer l’icone partout)

Pareil on voit que les horaires disparaissent, peut être possible de gérer avec card_mod également.

Le code de la 1ere carte avec background

type: custom:mushroom-template-card
tap_action:
  action: perform-action
  perform_action: script.test_registre
  target: {}
  data:
    num_registre: 31201
    valeur: 1
    split_value: 15
features_position: bottom
card_mod:
  style: |
    ha-card {
      {% set registre_binary = "{:0=16b}".format(states('input_number.test_registre_31201')|int(0))|batch(1)|map('join')|join(' ') %}
      {% if registre_binary.split(" ")[15] |int == 1 %}
      background-color: green;
      {% endif %}
    }

en affichage telephone

Pour le jour oui je peux le garder devant

par contre en réduisant même problème que les heures

Je pense qu’avec une custom-button-card on doit pouvoir mieux gérer les textes sant passer par du card_mod mais je e la maitrise pas du tout.

Avec une custom:layout-card et toujours les mushroom template et un peu de card-mod, je suis arrivé à quelque chose de pas trop mal en vue section.

registre pac layout

Tout reste lisible jusqu’à 740px de large avec tailles de section par défaut. En dessous on perd en partie les textes mais ça reste fonctionnel.

1 « J'aime »

Salut,

Effectivement ça s’adapte mieux à écran avec ce système :+1:. J’ai jamais trop joué avec ces custom cards, t’as l’air de maitriser.

De mon côté j’ai voulu continuer sur mon idée de button-card (car je suis têtu et j’avais envie d’y arriver :sweat_smile:)
Après un nombre incalculable d’heures passées (je n’ose même pas calculer combien…) j’ai réussi pas trop mal à tout implémenter dans une seule grosse button-card. Ca m’a permis de découvrir tout ce dont elle était capable (il y a un paquet de choses quand on veut aller loin !). J’ai réussi à coder la logique du registre global en input_text (en réalité c’est pas ça car j’ai pas géré l’endianess mais pour la demo on s’en moque)
Voici ce que ça donne quand on redimensionne:

proga

Le code la custom:button-card (je l’ai tronqué pour que ça ne dépasse pas la limite de caractères du forum):

type: custom:button-card
grid_options:
  columns: full
styles:
  card:
    - overflow: auto
  grid:
    - grid-template-columns: max-content repeat(24, 1fr)
    - grid-template-rows: auto repeat(7, 1fr)
    - grid-template-areas: |
        "header_day h0_title h1_title h2_title h3_title h4_title h5_title h6_title h7_title h8_title h9_title h10_title h11_title h12_title h13_title h14_title h15_title h16_title h17_title h18_title h19_title h20_title h21_title h22_title h23_title"
        "label_lun h0_lun h1_lun h2_lun h3_lun h4_lun h5_lun h6_lun h7_lun h8_lun h9_lun h10_lun h11_lun h12_lun h13_lun h14_lun h15_lun h16_lun h17_lun h18_lun h19_lun h20_lun h21_lun h22_lun h23_lun"
        "label_mar h0_mar h1_mar h2_mar h3_mar h4_mar h5_mar h6_mar h7_mar h8_mar h9_mar h10_mar h11_mar h12_mar h13_mar h14_mar h15_mar h16_mar h17_mar h18_mar h19_mar h20_mar h21_mar h22_mar h23_mar"
        "label_mer h0_mer h1_mer h2_mer h3_mer h4_mer h5_mer h6_mer h7_mer h8_mer h9_mer h10_mer h11_mer h12_mer h13_mer h14_mer h15_mer h16_mer h17_mer h18_mer h19_mer h20_mer h21_mer h22_mer h23_mer"
        "label_jeu h0_jeu h1_jeu h2_jeu h3_jeu h4_jeu h5_jeu h6_jeu h7_jeu h8_jeu h9_jeu h10_jeu h11_jeu h12_jeu h13_jeu h14_jeu h15_jeu h16_jeu h17_jeu h18_jeu h19_jeu h20_jeu h21_jeu h22_jeu h23_jeu"
        "label_ven h0_ven h1_ven h2_ven h3_ven h4_ven h5_ven h6_ven h7_ven h8_ven h9_ven h10_ven h11_ven h12_ven h13_ven h14_ven h15_ven h16_ven h17_ven h18_ven h19_ven h20_ven h21_ven h22_ven h23_ven"
        "label_sam h0_sam h1_sam h2_sam h3_sam h4_sam h5_sam h6_sam h7_sam h8_sam h9_sam h10_sam h11_sam h12_sam h13_sam h14_sam h15_sam h16_sam h17_sam h18_sam h19_sam h20_sam h21_sam h22_sam h23_sam"
        "label_dim h0_dim h1_dim h2_dim h3_dim h4_dim h5_dim h6_dim h7_dim h8_dim h9_dim h10_dim h11_dim h12_dim h13_dim h14_dim h15_dim h16_dim h17_dim h18_dim h19_dim h20_dim h21_dim h22_dim h23_dim"

# ancres de base
hour_title: &hour_title
  type: custom:button-card
  styles:
    name:
      - font-size: 0.8em
      - margin-left: -100%
    card:
      - border-style: none
      - overflow: visible 

day_label: &day_label
  type: custom:button-card
  styles:
    name:
      - font-weight: bold
    card:
      - border-style: none

empty_cell: &empty_cell
  card:
    type: custom:button-card
    label: "​"
    show_label: true
    styles:
      card:
        - border-radius: 5px
        - min-width: 15px

custom_fields:
  header_day:
    card:
      type: custom:button-card
      color_type: blank-card
  h0_title:
    card:
      <<: *hour_title
      name: "0"
  h1_title:
    card:
      <<: *hour_title
      name: "1"
  h2_title:
    card:
      <<: *hour_title
      name: "2"
  h3_title:
    card:
      <<: *hour_title
      name: "3"
  h4_title:
    card:
      <<: *hour_title
      name: "4"
  h5_title:
    card:
      <<: *hour_title
      name: "5"
  h6_title:
    card:
      <<: *hour_title
      name: "6"
  h7_title:
    card:
      <<: *hour_title
      name: "7"
  h8_title:
    card:
      <<: *hour_title
      name: "8"
  h9_title:
    card:
      <<: *hour_title
      name: "9"
  h10_title:
    card:
      <<: *hour_title
      name: "10"
  h11_title:
    card:
      <<: *hour_title
      name: "11"
  h12_title:
    card:
      <<: *hour_title
      name: "12"
  h13_title:
    card:
      <<: *hour_title
      name: "13"
  h14_title:
    card:
      <<: *hour_title
      name: "14"
  h15_title:
    card:
      <<: *hour_title
      name: "15"
  h16_title:
    card:
      <<: *hour_title
      name: "16"
  h17_title:
    card:
      <<: *hour_title
      name: "17"
  h18_title:
    card:
      <<: *hour_title
      name: "18"
  h19_title:
    card:
      <<: *hour_title
      name: "19"
  h20_title:
    card:
      <<: *hour_title
      name: "20"
  h21_title:
    card:
      <<: *hour_title
      name: "21"
  h22_title:
    card:
      <<: *hour_title
      name: "22"
  h23_title:
    card:
      <<: *hour_title
      name: "23"

  label_lun:
    card:
      <<: *day_label
      name: Lun
  h0_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 0
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 0; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h1_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 1
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 1; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h2_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 2
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 2; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h3_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 3
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 3; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h4_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 4
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 4; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h5_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 5
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 5; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h6_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 6
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 6; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h7_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 7
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 7; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h8_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 8
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 8; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h9_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 9
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 9; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h10_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 10
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 10; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h11_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 11
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 11; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h12_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 12
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 12; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h13_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 13
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 13; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h14_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 14
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 14; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h15_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 15
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 15; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h16_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 16
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 16; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h17_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 17
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 17; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h18_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 18
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 18; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h19_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 19
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 19; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h20_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 20
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 20; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h21_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 21
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 21; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h22_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 22
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 22; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h23_lun:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 23
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 23; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]

  label_mar:
    card:
      <<: *day_label
      name: Mar
  h0_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 24
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 24; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h1_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 25
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 25; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h2_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 26
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 26; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h3_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 27
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 27; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h4_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 28
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 28; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h5_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 29
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 29; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h6_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 30
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 30; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h7_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 31
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 31; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h8_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 32
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 32; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h9_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 33
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 33; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h10_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 34
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 34; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h11_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 35
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 35; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h12_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 36
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 36; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h13_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 37
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 37; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h14_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 38
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 38; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h15_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 39
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 39; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h16_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 40
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 40; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h17_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 41
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 41; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h18_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 42
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 42; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h19_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 43
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 43; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h20_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 44
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 44; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h21_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 45
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 45; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h22_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 46
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 46; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h23_mar:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 47
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 47; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]

  label_mer:
    card:
      <<: *day_label
      name: Mer
  h0_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 48
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 48; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h1_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 49
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 49; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h2_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 50
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 50; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h3_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 51
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 51; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h4_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 52
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 52; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h5_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 53
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 53; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h6_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 54
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 54; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h7_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 55
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 55; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h8_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 56
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 56; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h9_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 57
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 57; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h10_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 58
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 58; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h11_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 59
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 59; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h12_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 60
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 60; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h13_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 61
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 61; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h14_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 62
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 62; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h15_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 63
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 63; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h16_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 64
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 64; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h17_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 65
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 65; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h18_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 66
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 66; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h19_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 67
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 67; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h20_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 68
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 68; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h21_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 69
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 69; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h22_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 70
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 70; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h23_mer:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 71
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 71; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]

  label_jeu:
    card:
      <<: *day_label
      name: Jeu
  h0_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 72
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 72; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h1_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 73
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 73; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h2_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 74
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 74; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h3_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 75
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 75; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h4_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 76
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 76; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h5_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 77
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 77; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h6_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 78
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 78; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h7_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 79
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 79; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h8_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 80
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 80; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h9_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 81
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 81; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h10_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 82
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 82; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h11_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 83
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 83; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h12_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 84
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 84; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h13_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 85
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 85; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h14_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 86
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 86; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h15_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 87
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 87; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h16_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 88
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 88; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h17_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 89
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 89; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h18_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 90
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 90; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h19_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 91
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 91; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h20_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 92
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 92; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h21_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 93
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 93; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h22_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 94
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 94; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h23_jeu:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 95
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 95; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]

  label_ven:
    card:
      <<: *day_label
      name: Ven
  h0_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 96
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 96; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h1_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 97
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 97; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h2_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 98
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 98; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h3_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 99
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 99; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h4_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 100
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 100; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h5_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 101
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 101; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h6_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 102
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 102; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h7_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 103
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 103; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h8_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 104
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 104; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h9_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 105
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 105; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h10_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 106
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 106; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h11_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 107
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 107; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h12_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 108
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 108; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h13_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 109
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 109; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h14_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 110
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 110; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h15_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 111
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 111; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h16_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 112
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 112; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h17_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 113
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 113; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h18_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 114
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 114; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h19_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 115
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 115; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h20_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 116
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 116; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h21_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 117
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 117; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h22_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 118
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 118; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
  h23_ven:

    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
          index: 119
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
          - background-color: >
              [[[
                // Récupérer le buffer (string hex)
                const buffer = states['input_text.proga_buffer'].state;
                if (!buffer || buffer.length < 56 ) return "red";
                const index = 119; 
                // Calcul byte/bit
                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);
                const bit_index  = index % 8;
                const hex = buffer.substr(byte_index * 2, 2);
                const byte = parseInt(hex, 16);
                const bit = (byte >> bit_index) & 1;
                return bit === 1 ? "green" : "white";
              ]]]
 

Le python pour la générer:

# Génère le YAML complet (7 jours × 24 heures) avec ancres et alias
header = """type: custom:button-card
grid_options:
  columns: full
styles:
  card:
    - overflow: auto
  grid:
    - grid-template-columns: max-content repeat(24, 1fr)
    - grid-template-rows: auto repeat(7, 1fr)
    - grid-template-areas: |
        "header_day h0_title h1_title h2_title h3_title h4_title h5_title h6_title h7_title h8_title h9_title h10_title h11_title h12_title h13_title h14_title h15_title h16_title h17_title h18_title h19_title h20_title h21_title h22_title h23_title"
        "label_lun h0_lun h1_lun h2_lun h3_lun h4_lun h5_lun h6_lun h7_lun h8_lun h9_lun h10_lun h11_lun h12_lun h13_lun h14_lun h15_lun h16_lun h17_lun h18_lun h19_lun h20_lun h21_lun h22_lun h23_lun"
        "label_mar h0_mar h1_mar h2_mar h3_mar h4_mar h5_mar h6_mar h7_mar h8_mar h9_mar h10_mar h11_mar h12_mar h13_mar h14_mar h15_mar h16_mar h17_mar h18_mar h19_mar h20_mar h21_mar h22_mar h23_mar"
        "label_mer h0_mer h1_mer h2_mer h3_mer h4_mer h5_mer h6_mer h7_mer h8_mer h9_mer h10_mer h11_mer h12_mer h13_mer h14_mer h15_mer h16_mer h17_mer h18_mer h19_mer h20_mer h21_mer h22_mer h23_mer"
        "label_jeu h0_jeu h1_jeu h2_jeu h3_jeu h4_jeu h5_jeu h6_jeu h7_jeu h8_jeu h9_jeu h10_jeu h11_jeu h12_jeu h13_jeu h14_jeu h15_jeu h16_jeu h17_jeu h18_jeu h19_jeu h20_jeu h21_jeu h22_jeu h23_jeu"
        "label_ven h0_ven h1_ven h2_ven h3_ven h4_ven h5_ven h6_ven h7_ven h8_ven h9_ven h10_ven h11_ven h12_ven h13_ven h14_ven h15_ven h16_ven h17_ven h18_ven h19_ven h20_ven h21_ven h22_ven h23_ven"
        "label_sam h0_sam h1_sam h2_sam h3_sam h4_sam h5_sam h6_sam h7_sam h8_sam h9_sam h10_sam h11_sam h12_sam h13_sam h14_sam h15_sam h16_sam h17_sam h18_sam h19_sam h20_sam h21_sam h22_sam h23_sam"
        "label_dim h0_dim h1_dim h2_dim h3_dim h4_dim h5_dim h6_dim h7_dim h8_dim h9_dim h10_dim h11_dim h12_dim h13_dim h14_dim h15_dim h16_dim h17_dim h18_dim h19_dim h20_dim h21_dim h22_dim h23_dim"

# ancres de base
hour_title: &hour_title
  type: custom:button-card
  styles:
    name:
      - font-size: 0.8em
      - margin-left: -100%
    card:
      - border-style: none
      - overflow: visible 

day_label: &day_label
  type: custom:button-card
  styles:
    name:
      - font-weight: bold
    card:
      - border-style: none

empty_cell: &empty_cell
  card:
    type: custom:button-card
    label: "​"
    show_label: true
    styles:
      card:
        - border-radius: 5px
        - min-width: 15px

custom_fields:
  header_day:
    card:
      type: custom:button-card
      color_type: blank-card
"""
empty_cell_card="""
    card:
      type: custom:button-card
      label: "​"
      show_label: true
      tap_action:
        action: perform-action
        perform_action: script.toggle_prog_bit
        data:
          prog: "A"
"""
empty_cell_styles="""
      styles:
        card:
          - border-radius: 5px
          - min-width: 15px
"""
jours = ["lun","mar","mer","jeu","ven","sam","dim"]

with open("lovelace_schedule.yaml","w",encoding="utf-8") as f:
    f.write(header)
    for h in range(24):
        f.write(f"  h{h}_title:\n    card:\n      <<: *hour_title\n      name: \"{h}\"\n")
    for j in jours:
        f.write(f"\n  label_{j}:\n    card:\n      <<: *day_label\n      name: {j.capitalize()}\n")
        for h in range(24):
            # f.write(f"  h{h}_{j}:\n    <<: *empty_cell\n")
            f.write(f"  h{h}_{j}:\n"+empty_cell_card)  
            f.write("          index: "+str(jours.index(j)*24 + h))
            f.write(empty_cell_styles)
            f.write("          - background-color: >\n")
            f.write("              [[[\n")
            f.write("                // Récupérer le buffer (string hex)\n")
            f.write("                const buffer = states['input_text.proga_buffer'].state;\n")
            f.write("                if (!buffer || buffer.length < 56 ) return \"red\";\n")
            f.write
            f.write("                const index = "+str(jours.index(j)*24 + h)+"; \n")
            f.write
            f.write("                // Calcul byte/bit\n")
            f.write("                const byte_index = 4 * Math.floor(index / 24) + 3 - Math.floor((index % 24) / 8);\n")
            f.write("                const bit_index  = index % 8;\n")
            f.write
            f.write("                const hex = buffer.substr(byte_index * 2, 2);\n")
            f.write("                const byte = parseInt(hex, 16);\n")
            f.write
            f.write("                const bit = (byte >> bit_index) & 1;\n")
            f.write
            f.write("                return bit === 1 ? \"green\" : \"white\";\n")
            f.write("              ]]]\n")            
print('Fichier "lovelace_schedule.yaml" généré')


Et le script Home Assistant toogle_prog_bit:

sequence:
  - variables:
      buffer_entity: "{{ 'input_text.prog' + prog + '_buffer' }}"
      buffer: "{{ states(buffer_entity) }}"
      byte_index: "{{ 4 * (index // 24)  + 3 - (index % 24 // 8)| int }}"
      bit_index: "{{ (index % 8) | int }}"
      old_byte_str: "{{ buffer[byte_index*2 : byte_index*2 + 2] | string }}"
      old_byte_val: "{{ int(old_byte_str | string, 0, 16) }}"
      bit_val: "{{ (old_byte_val // (2 ** bit_index)) % 2 }}"
      new_byte_val: |-
        {% if bit_val == 1 %}
          {{ (old_byte_val - (2 ** bit_index)) }}
        {% else %}
          {{ (old_byte_val + (2 ** bit_index)) }}
        {% endif %}
      new_byte: "{{ '{:02X}'.format(new_byte_val|int) }}"
      new_buf: "{{ buffer[:byte_index*2] ~ new_byte ~ buffer[byte_index*2 + 2:] }}"
  - target:
      entity_id: "{{ buffer_entity }}"
    data:
      value: "{{ new_buf }}"
    action: input_text.set_value
description: Toggle un bit dans un programme
fields:
  prog:
    description: Programme (A/B/C/D)
    example: A
  index:
    description: Index du bit (0-167)
    example: 0
alias: toggle_prog_bit

Maintenant je me bats avec ESPhome, c’est pas si évident que ça en l’air pour synchroniser les deux, mais je tiens le bon bout :slightly_smiling_face:

En tout cas merci pour vos solutions, ça va me servir.

Edit: J’ai mis à jour avec la correction pour gérer l’endianess

2 « J'aime »

Bonjour,

J’ai fini d’implémenter la programmation horaire, je présente le résultat sur le sujet dédié à la passerelle.

Lorsque je publierai le code sur github et le forum, je citerai cette discussion et je donnerai les différentes solutions.

Merci encore pour votre aide et vos idées :+1:

2 « J'aime »

Ce sujet a été automatiquement fermé après 60 jours. Aucune réponse n’est permise dorénavant.