Cela fonctionne pour TOUS les contrats proposés par EDF. (Offres Zen, Offres Bleu, Tempo, Offres électricité verte et Gaz naturel)
Solutions déjà données pour les contrats suivants, actuellement :
- Tempo
- Bleu - HP HC
- Bleu option base
- Zen fixe HP HC
Bonjour à tous,
Dans cet exemple, cela concerne le prix mensuel de l’abonnement EDF Zen Fixe HP/HC 9kVa, et celui des kWh, que je récupère directement sur le .PDF mis en ligne et tenu à jour sur le site d’EDF, grâce à l’intégration PDF Scrape disponible là : GitHub - iluvdata/pdf_scrape: Scrape PDF files available via http or https to create sensors in Homeassistant
En complément (optionnel - étape 6 et 7), cette méthode est basée sur le fait de mettre à jour une entrée input.number en lui changeant sa valeur en fonction de celle du capteur correspondant créé sous PDF Scrape, c’est à dire récupérée sur internet, uniquement si elle est disponible. Si indisponible, vous gardez la dernière valeur valide.
Pour cela :
ETAPE 1 : Mise en place de PDF Scrape
Après avoir installé PDF Scrape depuis HACS.
Sous Appareils&services, cliquer sur Ajouter une intégration, et recherchez « PDF Scrape», puis installez-la.
ETAPE 2 : Récupérer toutes les informations du PDF ciblé
Ici, il vous faut indiquer :
Name : Le nom de fichier PDF que HA doit lire
URL of PDF : Le lien du fichier PDF en question (doit se terminer par .pdf)
Update interval :
Mettre 8760 heures, soit 1 an !
Dans mon cas, j’utilise le lien : https://particulier.edf.fr/content/dam/2-Actifs/Documents/Offres/Grille-prix-zen-fixe.pdf
Vous pourrez créer autant de Capteurs que vous le désirez à partir des informations contenues dans ce texte. C’est ainsi que l’on va pouvoir créer 3 capteurs : prix abonnement + prix kwh heures pleines + prix kwh heures creuses. Possible de récupérer la date d’application de la nouvelle tarification sous forme de capteur aussi.
ETAPE 3 : Ajouter un capteur - Add Search Target
A cette étape, vous allez créer un capteur en définissant l’endroit où se trouve la valeur désirée sur le texte en provenance du PDF.
En cliquant sur « Add Search Target ».
1°) Target Page → si le PDF a plusieurs pages, sélectionner celle contenant la valeur recherchée
2°) Regular Expression → Laisser tel quel
3°) Configure Sensor →
Name : Donner le nom du capteur voulu
Limited Template :
Vous trouverez tout en bas de ce tutoriel une liste des URL + Limited Template à utiliser suivant vos contrats. Si le votre n’est pas dedans, merci d’en faire la demande, ou de partager si vous avez réussi à le faire par vous-même.
Unit of Measurement : €
Résultat pour Zen fixe HP HC, dans mon cas :
ETAPE 4 : Créer une automatisation pour tenter de mettre à jour le PDF source toutes les 12h, uniquement les 5 premiers jours de févriers et d’aout, dates auxquelles les tarifs sont mis à jour chaque année depuis 8 ans maintenant.
Attention à l’indentation, sinon erreur !! ![]()
Le device_id à mettre est celui de VOTRE configuration PDF SCRAPE
alias: Mise à jour automatique du PDF EDF
description: >-
Va chercher la nouvelle version du PDF contenant le prix de l'abonnement et
des kwh, entre le 1 et le 5 février et même chose en aout.
triggers:
- trigger: time_pattern
hours: /12
conditions:
- condition: template
value_template: "{{ now().month in [2, 8] and now().day in range(1, 6) }}"
actions:
- action: homeassistant.reload_config_entry
metadata: {}
target:
device_id: 184bc781f8bba3ac051606855de7bb08
data: {}
mode: single
ETAPE 5 : Créer un capteur divisant le prix de l’abonnement mensuel par le nombre de jour du mois en cours.
Pour les abonnements uniquement, le montant étant par mois, on crée une entité Template permettant d’avoir un coût journalier.
On vient créer un capteur Template qui reprend ce cout, et l’adapte pour le diviser par le nombre de jours dans le mois en cours, avant de le multiplier par 1000, avec EUR/kWh en unité de mesure. (l’idée étant d’ajouter seulement un wh/jour via une automatisation, raison de la multiplication du prix par 1000)
{% set montant_mensuel = states('sensor.nom_du_sensor_cree_avec_pdf_scrape_pour_abonnement') | float %}
{% set now = now() %}
{% set start_of_month = now.replace(day=1) %}
{% set end_of_month = (start_of_month + timedelta(days=31)).replace(day=1) - timedelta(days=1) %}
{% set days_in_month = (end_of_month - start_of_month).days + 1 %}
{{ ((montant_mensuel / days_in_month) * 1000) | round(2) }}
Pour voir le cout journalier de l’abonnement dans la page « Energie », utiliser le tuto suivant : Ajout du cout de l'abonnement EDF/Gaz/Eau (ou autre fournisseur) au dashboard Energy - accessible à tous
Attention, sauter l’étape 1 sur celui-ci, vous venez de la faire ici. ![]()
ETAPE 6 : Optionnel → ajout d’une sécurité concernant mise à jour du capteur - Partie 1
A présent, afin de s’assurer d’avoir toujours un capteur valide, on va créer un input.number sur lequel on va transférer la valeur du capteur correspondant créé via PDF Scrape. Si 3 capteurs, alors il faudra créer 3 input_number : un pour chacun.
Pour cela, se rendre sur « Appareils&services », puis « Entrées », et cliquer sur « Créer une Entrée ».
Pour l’abonnement, par exemple, il aura pour ID : input_number.nom_du_sensor_cree_avec_pdf_scrape_pour_abonnement
Avec une valeur max de 1000, du fait que le prix de l’abonnement sera normalement toujours en dessous.
ETAPE 7 : Optionnel → ajout d’une sécurité concernant mise à jour du capteur - Partie 2
Il ne reste plus qu’à créer l’automatisation qui va prendre la valeur du capteur créé sous PDF Scrape, pour la coller sur ce nouveau capteur input.number, créé à l’étape 5, qu’on utilisera sur la page Énergie.
Et comme garde-fou, on ne fera la mise à jour que si le capteur sous PDF Scrape est valide. Dans le cas contraire, notre input_number reste lui valide.
Voici l’automatisation correspondante :
alias: "Mise à jour coût abonnement si valide dans PDF Scrape "
description: ""
triggers:
- entity_id:
- sensor.nom_du_sensor_cree_avec_pdf_scrape_pour_abonnement
trigger: state
conditions:
- condition: template
value_template: >
{{ not states('sensor.nom_du_sensor_cree_avec_pdf_scrape_pour_abonnement') in ['unavailable', 'unknown']
}}
actions:
- target:
entity_id: input_number.nom_du_sensor_cree_avec_pdf_scrape_pour_abonnement
data:
value: "{{ states('sensor.nom_du_sensor_cree_avec_pdf_scrape_pour_abonnement') }}"
action: input_number.set_value
Si vous récupérez comme moi 3 prix (abonnement + prix kwh hp et hc), il vous faudra 3 input.number, bien sûr. Et adapter l’automatisation pour qu’elle soit valide pour chacun d’eux, ou simplement faire 3 automatisations.
INFOS COMPLÉMENTAIRES :
Vous avez un capteur « propre » qui restera même si vous supprimez un jour PDF Scrape.
Enfin, tant que vous utilisez cette manière de faire, vous aurez une valeur qui ne pourra jamais être indisponible.
LISTE DES URL DES PDF et LIMITED TEMPLATE CORRESPONDANTS :
Date d’application indiquée sur le PDF :
{% set mois = {'janvier':'01','février':'02','fevrier':'02','mars':'03','avril':'04','mai':'05','juin':'06','juillet':'07','août':'08','aout':'08','septembre':'09','octobre':'10','novembre':'11','décembre':'12','decembre':'12'} %}
{% set found = namespace(date='') %}
{% for line in value.split('\n') %}
{% if 'Applicable au' in line and found.date == '' %}
{% set line_lower = line.lower() %}
{% for mois_nom, mois_num in mois.items() %}
{% if mois_nom in line_lower %}
{% set annees = line | regex_findall('(20\d\d)') %}
{% if annees|length > 0 %}
{% set found.date = '01/' ~ mois_num ~ '/' ~ annees[0] %}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{{ found.date if found.date != '' else 'Non disponible' }}
Zen Fixe HP/HC :
URL du PDF : https://particulier.edf.fr/content/dam/2-Actifs/Documents/Offres/Grille-prix-zen-fixe.pdf
- Limited Template Abonnement mensuel 9kVa :
{% set found = namespace(val='', in_hc=false) %}
{% for line in value.split('\n') %}
{% if 'Option Heures Creuses' in line %}
{% set found.in_hc = true %}
{% endif %}
{% if found.in_hc and found.val == '' and line.strip().startswith('9 ') %}
{% set parts = line.strip().split() %}
{% if parts|length >= 2 %}
{% set found.val = parts[1] %}
{% endif %}
{% endif %}
{% endfor %}
{{ (found.val | replace(',', '.') | float) | round(2) if found.val else 0 }}
Abonnement mensuel 3, 6, 12kVa et autres :
Remplacer le 9 dans cette ligne par la puissance correspondant à votre abonnement :
{% if found.in_hc and found.val == '' and line.strip().startswith('9 ') %}
- Limited Template kWh Heures pleines :
{% set found = namespace(val='', count=0, in_hc=false) %}
{% for line in value.split('\n') %}
{% if 'Option Heures Creuses' in line %}
{% set found.in_hc = true %}
{% endif %}
{% if found.in_hc and found.val == '' %}
{% set found.count = 0 %}
{% set parts = line.strip().split() %}
{% for part in parts %}
{% if ',' in part %}
{% set found.count = found.count + 1 %}
{% endif %}
{% endfor %}
{% if found.count == 2 %}
{% for part in parts %}
{% if ',' in part and found.val == '' %}
{% set found.val = part %}
{% endif %}
{% endfor %}
{% endif %}
{% endif %}
{% endfor %}
{{ (found.val | replace(',', '.') | float / 100) | round(4) if found.val else 0 }}
- Limited Template kWh Heures creuses :
{% set found = namespace(val='', count=0, found_count=0, in_hc=false) %}
{% for line in value.split('\n') %}
{% if 'Option Heures Creuses' in line %}
{% set found.in_hc = true %}
{% endif %}
{% if found.in_hc and found.val == '' %}
{% set found.count = 0 %}
{% set parts = line.strip().split() %}
{% for part in parts %}
{% if ',' in part %}
{% set found.count = found.count + 1 %}
{% endif %}
{% endfor %}
{% if found.count == 2 %}
{% set found.found_count = 0 %}
{% for part in parts %}
{% if ',' in part %}
{% set found.found_count = found.found_count + 1 %}
{% if found.found_count == 2 %}
{% set found.val = part %}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endif %}
{% endfor %}
{{ (found.val | replace(',', '.') | float / 100) | round(4) if found.val else 0 }}
Bleu Heures pleines heures creuses:
URL du PDF : https://particulier.edf.fr/content/dam/2-Actifs/Documents/Offres/Grille_prix_Tarif_Bleu.pdf
- Limited Template Abonnement mensuel 9kVa :
{% set found = namespace(val='', in_hc=false) %}
{% for line in value.split('\n') %}
{% if 'Option Heures Creuses' in line %}
{% set found.in_hc = true %}
{% endif %}
{% if found.in_hc and found.val == '' and line.strip().startswith('9 ') %}
{% set parts = line.strip().split() %}
{% if parts|length >= 2 %}
{% set found.val = parts[1] %}
{% endif %}
{% endif %}
{% endfor %}
{{ (found.val | replace(',', '.') | float) | round(2) if found.val else 0 }}
Abonnement mensuel 3, 6, 12kVa et autres :
Remplacer le 9 dans cette ligne par la puissance correspondant à votre abonnement :
{% if found.in_hc and found.val == '' and line.strip().startswith('9 ') %}
- Limited Template kWh Heures pleines :
{% set found = namespace(val='', in_hc=false) %}
{% for line in value.split('\n') %}
{% if 'Option Heures Creuses' in line %}
{% set found.in_hc = true %}
{% endif %}
{% if found.in_hc and found.val == '' and line.strip().startswith('6 ') %}
{% set parts = line.strip().split() %}
{% if parts|length >= 3 %}
{% set found.val = parts[2] %}
{% endif %}
{% endif %}
{% endfor %}
{{ (found.val | replace(',', '.') | float / 100) | round(4) if found.val else 0 }}
- Limited Template kWh Heures creuses :
{% set found = namespace(val='', in_hc=false) %}
{% for line in value.split('\n') %}
{% if 'Option Heures Creuses' in line %}
{% set found.in_hc = true %}
{% endif %}
{% if found.in_hc and found.val == '' and line.strip().startswith('6 ') %}
{% set parts = line.strip().split() %}
{% if parts|length >= 4 %}
{% set found.val = parts[3] %}
{% endif %}
{% endif %}
{% endfor %}
{{ (found.val | replace(',', '.') | float / 100) | round(4) if found.val else 0 }}
Tempo:
URL du PDF : https://particulier.edf.fr/content/dam/2-Actifs/Documents/Offres/Grille_prix_Tarif_Bleu.pdf
- Limited Template Abonnement mensuel 9kVa :
{% set found = namespace(val='', in_tempo=false) %}
{% for line in value.split('\n') %}
{% if 'Option Tempo' in line %}
{% set found.in_tempo = true %}
{% endif %}
{% if found.in_tempo and found.val == '' and line.strip().startswith('9 ') %}
{% set parts = line.strip().split() %}
{% if parts|length >= 2 %}
{% set found.val = parts[1] %}
{% endif %}
{% endif %}
{% endfor %}
{{ (found.val | replace(',', '.') | float) | round(2) if found.val else 0 }}
Abonnement mensuel 3, 6, 12kVa et autres :
Remplacer le 9 dans cette ligne par la puissance correspondant à votre abonnement :
{% if found.in_hc and found.val == '' and line.strip().startswith('9 ') %}
- Limited Template kWh jour bleu HC :
{% set found = namespace(val='', in_tempo=false) %}
{% for line in value.split('\n') %}
{% if 'Option Tempo' in line %}
{% set found.in_tempo = true %}
{% endif %}
{% if found.in_tempo and found.val == '' and line.strip().startswith('6 ') %}
{% set parts = line.strip().split() %}
{% if parts|length >= 3 %}
{% set found.val = parts[2] %}
{% endif %}
{% endif %}
{% endfor %}
{{ (found.val | replace(',', '.') | float / 100) | round(4) if found.val else 0 }}
- Limited Template kWh jour bleu HP :
{% set found = namespace(val='', in_tempo=false) %}
{% for line in value.split('\n') %}
{% if 'Option Tempo' in line %}
{% set found.in_tempo = true %}
{% endif %}
{% if found.in_tempo and found.val == '' and line.strip().startswith('6 ') %}
{% set parts = line.strip().split() %}
{% if parts|length >= 4 %}
{% set found.val = parts[3] %}
{% endif %}
{% endif %}
{% endfor %}
{{ (found.val | replace(',', '.') | float / 100) | round(4) if found.val else 0 }}
- Limited Template kWh jour blanc HC :
{% set found = namespace(val='', in_tempo=false) %}
{% for line in value.split('\n') %}
{% if 'Option Tempo' in line %}
{% set found.in_tempo = true %}
{% endif %}
{% if found.in_tempo and found.val == '' and line.strip().startswith('6 ') %}
{% set parts = line.strip().split() %}
{% if parts|length >= 5 %}
{% set found.val = parts[4] %}
{% endif %}
{% endif %}
{% endfor %}
{{ (found.val | replace(',', '.') | float / 100) | round(4) if found.val else 0 }}
- Limited Template kWh jour blanc HP :
{% set found = namespace(val='', in_tempo=false) %}
{% for line in value.split('\n') %}
{% if 'Option Tempo' in line %}
{% set found.in_tempo = true %}
{% endif %}
{% if found.in_tempo and found.val == '' and line.strip().startswith('6 ') %}
{% set parts = line.strip().split() %}
{% if parts|length >= 6 %}
{% set found.val = parts[5] %}
{% endif %}
{% endif %}
{% endfor %}
{{ (found.val | replace(',', '.') | float / 100) | round(4) if found.val else 0 }}
- Limited Template kWh jour rouge HC :
{% set found = namespace(val='', in_tempo=false) %}
{% for line in value.split('\n') %}
{% if 'Option Tempo' in line %}
{% set found.in_tempo = true %}
{% endif %}
{% if found.in_tempo and found.val == '' and line.strip().startswith('6 ') %}
{% set parts = line.strip().split() %}
{% if parts|length >= 7 %}
{% set found.val = parts[6] %}
{% endif %}
{% endif %}
{% endfor %}
{{ (found.val | replace(',', '.') | float / 100) | round(4) if found.val else 0 }}
- Limited Template kWh jour rouge HP :
{% set found = namespace(val='', in_tempo=false) %}
{% for line in value.split('\n') %}
{% if 'Option Tempo' in line %}
{% set found.in_tempo = true %}
{% endif %}
{% if found.in_tempo and found.val == '' and line.strip().startswith('6 ') %}
{% set parts = line.strip().split() %}
{% if parts|length >= 8 %}
{% set found.val = parts[7] %}
{% endif %}
{% endif %}
{% endfor %}
{{ (found.val | replace(',', '.') | float / 100) | round(4) if found.val else 0 }}
Bleu option base
URL du PDF : https://particulier.edf.fr/content/dam/2-Actifs/Documents/Offres/Grille_prix_Tarif_Bleu.pdf
- Limited Template Abonnement mensuel 9kVa :
{% set found = namespace(val='', in_base=false) %}
{% for line in value.split('\n') %}
{% if 'Option Base' in line %}
{% set found.in_base = true %}
{% endif %}
{% if 'Option Heures Creuses' in line %}
{% set found.in_base = false %}
{% endif %}
{% if found.in_base and found.val == '' and line.strip().startswith('9 ') %}
{% set parts = line.strip().split() %}
{% if parts|length >= 2 %}
{% set found.val = parts[1] %}
{% endif %}
{% endif %}
{% endfor %}
{{ (found.val | replace(',', '.') | float) | round(2) if found.val else 0 }}
- Limited Template kWh :
{% set found = namespace(val='', in_base=false) %}
{% for line in value.split('\n') %}
{% if 'Option Base' in line %}
{% set found.in_base = true %}
{% endif %}
{% if 'Option Heures Creuses' in line or 'Option Tempo' in line %}
{% set found.in_base = false %}
{% endif %}
{% if found.in_base and found.val == '' and line.strip().startswith('6 ') %}
{% set parts = line.strip().split() %}
{% if parts|length >= 3 %}
{% set found.val = parts[2] %}
{% endif %}
{% endif %}
{% endfor %}
{{ (found.val | replace(',', '.') | float / 100) | round(4) if found.val else 0 }}
Enjoy !
:









