Skip to main content

enedis-client

Récupère la courbe de charge de ton compteur Linky via la passerelle MyElectricalData, et l'exporte en JSON et en CSV.

Première brique d'une future intégration Home Assistant : toute la logique d'accès aux données vit ici, pour être réutilisée telle quelle ensuite.

Démarrage

make setup      # venv + dépendances
make demo       # essaie tout, sans token ni réseau

make demo fait tourner la chaîne complète — découpage en fenêtres, parsing, agrégation, export — sur des données simulées. C'est le moyen le plus rapide de voir ce que produit l'outil sans toucher à ton quota Enedis.

Pour de vraies données :

cp .env.example .env    # puis renseigne ENEDIS_PDL et ENEDIS_TOKEN
make check              # vérifie le consentement et le quota restant
make daily              # consommation quotidienne en kWh -> dumps/
make fetch              # courbe de charge (nécessite la collecte horaire)

Commence par make daily. La consommation quotidienne ne dépend que du consentement et fonctionne immédiatement. La courbe de charge, elle, exige en plus que la collecte horaire soit activée chez Enedis — voir En cas de problème.

Commandes

Commande Effet
enedis check Valide le .env, l'état du consentement Enedis et le quota d'appels
enedis daily --days 30 Consommation quotidienne en kWh — marche sans la collecte horaire
enedis fetch --days 30 Courbe de charge au pas du compteur
enedis fetch --start 2026-01-01 --end 2026-02-01 Une période précise (--end est exclue)
enedis demo --days 20 La courbe de charge sur des données simulées
enedis cache-clear Efface les données que la passerelle a mises en cache

Options communes : --format json|csv|both, --out <dossier>, --no-cache, -y/--yes, -v pour le détail, --env-file pour un .env alternatif.

--end est exclue : --end 2026-02-01 s'arrête au 31 janvier inclus. Les périodes impossibles (inversées, futures, au-delà de 24 mois) sont refusées avec un message et le code de sortie 2, avant le moindre appel réseau.

Le binaire s'appelle enedis une fois le projet installé ; python -m enedis_client fonctionne aussi.

Le cache stocke tes données chez un tiers

Les endpoints en /cache font stocker tes données chiffrées, pendant 30 jours, sur les serveurs de MyElectricalData. C'est un compromis : le cache épargne le quota Enedis, qui est serré.

Le cache est actif par défaut, et chaque commande le rappelle à l'écran. --no-cache va chercher la donnée directement chez Enedis sans rien y laisser, au prix d'un appel de quota. enedis cache-clear efface ce qui y est déjà.

Ce que couvre le client

Endpoint Méthode Donnée
consumption_load_curve consumption_load_curve() Puissance moyenne en W, au pas du compteur
production_load_curve production_load_curve() Idem, en production (photovoltaïque)
daily_consumption daily_consumption() Énergie en Wh, par journée
daily_production daily_production() Idem, en production
contracts contracts() Puissance souscrite, option tarifaire
valid_access valid_access() Consentement, quota, réinitialisation
*/cache (DELETE) clear_cache() Purge du cache de la passerelle

identity, contact et addresses existent aussi côté passerelle mais ne sont pas exposés : ce sont des données personnelles sans rapport avec la consommation.

En bibliothèque

from datetime import date, timedelta
from enedis_client import MyElectricalDataClient, Settings, fetch_daily, fetch_load_curve

today = date.today()
with MyElectricalDataClient(Settings.from_env()) as client:
    # Quotidien : une énergie en Wh par journée.
    series = fetch_daily(client, today - timedelta(days=30), today)
    print(f"{series.total_energy_kwh:.1f} kWh sur {len(series)} jours")

    # Courbe de charge : une puissance moyenne en W par intervalle.
    curve = fetch_load_curve(client, today - timedelta(days=7), today)
    for reading in curve.readings[:3]:
        print(reading.start, "->", reading.end, reading.power_w, "W", reading.energy_wh, "Wh")

DailySeries et LoadCurve sont deux types distincts, volontairement : le quotidien porte des Wh d'énergie, la courbe de charge des W de puissance. Passer l'un au parseur de l'autre lève une ParseError explicite plutôt que de produire des chiffres faux d'un facteur deux.

Ce que le format Enedis a de piégeux

Trois détails cassent silencieusement les calculs si on les rate. Ils sont traités dans models.py et couverts par des tests.

  • date est la fin de l'intervalle, pas son début. IntervalReading expose les deux (start et end).
  • value est une puissance moyenne en watts, pas une énergie. energy_wh fait la conversion avec la vraie durée de l'intervalle.
  • Le pas de mesure n'est pas toujours 30 minutes : Enedis livre du PT10M, PT30M ou PT60M selon le compteur. Il est lu dans chaque mesure.

À quoi s'ajoute le changement d'heure : en octobre, l'heure 02:00–03:00 est vécue deux fois et Enedis renvoie deux fois les mêmes horodatages. Ils sont désambiguïsés par l'ordre d'arrivée. Pour comparer ou soustraire deux mesures, utilise end_utc — entre deux datetime qui partagent le même fuseau, Python soustrait les valeurs naïves et ignore le décalage.

