Dans le but de tendre vers une indépendance énergetique (partielle ou totale) de mon logement, j'ai réalisé ce simulateur d'energie permettant de quantifier au plus juste mon besoin en production solaire et stockage d'énergie.
Mon logement étant déjà équipé de panneaux photovoltaiques en autoconsommation avec revente de surplus, je me suis servi des données agrégées, au fil des mois, par mon système domotique (Home Assistant) pour créer ce simulateur.
Cet outil a pour but :
- de récolter les données de mon système domotique sur une période de temps limitée (période d'étude).
- Sur cette période d'étude, de définir le meilleur compromis en terme d'ajout de production solaire et stockage d'énergie en fonction de mes objectifs en autoconsommation et taux de couverture (autosuffisance).
- Sur cette même période d'étude, de simuler ce scénario (meilleur compromis) ou un scénario forcé sur les données récoltées de mon système domotique.
- D'afficher les résultats sous forme de graphes avec un Avant (valeurs actuelles)/Après (valeurs simulées).
Warning
Cet outil doit être utilisé à titre informatif et ne peux pas répondre avec une grande précision aux besoins exprimés.
Note
Part de la production PV consommée sur place.
C'est le pourcentage de la production PV directement utilisée pour couvrir la consommation locale, sans passer par l'export réseau.
- PV totale = somme de toute la production PV sur la période.
-
PV utilisée sur place dépend du mode :
-
En mode report (réel) :
$PV\ utilisée\ =\ PV\ totale\ -\ Export$ -
En mode simulation :
$PV utilisée\ =\ \sum(pv\_direct + batt\_to\_load)$
-
En mode report (réel) :
- Toujours comprise entre 0% et 100%
Note
Part de la consommation couverte par le PV.
Plus cette valeur tend vers 100%, moins nous sommes dépendants du réseau électrique.
C'est le pourcentage de la consommation locale qui provient de la production photovoltaique (directement ou via batterie).
- Consommation totale = somme de la demande énergétique sur la période.
-
PV utilisée sur place = identique à celle utilisée pour le calcul de l'AC:
-
En mode report (réel) :
$PV\ utilisée\ =\ PV\ totale\ -\ Export$ -
En mode simulation :
$PV utilisée\ =\ \sum(pv\_direct + batt\_to\_load)$
-
En mode report (réel) :
- Toujours comprise entre 0% et 100%
électricité prise au réseau
surplus injecté au réseau
- Report (mode
report) : récupère l’historique PV/Conso, calcule import/export horaire et journalier. - Simulation (mode
simu) : parcourt un espace de scénarios PV (facteur) × batterie selon vos objectifs (AC/TC), et produit le meilleur compromis.- Il n'y a pas de reset journalier des paramètres de batterie simulée sur toute la période d'étude.
- Plot (mode
plot) : Affichage en mode console.- graphe horaire bipolaire (consommation en haut / production en bas),
- comparatif Avant/Après pour un jour donné,
- affichage multi-jours (24 h / 48 h) avec empilement vertical.
- Python 3.10+
- Home Assistant (optionnel, si vous utilisez la source
ha_ws) - Un long-lived access token Home Assistant (si vous utilisez la source
ha_ws)
- Paquets principaux Python:
websocket-client,rich
pip install -r requirements.txtPlacez les fichiers dans un dossier de travail, par exemple :
energy_tool.py
cli_output.py
ha_ws_api.py
pv_config.jsonPar défaut, l'outil a été initialement pensé pour récupérer les données via Home Assistant car celui-ci agrége mes données de production et de consommation électrique depuis que mon installation photovoltaique a été physiquement installée.
Il serait possible d'utiliser d'autres sources de données pour utiliser l'outil comme par exemple :
- un fichier CSV (eg: EDF)
- une API propriétaire du constructeur des onduleurs/micro-onduleurs (eg: enlighten)
- etc ...
Il existe deux possibilités de communiquer avec Home Assistant depuis un outil externe:
- une API WebSocket
- une API REST
Le choix s'est porté sur l'API WebSocket d'Home Assistant et donc l'implémentation d'un client WebSocket sur ce simulateur. Pour communiquer avec Home Assistant, nous avons besoin d'une URI formalisée de cette manière :
- en local :
ws://<ADRESSE_IP_LOCALE>:8123/api/websocket- a distance :
wss://<ADRESSE_SERVEUR_DOMOTIQUE>/api/websocketCette adresse doit être renseignée dans le fichier de configuration JSON:
"BASE_URL": "ws://homeassistant:8123/api/websocket"L'autentification sur le système domotique se fait grâce à un jeton d'accès longue durée.
Il se crée facilement sur la page de sécurité du compte associé d'Home Assistant et doit être renseigné dans le fichier de configuration JSON:
"TOKEN": "XXXXXXXXXXXX"Finalement, deux entités sont nécessaires pour récupérer les données de production et de consommation et doivent être renseignées dans le fichier de configuration JSON, respectivement les étiquettes PV_ENTITY et LOAD_ENTITY.
Par exemple pour un système Enphase, ces 2 entités ont ce formalisme :
sensor.envoy_XXXXXXXXXXXX_production_d_energie_totale et sensor.envoy_XXXXXXXXXXXX_consommation_d_energie_totale.
Il est possible de choisir la source csv pour le mode report.
Le fichier de configuration JSON doit contenir l'attribut :
"IN_CSV": "<CHEMIN DU FICHIER JSON>"Le fichier CSV doit contenir les attributs suivant et doit contenir les données par pas de 1h :
- date : date et heure au format ISO "YYYY-MM-DDTHH:MM"
- pv_diff : la production totale en kWh pour la période
date - load_diff : la consommation totale en kWh pour la période
date
Exemple :
date,pv_diff,load_diff
2025-06-01 00:00,0.0,1.687
2025-06-01 01:00,0.0,1.128
2025-06-01 02:00,0.0,0.673
2025-06-01 03:00,0.0,0.609
2025-06-01 04:00,0.0,0.524
2025-06-01 05:00,0.0,0.458
2025-06-01 06:00,0.0,0.495
2025-06-01 07:00,0.035,0.446
2025-06-01 08:00,0.61,0.852
2025-06-01 09:00,0.789,1.59
2025-06-01 10:00,1.397,1.755
2025-06-01 11:00,1.009,1.493
2025-06-01 12:00,1.323,2.447
2025-06-01 13:00,1.356,2.422
2025-06-01 14:00,1.296,1.837
2025-06-01 15:00,0.971,1.068
2025-06-01 16:00,1.365,1.418
2025-06-01 17:00,1.119,1.311
2025-06-01 18:00,0.473,0.615
2025-06-01 19:00,0.163,0.512
2025-06-01 20:00,0.019,1.266
2025-06-01 21:00,0.0,1.183
2025-06-01 22:00,0.0,0.708
2025-06-01 23:00,0.0,0.648
Work In Progress !!
Tout passe par un unique JSON (ex. pv_config.json)
Exemple minimal à adapter à vos valeurs :
{
"BASE_URL": "wss://votre-ha/api/websocket",
"TOKEN": "XXXXXXXX",
"IN_CSV": "mon_fichier_source.csv"
"PV_ENTITY": "sensor.envoy_xxx_production_d_energie_totale",
"LOAD_ENTITY": "sensor.envoy_xxx_consommation_d_energie_totale",
"START": "2025-03-01T00:00:00",
"END": "2025-04-01T00:00:00",
"OUT_CSV_DETAIL": "ha_energy_import_export_hourly.csv",
"OUT_CSV_DAILY": "ha_energy_import_export_daily.csv",
"OUT_CSV_SIMU": "ha_energy_simulation_combos.csv",
"PV_ACTUAL_KW": 4.0,
"TARGET_AC_MIN": 85.0,
"TARGET_AC_MAX": 95.0,
"TARGET_TC_MIN": 75.0,
"BATTERY_EFF": 0.90,
"BATTERY_SIZES": [0,5,10,12,14,16,18,20,22,24,26,28,30],
"PV_FACTORS": [1.0,1.2,1.5,1.8,2.0,2.2,2.4,2.6,3.0],
"ALLOW_DISCHARGE_IN_HC": true,
"GRID_CHARGE_IN_HC": true,
"GRID_HOURS": [22,23,0,1,2,3,4,5],
"GRID_TARGET_SOC": 0.80,
"GRID_CHARGE_LIMIT": 3.0,
"ALLOW_EXPORT": true,
"PV_CHARGE_LIMIT": 3.0,
"INITIAL_SOC": 0.50,
"BATT_MIN_SOC": 0.10,
"MAX_CHARGE_KW_PER_HOUR": 0.0,
"MAX_DISCHARGE_KW_PER_HOUR": 0.0
}- BASE_URL/TOKEN: connexion Home Assistant (mode
reportavec la sourceha_ws). - IN_CSV: utilisation d'un fichier CSV (mode
reportavec la sourcecsv) - PV_ENTITY/LOAD_ENTITY: L'entité de production totale et de consommation totale d'Home Assistant (mode
reportavec la sourceha_ws). - START/END: fenêtre d'étude (ISO local sans
Zpour éviter les décalages). - TARGET_AC_MIN/TARGET_AC_MAX/TARGET_TC_MIN: objectifs de sélection des scénarios pour l'autoconsommation et le taux de couverture (mode
simu). - BATTERY_EFF/BATTERY_SIZES/PV_FACTORS: grille de recherche de scénarios (mode
simu). - ALLOW_DISCHARGE_IN_HC: autorise la décharge de la batterie en heures creuses (mode
simu). - GRID_CHARGE_IN_HC: autorise la charge de la batterie en heures creuses (mode
simu). - GRID_HOURS: heures creuses (mode
simu). - GRID_TARGET_SOC: Jusqu'à quel niveau de charge, on souhaite remonter la batterie (mode
simu). - GRID_CHARGE_LIMIT: La puissance maximale de recharge par heure, en kWh (mode
simu). - ALLOW_EXPORT: Autorisé ou non l'export sur le Grid (mode
simu). - PV_CHARGE_LIMIT: Limité la capacité de charges des batteries en provenance du PV (mode
simu). - INITIAL_SOC: état de charge initial de la batterie pour la période d'étude.
- BATT_MIN_SOC: réserve non déchargeable de la batterie.
- DISCHARGE_KW_PER_HOUR: limites (kWh par pas horaire).
0= illimité
Note
Vous pouvez forcer le scénario de simulation (PV et batterie) via le JSON en posant par ex. SIM_OVERRIDE: {"pv_factor": 2.4, "batt_kwh": 24}.
python3 energy_tool.py --mode report --config pv_config.json --source ha_wsou depuis un CSV déjà exporté :
python3 energy_tool.py --mode report --config pv_config.json --source csvpython3 energy_tool.py --mode simu --config pv_config.jsonpython3 energy_tool.py --mode simu --config pv_config.json --override trueExemple d'affichage :
"SIM_SCENARIO": {
"PV_FACTOR": 1.5,
"BATTERY_KWH": 32
}Les graphes reprennent l'aspect du dashboard Energie de Home Assistant.
- En abscisse : les heures de chaque jour de l'étude
- En ordonnée : La mesure d'énérgie en kWh
- Sur la partie haute :
- En orange : La production consommée directement par le logement (graphes actuel et simulé)
- En violet : La décharge de la batterie consommée par le logement (graphe simulé)
- En bleu : L'importation du Grid consommé par le logement (graphes actuel et simulé)
- Sur la partie basse :
- En bleu clair : La charge de la batterie par le Grid (graphe simulé)
- En jaune : La charge de la batterie par les panneaux photovoltaiques (graphe simulé)
- En Blanc creme : L'export du surplus de production vers le Grid (graphes actuel et simulé)
- Sur la partie haute :
python3 energy_tool.py --mode plot --config pv_config.json --day 2025-06-01python3 energy_tool.py --mode plot --config pv_config.json --day 2025-06-01 --days 2Note
Les graphes utilisent Rich : couleurs, panneaux de contexte (puissance PV, scénario, SoC initial, AC/TC, etc.).
Il est possible qu'aucun scénario ne satisfait pas les objectifs d'AC et TC définis dans le fichier de configuration JSON pour une simulation non forcée sur la période définie par report.
Cela peut-être dû à plusieurs facteurs, exemple:
- objectif d'autoconsommation (AC) trop contraint.
- objectif de taux de couverture (TC) trop élevé.
- Si, par exemple, on n'autorise pas la décharge de la batterie en HC, cela aura pour conséquence de faire chuter le TC.
- la fourchette de tailles de batteries n'est pas suffisament grande.
- la fourchette de facteurs multiplicateurs de PV n'est pas suffisament grande.
Par défaut, la batterie déchargera automatiquement en Heures Pleines pour atteindre les objectifs d'autoconsommation et de taux de couverture, mais il est possible d'améliorer les résultats en déchargeant aussi la batterie en Heures Creuses à l'aide du paramètre ALLOW_DISCHARGE_IN_HC dans la configuration.
Exemple : Pour le même scénario :
- Vue de gauche : Sans décharge de la batterie en HC.
- Vue de droite : Avec décharge de la batterie en HC.
Note
- On remarque que le TC évolue en autorisant la décharge de la batterie en HC.
- On remarque également que le facteur multiplicateur choisi n'est pas suffisant pour couvrir toute la consommation du logement sur ce jour.
- On remarque que la production photovoltaique simulée n'a pas été suffisante pour recharger la batterie et ainsi couvrir tous les besoins de la journée.
Avec les mêmes paramètres de simulation, sur le graphe 48h, toutes les HP sont couvertes par la capacité de la batterie simulée sans décharge en HC.
Ce qui n'est pas le cas avec une décharge simulée également en HC.
Avec le paramètre GRID_CHARGE_IN_HC dans la configuration, on peut simuler la recharge de la batterie en Heure Creuse. Il est également possible de définir jusqu'à quel pourcentage maximum de batterie on souhaite recharger (GRID_TARGET_SOC) ainsi que la puissance limite par heure (GRID_CHARGE_LIMIT).
Note
- On remarque lors des heures de charges batterie, que l'on tire sur le grid, la charge de la maison ainsi que la recharge de la batterie mais l'import reste quand même inférieur à la situation actuelle (sans batterie et moins de PV)
Avec le paramètre ALLOW_EXPORT, il est possible de restreindre la simulation à ne pas renvoyer d'energie sur le Grid (surplus de production photovoltaique).
Avec le paramètre PV_CHARGE_LIMIT, il est possible de limiter la quantité de photovoltaique injectée limitant la recharge de la batterie.
Dans cet exemple, pas d'export sur le Grid et une limite d'injection à 3 kWh toutes les heures :

