[RESOLU] Affichage d'un tableau de taille variable limitée à 255 caractères

Bonjour,

J’utilise HA en parallèle d’une application que je développe en python, les deux dialoguant via Mqtt. Je souhaite afficher dans une zone un tableau de taille variable dont les éléments sont des noms d’équipements et leur état de connexion au réseau (avec quelques autres informations). Pour transférer les infos de l’application vers HA, je me confronte donc rapidement à la limite des 255 caractères d’une entité. L’idée est d’avoir un système qui s’adapte automatiquement à l’ajout d’équipements sans modifier de code : c’est le cas côté détection (application python) mais je n’ai pas trouvé la solution côté affichage.

J’ai cherché sur les forums mais n’ai rien trouvé de concluant… J’ai donc essayé la solution suivante :

  • mon application python génère un fichier html,
  • j’utilise html-template-card dans ha avec un iframe qui fait appel à ce fichier html (/local/monfichier.html par exemple). Le nom du fichier est envoyé par l’application à HA via un message MQTT. La réception de ce message permet bien de rafraichir l’affichage du contenu de la carte sur le navigateur de mon PC, mais pas avec l’APP Android. Sur l’application, le contenu de la « frame » affiché est celui du tout premier affichage et ne change plus (même en rechargeant les ressources ou en rafraichissant). Je pense qu’il y a une notion de cache.

Auriez-vous une idée me permettant de transmettre à HA pour affichage des informations via une chaine de caractères sans limite de taille : le protocole mqtt peut être remplacer par l’API rest ou autre, le formatage de l’affichage peut être généré par HA ou par mon application Python ? J’ai découvert le monde HA depuis le début de l’année, je suis donc loin de connaitre toutes les possibilités offertes…

Ma configuration


[center]## System Information

version core-2024.2.2
installation_type Unsupported Third Party Container
dev false
hassio false
docker true
user abc
virtualenv false
python_version 3.12.2
os_name Linux
os_version 6.1.0-rpi8-rpi-v8
arch aarch64
timezone Europe/Paris
config_dir /config
Home Assistant Community Store
GitHub API ok
GitHub Content ok
GitHub Web ok
GitHub API Calls Remaining 5000
Installed Version 1.34.0
Stage running
Available Repositories 1469
Downloaded Repositories 15
HACS Data ok
Home Assistant Cloud
logged_in false
can_reach_cert_server ok
can_reach_cloud_auth ok
can_reach_cloud ok
Dashboards
dashboards 11
resources 9
views 28
mode yaml
Recorder
oldest_recorder_run 20 août 2024 à 20:23
current_recorder_run 8 septembre 2024 à 17:47
estimated_db_size 48.20 MiB
database_engine sqlite
database_version 3.44.2
[/center]

bonjour
tu peux essayer d’intégrer dans ton url une variable qui ne sert à rien si ce n’est à rafraîchir ta page
https://www.home-assistant.io?resfresh=0 puis https://www.home-assistant.io?resfresh=1 etc
l’idéal serai de mettre un timestamp comme valeur
https://www.home-assistant.io?resfresh=1725836494 pour le 09/09/2024 à 01:01:34
l’URL étant différente sa force le cache à être actualisé

Bonjour, la limite de 255 caractères existe pour l’état du sensors mais pas le un attribut.

Je te conseil de formater ta donnée en type liste, ce qui est très bien adapté pour un tableau :

list:
  - retard: 0
    depart: "2024-09-08 15:24:00+02:00"
    depart_reel: "2024-09-08 15:24:00+02:00"
    status: programmer
  - retard: 0
    depart: "2024-09-08 16:24:00+02:00"
    depart_reel: "2024-09-08 16:24:00+02:00"
    status: programmer
  - retard: 0
    depart: "2024-09-08 17:24:00+02:00"
    depart_reel: "2024-09-08 17:24:00+02:00"
    status: programmer
  - retard: 0
    depart: "2024-09-08 18:24:00+02:00"
    depart_reel: "2024-09-08 18:24:00+02:00"
    status: programmer
  - retard: 0
    depart: "2024-09-08 19:24:00+02:00"
    depart_reel: "2024-09-08 19:24:00+02:00"
    status: programmer
bus_restant_pour_aujourd_hui: 5
refresh: "2024-09-08 15:08:09.680407+02:00"
device_class: timestamp
friendly_name: "Bus 23 "

Bonsoir, merci pour ta réponse selecus.

Quelque part c’est ce que je pensais faire, à la différence que je n’appelais pas une url mais un fichier avec une ligne du type :
<iframe class="transparent-iframe" src="{{ states('sensor.reseau_ethernet_equipements') }}"></iframe> en changeant également la valeur d’une balise avec le contenu de mon « states » équivalent à /local/monfichier-timestamp.html

A chaque fois que l’entité change, sur firefox sur le pc, l’affichage se met bien à jour avec le bon contenu, mais pas sur mon téléphone. Du coup, j’ai essayé avec mon site en ligne et une url en http://… et dans ce cas, ça à l’air de marcher à la fois sur le PC et sur le téléphone. Mais je trouve la solution un peu lourde à mettre en place au final.

1 « J'aime »