Limites de l'API

  • Courbe de charge : 7 jours maximum par appel, 24 mois d'historique.
  • Quotidien : 1095 jours par appel, 36 mois d'historique. Enedis le dit lui-même — « Il est possible de recevoir au maximun 1095j de données consécutives ».
  • Rien pour la journée en cours : les bornes sont ramenées automatiquement dans la fenêtre servable, et fetch/daily découpent et recollent les périodes plus longues.
  • Une plage longue est annoncée avant d'être lancée. Le nombre d'appels s'affiche en tête, et au-delà de 20 la commande demande confirmation — deux ans d'historique, c'est 105 appels pour un quota de l'ordre de 50 par jour. --yes passe outre.
  • Deux quotas, pas un. enedis check affiche le compteur de la passerelle (appels / quota), mais Enedis applique en plus son propre throttling, qui peut refuser un appel alors que ce compteur est à zéro. Dans ce cas la réponse indique l'heure de réouverture, et enedis fetch la relaie telle quelle. Ce refus n'est jamais réessayé : l'accès ne rouvre pas avant plusieurs heures.
  • Le cache de la passerelle est utilisé par défaut ; --no-cache force un vrai appel chez Enedis.
  • La collecte de la courbe de charge doit être activée chez Enedis, et se réactive chaque année à la date anniversaire. Sans ça, les réponses sont vides.

En cas de problème

Message Cause Quoi faire
aucune mesure entre … la collecte horaire doit etre activee La passerelle répond 404 no measure found. Le consentement peut être valide sans que la collecte horaire le soit : c'est une option distincte, à activer sur le compte Enedis (Je souhaite accéder à mes données horaires). L'activer, puis attendre : elle passe par En cours d'activation et le premier relevé arrive sous quelques jours. Rien n'est rétroactif. En attendant, enedis daily fonctionne.
quota d'appels Enedis atteint … Acces rouvert le … Throttling Enedis, indépendant du compteur affiché par enedis check. Attendre l'heure indiquée. Le cache de la passerelle évite d'y revenir.
token refuse par la passerelle (403 Le point de livraison ne correspond au token fourni) ENEDIS_TOKEN invalide, ou lié à un autre PDL. Refaire un consentement invalide le token précédent. Reprendre le token affiché sur myelectricaldata.fr et le remettre dans .env.
consentement Enedis absent ou expire Le consentement a une date de fin. Le renouveler sur myelectricaldata.fr.

enedis check répond aux trois derniers cas sans consommer de quota Enedis.

Intégration Home Assistant

Le dossier custom_components/enedis_med/ contient une intégration installable via HACS en dépôt personnalisé (catégorie Integration), puis ajoutée depuis Paramètres → Appareils et services.

La configuration se fait entièrement par l'interface : point de livraison et token. Le couple est validé auprès de la passerelle avant que l'entrée soit créée, donc une erreur de saisie se voit tout de suite.

La consommation apparaît dans le dashboard Energy sous Consommation du réseau, au nom Enedis <pdl> consommation. Ce n'est pas une entité mais une statistique externe : c'est la seule façon d'injecter de l'historique passé, ce qu'un capteur classique ne permet pas.

Ce qu'il faut savoir

  • Le token est stocké en clair dans .storage/core.config_entries. C'est le fonctionnement normal de Home Assistant pour toutes les intégrations.
  • Refaire un consentement sur myelectricaldata.fr invalide le token précédent. Home Assistant le détecte et ouvre un formulaire de ré-authentification qui ne redemande que le token.
  • Le rattrapage est étalé. Un appel couvre 7 jours et le quota est de 50 appels par jour : après une longue coupure, le dashboard se remplit sur plusieurs cycles plutôt que d'un bloc. Le cycle est de 12 heures.
  • Les mesures impossibles sont écartées. Tout intervalle dépassant la puissance souscrite lue dans ton contrat est ignoré et journalisé. Sur des données réelles, un point à 20 822 W pour 9 kVA souscrits ramenait l'erreur totale de 5,75 % à 1,31 % face aux index quotidiens.

Développement

make test    # aucun appel réseau : respx simule la passerelle
make lint    # style ruff

L'environnement exige Python 3.14, imposé par pytest-homeassistant-custom-component. make setup l'installe via uv.

Pour figer le format exact renvoyé par ton propre compteur :

python scripts/capture_fixture.py --day 2026-09-01

Un seul appel, sur une seule journée ; le PDL est remplacé et les puissances bruitées, donc la fixture produite est commitable.

Structure

Fichier Rôle
config.py Lecture et validation du .env, masquage du token
client.py Appels HTTP, retries, traduction des erreurs
models.py Parsing, fuseau horaire, énergie ; LoadCurve et DailySeries
windows.py Découpage en fenêtres (7 jours horaire, 1095 quotidien)
loadcurve.py Enchaînement des fenêtres et recollement
export.py Écriture JSON et CSV
demo.py Fausse passerelle pour le mode démo
errors.py Une exception par cause traitable
cli.py Commandes check, fetch, demo
demo.py Fausse passerelle pour le mode démo

Metadata

Release files for enedis-client 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for enedis-client 1.0.0
File Size Uploaded Provenance
enedis_client-1.0.0.tar.gz 44.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for enedis-client 1.0.0
File Interpreter ABI Platform
enedis_client-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 79.5 kB

Release files / enedis_client-1.0.0.tar.gz

Download URL enedis_client-1.0.0.tar.gz
Size 44.3 kB
Tags Source
SHA-256 checksum
How to use checksums
2a8b9916be751ff3b5edd15409f6047dbd6a53062751614f13d3f059440799c3
BLAKE2b-256 checksum
How to use checksums
b8a1c11070a08cc7aa205d89fc71f1ee9e5edc76bce75d05541c385ceb0b36ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / enedis_client-1.0.0-py3-none-any.whl

Download URL enedis_client-1.0.0-py3-none-any.whl
Size 35.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
75540bff1765ca18e47b5701a3c646529bc8e6b97e7b15b2b50cb32432b892c2
BLAKE2b-256 checksum
How to use checksums
93aec9d198a1fd300039cad9654383093ccedbcee767b638171ed4d1fce6d62f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for enedis-client 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page