Pour chaque heure h :
- PV → charges directes :
pv_direct = min(pv[h], load[h]) - Batterie → charges : borné par SoC – réserve et
MAX_DISCHARGE_KW_PER_HOUR - Import = reste de charge si non couvert
- PV → batterie (stockage) : borné par capacité restante et
MAX_CHARGE_KW_PER_HOUR - Export = surplus PV non stocké/consommé
- Recharge réseau (HC) si activée, vers
GRID_TARGET_SOCsans dépasserGRID_CHARGE_LIMIT(kWh)
Paramètres clés :
- Rendement unique
BATTERY_EFFpour charge/décharge. BATT_MIN_SOC(réserve) : fraction non déchargeable.INITIAL_SOC: SoC initial au début de la fenêtre (pas de reset journalier).- Limites charge/décharge (kWh/h) optionnelles.
ALLOW_DISCHARGE_IN_HC |
GRID_CHARGE_IN_HC |
Comportement |
|---|---|---|
| FALSE | FALSE | Ni charge, ni décharge en HC -> tout vient du réseau |
| FALSE | TRUE | Recharge autorisée, mais pas de décharge -> on remplit la batterie avec le réseau, toute la conso vient du réseau |
| TRUE | FALSE | Décharge autorisée, mais pas de recharge -> la batterie allimente le load si disponible |
| TRUE | TRUE | Recharge et décharge autorisée, priorité à la recharge |
Dans une stratégie d'optimisation de l'autoconsommation pour les tarifs HC/HP:
- On met
GRID_CHARGE_IN_HC = truepour profiter des HC pour charger avec le réseau et alimenter l'habitation avec le réseau. - On met
ALLOW_DISCHARGE_IN_HC = falsepour éviter de vider la batterie en HC et maximiser l'autoconsommation.