Merci Roumano,
Tu m’as mis sur la bonne voie : j’avais vu cette différence entre state/attribute, mais sans trop comprendre (d’ailleurs je ne suis pas encore sûr d’avoir compris) la différence d’utilité entre ces deux notions. Néanmoins, mon premier test m’a permis de modifier l’attribut d’un capteur (via rest) sans avoir de problème de nombre de caractères. Je vais continuer dans ce sens car je pense qu’il va me permettre d’arriver à faire ce que je souhaite.

1 « J'aime »

tiens-nous au courant de ta solution. ce genre de petits problèmes est toujours passionnant

Une fois sur la bonne piste, je n’ai pas mis longtemps à revenir :sweat_smile:
Pour adapter à ce que j’ai déjà fait (en mqtt), je me suis dit qu’il n’y avait pas de raison que le principe ne soit pas le même qu’avec l’API Rest ! Du coup j’ai suivi ce lien, et plus particulièrement la partie ‹ attributes ›, et voilà, le tour est joué ! Pour l’instant, mon appli envoie un message contenant le « préformattage html » qui est affiché directement grâce à html-template-card, ça se met à jour instannément, aussi bien sur le navigateur du pc que dans l’application compagnon sur le mobile…

Merci à vous pour votre aide !

1 « J'aime »

Super si ça a put t’aider, …

Voici, comment j’ai fait en multiscrape pour gerer une liste :

- name: Bus ZZZ - XXX -> YYYY
  resource: https://data.mobilites-m.fr/api/routers/default/index/stops/SEM:XXXX/stoptimes
  headers:
    origin: home-assistant
    Content-Type: application/json
  scan_interval: 0
  button:
    - name: Mise a jour des bus Ligne 23 - XXX -> YYYY
      unique_id: bus_23_refresh_XXX_YYYY
  sensor:
    - name: 'Bus 23 '
      unique_id: bus_23_XXX_YYYY
      value_template: >
        {% if value_json[0].times | list | count >= 1 %}
          {{ strptime(((today_at('00:00') + timedelta(seconds= (value_json[0].times[0].scheduledArrival | int) )) | string), '%Y-%m-%d %H:%M:%S%z') }}
        {% else %}
          unavailable
        {% endif %}
      device_class: timestamp
      attributes:
        - name: list
          value_template: >
            [
            {%- for i in range(0, value_json[0].times | list | count, 1) -%}
              {%- if (value_json[0].times[i].realtimeState == 'SCHEDULED') -%}
                {%- set status = 'programmer' -%}
              {%- else -%}
                {%- set status = value_json[0].times[0].realtimeState -%}
              {% endif %}
              {%- set cycle = {'retard': value_json[0].times[i].arrivalDelay, 'depart': (today_at('00:00') + timedelta(seconds= ((value_json[0].times[i].scheduledArrival | int) ))) | string, 'depart_reel': (today_at('00:00') + timedelta(seconds= ((value_json[0].times[i].realtimeArrival | int) ))) | string, 'status': status }-%}
              {{ cycle }},
            {% endfor %}
            ]
        - name: "Bus Restant pour aujourd'hui"
          value_template: "{{ value_json[0].times | list | count }}"
        - name: Refresh
          value_template: "{{ now() }}"

Et une fois en liste, l’affichage en tableau est facile ( mais un peut travailler pour que ce soit facile a lire) :

  type: custom:flex-table-card
  strict: true
  title: Bus Retour
  sort_by:
    - depart+
  columns:
    - name: Depart
      data: list
      modify: |-
        if (parseInt(x.retard) >= 1 ) '<div style="color:#E70B0B;">' +
          x.depart.substr(11,5) + ' -> ' + x.depart_reel.substr(11,5) + '</div>'
        else
          x.depart.substr(11,5)
    - name: Depart2
      data: list
      modify: x.depart
      id: depart
      hidden: true
    - name: DepartReel
      data: list
      modify: x.depart_reel
      id: departreel
      hidden: true
    - name: Retard
      data: list
      modify: |
        if (parseInt(x.retard) >= 3600 )
          '<div style="color:#E70B0B;">' + Math.trunc(x.retard /3600) + 'h' + Math.trunc(x.retard /60) + 'm' +x.retard % 60 + 's</div>'
        else if (parseInt(x.retard) >= 60 )
          '<div style="color:#E70B0B;">' + Math.round(x.retard /60) + 'm' + '</div>'
        else if (parseInt(x.retard) >= 1 )
          '<div style="color:#E70B0B;">' + x.retard + 's</div>'
        else
          '<div style="color:#139523;">' + x.retard + '</div>'
    - name: Statut
      data: list
      modify: |
        if (x.status != "programmer" || x.status != "UPDATED")
          '<div style="color:#139523;">' + x.status + '</div>'
        else
          '<div style="color:#E70B0B;">' + x.status + '</div>'
  entities:
    include: sensor.bus_23_XXX_YYY
  card_mod:
    style: |
      tbody tr:hover {
        background-color: coral !important;
      }
  css:
    table+: 'border-collapse: collapse; padding: 1px;'
    th+: 'border: 1px solid white; padding: 3px;'
    td+: 'border: 1px solid white; padding: 3px;'