Aller au contenu

Optimisation des coûts

L’algorithme de régulation basé sur les prix de Voltmasters : planifier la batterie autour des prix dynamiques de l’énergie pour minimiser le coût.

L’optimisation des coûts est l’algorithme de régulation basé sur les prix de Voltmasters. Il minimise le coût énergétique de l’installation en décidant, à chaque cycle de régulation, comment charger et décharger la batterie, sur la base des prix de l’énergie prévus et des prévisions de production PV et de consommation.

Comment ça fonctionne

À chaque cycle de régulation, l’algorithme :

  • Regarde devant lui sur l’horizon de prévision : les prix dynamiques (day-ahead), la production PV attendue et la consommation attendue.
  • Planifie la batterie pour que l’énergie soit stockée quand elle est bon marché (ou issue du surplus PV) et utilisée, ou injectée, quand elle est chère. Ce plan prévisionnel est le planning de la batterie.
  • N’agit que si c’est rentable : la charge et la décharge ne sont planifiées que si l’écart de prix est assez grand pour compenser les pertes aller-retour de la batterie (une différence de prix minimale réglable).
  • Respecte les limites : l’état de charge minimum et maximum de la batterie et les limites du raccordement (injection et consommation maximales).

Le plan détaillé, les types d’événements et un exemple chiffré sont décrits sur la page Planning de la batterie. Le reste de cette page explique comment l’algorithme arrive à ces décisions.

Deux boucles : planifier et agir

L’optimisation des coûts tourne comme deux boucles qui coopèrent autour d’un même objet : le planning de la batterie.

  • La boucle de planification examine tout l’horizon de prévision et calcule le plan de charge et de décharge le moins cher. C’est le « cerveau ». Le plan est recalculé régulièrement, à chaque nouveau créneau de 15 minutes et dès qu’une nouvelle prévision arrive, de sorte qu’il reflète toujours les derniers prix, la production et l’état réel de la batterie.
  • La boucle de régulation tourne à chaque cycle (environ une fois par seconde). Elle lit l’unique entrée du planning qui couvre maintenant, la traduit en consignes concrètes pour la batterie, le PV et les bornes EV, et adapte celles-ci aux mesures et aux limites en temps réel. Ce sont les « mains ».
flowchart LR
    subgraph inputs["Prévisions et état en direct"]
        P["Prix day-ahead"]
        PV["Prévision de production PV"]
        C["Prévision de consommation"]
        B["État de charge de la batterie"]
    end

    GEN["Générer le planning de la batterie<br/>boucle de planification"]
    SCHED[("Planning de la batterie")]
    READ["Lire l’entrée pour maintenant<br/>boucle de régulation, environ 1s"]
    SET["Traduire en consignes batterie / PV / EV"]
    HW["Batterie, PV, raccordement réseau"]

    P --> GEN
    PV --> GEN
    C --> GEN
    B --> GEN
    GEN --> SCHED
    SCHED --> READ
    READ --> SET
    SET --> HW
    HW -. "valeurs mesurées" .-> GEN
La boucle de planification construit le planning à partir des prévisions et de l’état réel de la batterie ; la boucle de régulation le lit à chaque cycle et pilote le matériel. Les résultats mesurés reviennent dans le plan suivant.

Séparer le travail de cette façon évite de devoir faire tourner chaque seconde l’optimisation prévisionnelle, qui est coûteuse, tout en laissant la boucle rapide réagir à la réalité entre deux plans.

Ce dont l’algorithme a besoin

Le plan est construit à partir d’un mélange de prévisions, de mesures en direct et de configuration du projet :

Entrée D’où elle vient Rôle dans l’algorithme
Prix day-ahead de consommation et d’injection (par créneau de 15 min) Fournisseur de prévisions (marché dynamique/day-ahead) Indique au plan quand l’énergie est bon marché à l’achat et quand il est lucratif de vendre
Prévision de production PV Fournisseur de prévisions (basé sur la météo) Indique au plan quand de l’énergie solaire gratuite ou bon marché est disponible à stocker
Prévision de consommation Fournisseur de prévisions Indique au plan quand le site aura besoin d’énergie : les déficits qui valent la peine d’être couverts
État de charge de la batterie Mesure en direct par batterie Le point de départ de la trajectoire de SoC projetée
Limites et rendement de la batterie Configuration du projet SoC min/max, vitesse de charge et de décharge, puissance nominale, rendement aller-retour
Limites du raccordement Configuration du projet Prélèvement maximal (marge de charge) et injection maximale (plafond d’injection)
Différence de prix minimale Configuration du projet L’écart qu’une paire charge/décharge doit dépasser pour valoir la perte et l’usure
Vente par injection de la batterie Configuration du projet Si revendre l’énergie stockée au réseau est autorisé du tout
Charge réseau pour injection Configuration du projet Si le planificateur peut aussi acheter de l’énergie réseau bon marché uniquement pour la revendre lors des pointes d’injection

