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 
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;'