L’idée centrale : l’arbitrage de prix dans les limites

Au fond, l’algorithme fait de l’arbitrage d’énergie : stocker l’énergie tant qu’elle est bon marché (surplus PV ou heures réseau à bas prix) et la restituer quand elle est chère, soit en couvrant la consommation propre du site, soit en l’injectant sur le réseau pour générer un revenu.

Deux choses gardent cela honnête :

  • Les pertes aller-retour. L’énergie perdue à l’entrée et à la sortie de la batterie fait qu’un kilowattheure stocké en restitue moins d’un. Le plan dimensionne chaque charge et chaque décharge à l’aide du rendement aller-retour de la batterie.
  • La différence de prix minimale. Une paire charge/décharge n’est planifiée que si l’écart de prix entre le créneau bon marché et le créneau cher franchit un seuil réglable. Cela couvre la perte aller-retour et l’usure de la batterie, et empêche de cycler la batterie pour un gain marginal.

Tout ce que l’optimiseur planifie doit aussi tenir dans les bornes d’état de charge et les limites du raccordement ; ces contraintes traversent chacune des étapes ci-dessous.

Construire le planning, étape par étape

La boucle de planification transforme l’horizon de prévision en planning de batterie par une chaîne fixe. Chaque étape ajoute ou affine des plans par-dessus la précédente :

flowchart TD
    A["Horizon de prévision<br/>prix · PV · consommation"] --> S1
    S1["1 · Sources d’énergie par créneau<br/>excédent PV + marge réseau"] --> S2
    S2["2 · Repérer les créneaux déficitaires<br/>la consommation dépasse le PV"] --> S3
    S3["3 · Planifier la charge pour les déficits<br/>la source abordable la moins chère d’abord"] --> S35
    S35["3.5 · Charge à prix négatif<br/>charger tant que le prix est sous zéro"] --> S375
    S375["3.75 · Décharge pour injection<br/>vendre à un prix d’injection élevé"] --> S38
    S38["3.8 · Charge réseau pour injection<br/>acheter bon marché pour vendre aux pointes"] --> S3875
    S3875["3.875 · Stockage du PV non pilotable<br/>stocker le surplus PV inévitable"] --> S46
    S46["4–6 · Construire les entrées et projeter le SoC<br/>charge, décharge, inactif"] --> OUT[("Planning de la batterie")]
La chaîne de génération du planning. Chaque étape affine le plan avant qu’il ne soit transformé en entrées horodatées.
  1. Sources d’énergie par créneau. Pour chaque créneau, l’algorithme calcule combien d’énergie pourrait y être stockée et à quel prix : l’excédent PV (le solaire au-dessus de la consommation locale, une énergie qui serait sinon exportée, valorisée au prix d’injection) et la marge réseau (ce qui peut encore être prélevé sous la limite du raccordement, valorisé au prix de consommation). Les deux sont plafonnés pour que la puissance de charge combinée ne dépasse jamais ce que les batteries peuvent absorber.
  2. Repérer les créneaux déficitaires. Les créneaux où la consommation prévue dépasse le PV prévu sont des déficits : le site devra soutirer de l’énergie. Ce sont les créneaux qui valent la peine d’être couverts par la batterie, et les plus chers sont les cibles prioritaires.
  3. Planifier la charge pour les déficits. C’est le cœur de l’optimiseur. En parcourant les déficits du plus cher au moins cher, il cherche dans les créneaux antérieurs les sources de charge les moins chères dont le prix est au moins la différence de prix minimale en dessous du prix du déficit, de sorte que seules les paires clairement rentables sont planifiées. Le PV est préféré au réseau (il est moins cher) ; les sources réseau sont prises de la moins chère à la plus chère. Chaque affectation est vérifiée contre le SoC projeté pour que la batterie ne soit jamais planifiée au-delà de sa capacité, et la décharge correspondante est inscrite dans le créneau déficitaire. Trois garde-fous décident si un déficit reçoit de l’énergie stockée :
    • Prix plancher. Un déficit dont le prix est inférieur à la différence de prix minimale n’est jamais servi par la batterie : même une recharge gratuite ne laisserait pas la marge exigée, il est donc simplement prélevé sur le réseau.
    • Pas d’aller-retour inutile. Une décharge que la batterie rechargerait juste après (charge bon marché ou apport solaire juste ensuite) n’est planifiée que si le prix du déficit dépasse aussi le prix de recharge plus la marge. Cela empêche la batterie d’alterner charge et décharge à l’intérieur d’une fenêtre de prix bon marché.
    • L’énergie stockée va à sa revendication la plus précieuse. Quand le stockage est disputé, un déficit qui peut être rechargé à bon compte depuis une fenêtre bon marché avant lui se charge d’abord depuis cette fenêtre, mais uniquement quand l’énergie stockée ainsi libérée a réellement un meilleur usage : un déficit ultérieur qui ne peut pas être rechargé à bon compte, ou une vente par injection rentable (que nulle fenêtre bon marché ne peut servir à la place). Sinon, le déficit garde la priorité au stockage.
  4. Charge à prix négatif. Quand le prix de consommation passe sous zéro, vous êtes payé pour consommer : l’algorithme planifie donc une charge supplémentaire pendant ces créneaux, tout en réservant de la place pour le PV qui ne peut pas être écrêté, afin de ne pas devoir payer pour l’injecter plus tard.
  5. Décharge pour injection. Quand la vente de l’énergie stockée est activée, l’algorithme repère les créneaux où le prix d’injection est attractif (positif et au-dessus de la différence de prix minimale) et y planifie des décharges, le prix le plus élevé en premier. Il ne descend jamais sous la réserve et jamais dans les quatre dernières heures de l’horizon (trop incertain pour y engager du stockage). Une injection peut aussi être ajoutée en bonus par-dessus une décharge de déficit existante. L’énergie stockée est affectée aux ventes qui en ont réellement besoin : les candidates qu’une fenêtre de charge bon marché peut servir à la place (typiquement des pointes d’un jour ultérieur) cèdent le pas aux achats dans la fenêtre, de sorte que la pointe du moment, que rien de moins cher ne peut atteindre, se vend en premier et à pleine puissance.
  6. Charge réseau pour injection. Quand l’option charge réseau pour injection est également activée, l’algorithme achète de l’énergie réseau bon marché uniquement pour la revendre : pour chaque créneau d’injection attractif dont la marge de décharge n’est pas remplie, il planifie des achats sur des créneaux antérieurs dont le prix franchit le seuil de rentabilité aller-retour, dimensionnés pour livrer exactement la vente supplémentaire (voir Vendre de l’énergie au réseau).
  7. Stockage du PV non pilotable. Le PV qui ne peut physiquement pas être écrêté, et qui serait sinon exporté à bas prix, est capté et réaffecté aux créneaux d’injection les plus rentables au lieu d’être perdu.
  8. Construire les entrées et projeter le SoC. Les plans deviennent des entrées horodatées (charge, décharge ou inactif), chacune avec une action et un objectif (voir Planning de la batterie). Les créneaux restants deviennent inactifs, ou compenser le surplus PV là où du solaire gratuit continue d’entrer dans la batterie. L’état de charge est projeté sur tout l’horizon pour que le plan complet reste dans les bornes min/max, et les entrées sont triées par heure.

Lors de l’enregistrement du plan, les entrées des créneaux déjà commencés sont conservées et fusionnées avec le nouveau plan, et les entrées de plus de 14 jours sont supprimées. Cela garde une trace de ce qui a réellement été planifié et exécuté pour chaque créneau.

Ce qui garde le plan réalisable

Plusieurs mécanismes traversent la chaîne pour garder le planning physiquement sain et stable :

  • Trajectoire de SoC projetée. L’algorithme simule le niveau d’énergie de la batterie créneau par créneau. La charge n’est jamais planifiée au-dessus du SoC maximum, et la décharge ne fait jamais descendre le SoC projeté sous le minimum effectif (le SoC minimum configuré plus toute réserve).
  • Segments de recharge. L’horizon est découpé en budgets indépendants aux grandes périodes de charge PV. Un déficit après un après-midi ensoleillé ne peut pas dépenser l’énergie qui appartient aux déficits avant lui. C’est ce qui garde les plans sur plusieurs jours stables au lieu de les faire bouger à chaque recalcul.
  • Les limites réseau partout. La puissance de charge par créneau est plafonnée par la marge de prélèvement encore libre sous la limite du raccordement ; l’injection et la décharge sont plafonnées par la limite d’injection. L’export PV et l’injection de la batterie partagent le même budget d’injection.
  • Réserves. L’énergie mise de côté par la réserve Peak Shaving est considérée comme intouchable pour une décharge ordinaire, le plan ne la dépense donc jamais. Elle reste disponible pour tenir le réseau à sa limite de prélèvement, et elle est rechargée en priorité quand elle s’épuise.

Du plan à la consigne : le cycle de régulation

Le planning exprime une intention ; la boucle de régulation la transforme en action. À chaque cycle, l’algorithme d’optimisation des coûts recherche l’entrée valable maintenant, lit son type d’action et la puissance planifiée, et convertit cela en une consigne, toujours bridée par l’état en direct et les limites réseau.

flowchart TD
    N["Ce cycle de régulation"] --> LOOK["Chercher l’entrée du planning pour maintenant"]
    LOOK --> AT{"Type d’action ?"}
    AT -->|charge_at_max_power| CMAX["Charger à puissance maximale<br/>plafonné par le prélèvement + la vitesse de charge"]
    AT -->|follow_scheduled_power| CFOL["Suivre la puissance planifiée<br/>plafonné par les limites"]
    AT -->|compensate_pv_surplus| CPV["Charger uniquement avec le surplus PV en direct"]
    AT -->|compensate_production_deficit| DDEF["Décharger pour couvrir le déficit en direct"]
    AT -->|idle| IDLE["Aucune action sur la batterie"]
    CMAX --> APPLY
    CFOL --> APPLY
    CPV --> APPLY
    DDEF --> APPLY
    IDLE --> APPLY
    APPLY["Appliquer les consignes<br/>respecter le SoC et les limites réseau"] --> REC["Enregistrer l’énergie réelle vs planifiée"]
À chaque cycle, le type d’action planifié est traduit en une consigne concrète pour la batterie, bridée par les contraintes en direct. La charge est évaluée en premier ; la décharge n’est envisagée que si rien n’est en charge.

Comment chaque action se comporte à l’exécution :

Type d’action Ce que fait la boucle de régulation
charge_at_max_power Charger à la puissance maximale que la marge de prélèvement et la vitesse de charge permettent
follow_scheduled_power Suivre exactement la puissance planifiée (charge depuis le réseau, ou décharge pour injecter), plafonnée par les limites
compensate_pv_surplus Charger uniquement avec le surplus PV en direct, sans charge depuis le réseau
compensate_production_deficit Décharger juste assez pour couvrir le déficit de production en direct
idle Laisser la batterie tranquille

Dans le même cycle, l’algorithme règle aussi les charges pilotables, l’allocation aux bornes de recharge et les consignes des onduleurs PV (en n’écrêtant que lorsque c’est nécessaire pour respecter la limite d’injection).

Comme le cycle travaille à partir de mesures en direct, il absorbe automatiquement l’erreur de prévision : les actions compensate_* se dimensionnent d’après ce qui se passe réellement à l’instant, tandis que follow_scheduled_power et charge_at_max_power suivent le plan dans les limites.

Les actions compensate_* équilibrent le raccordement vers 0 kW. Une puissance réseau cible déplace cette consigne vers un petit prélèvement permanent, utilisé sur les sites où un appareil externe écrête la production pour empêcher l’injection.

Boucler la boucle

Après chaque créneau de 15 minutes, le contrôleur enregistre ce qui a réellement été chargé (depuis le PV et depuis le réseau) et déchargé, et le compare au plan. Si moins d’énergie a été stockée que prévu, un ajustement de manquant retire ce manquant des créneaux cibles les plus chers d’abord. Le recalcul suivant repart alors de l’état réel de la batterie, de sorte que la stratégie se corrige en permanence à mesure que la réalité s’écarte de la prévision.

Exemple chiffré : prix élevés en soirée

Le graphique ci-dessous montre le scénario prix élevés en soirée. L’électricité est bon marché et le soleil présent dans la journée, puis les prix montent fortement pendant la pointe du soir.

Optimisation des coûts, scénario de prix élevés en soirée
L’optimiseur charge pendant la journée bon marché et ensoleillée et décharge dans la pointe chère du soir : acheter bas, utiliser haut.

À lire au regard de la chaîne : l’étape 2 marque la soirée comme une série de créneaux déficitaires chers ; l’étape 3 planifie la charge de la journée (surtout du surplus PV stocké) pour les couvrir, parce que l’écart de prix entre le jour et le soir franchit la différence de prix minimale ; et la boucle de régulation décharge ensuite pendant toute la pointe, le SoC projeté grimpant à son maximum dans la journée et redescendant durant la nuit. Le détail événement par événement de ce scénario se trouve sur la page Planning de la batterie.

Rapport avec un signal externe

L’optimisation des coûts est une stratégie locale. Quand un partenaire de signal externe pilote activement l’installation, ce partenaire a la priorité et l’optimisation des coûts ne pilote pas la batterie. Quand aucun signal externe n’est actif, ou que le partenaire est en veille, la batterie suit le planning d’optimisation des coûts.