Retour au blog
Tutoriel10 min de lecture

Recharge intelligente OCPP : SetChargingProfile en pratique

Les profils de recharge sont la partie d’OCPP 1.6 la plus mal comprise. Niveaux d’empilement, finalités, périodes de planning et planning composite — ce que chacun fait réellement, charges utiles à l’appui.

I
Infinite Service Team

Le profil Smart Charging est l’endroit où OCPP 1.6 cesse d’être un simple protocole requête/réponse. SetChargingProfile comporte des structures imbriquées, trois finalités différentes, un modèle d’empilement, et un jeu de règles de combinaison qu’il est facile de se tromper subtilement.

C’est aussi la partie de la spécification que la plupart des implémentations peuvent se permettre d’ignorer — jusqu’au jour où un gestionnaire de réseau leur demande d’effacer de la charge, et où cela devient urgent.

La forme d’un profil de recharge

Un profil de recharge répond à une seule question : *quel courant ou quelle puissance cette borne est-elle autorisée à délivrer, et quand ?* Tout, dans la structure, sert à cela.

[2, "msg-01", "SetChargingProfile", {
  "connectorId": 1,
  "csChargingProfiles": {
    "chargingProfileId": 100,
    "stackLevel": 0,
    "chargingProfilePurpose": "TxDefaultProfile",
    "chargingProfileKind": "Absolute",
    "chargingSchedule": {
      "chargingRateUnit": "A",
      "chargingSchedulePeriod": [
        { "startPeriod": 0,     "limit": 32.0 },
        { "startPeriod": 21600, "limit": 16.0 },
        { "startPeriod": 64800, "limit": 32.0 }
      ]
    }
  }
}]

Ce profil dit : 32 A dès le début, descendre à 16 A au bout de six heures, remonter à 32 A au bout de dix-huit heures. startPeriod est exprimé en secondes relatives au début du planning — ce n’est ni une heure d’horloge, ni une durée.

Les trois finalités ne sont pas interchangeables

chargingProfilePurpose décide de ce à quoi le profil s’applique, et c’est là que naît l’essentiel de la confusion.

ChargePointMaxProfile est le plafond physique de la borne entière. Il se pose sur connectorId: 0, parce qu’il décrit la station et non une prise. Rien ne peut le dépasser : c’est la limite du matériel et de l’alimentation derrière lui.

TxDefaultProfile est le profil par défaut des transactions. Posez-le sur un connecteur précis, ou sur connectorId: 0 pour donner le même défaut à tous les connecteurs. Il s’applique aux transactions qui n’ont pas de profil propre, y compris les futures.

TxProfile s’applique à une transaction précise, en cours. Il exige un transactionId, et il est jeté quand cette transaction se termine. C’est ce que vous utilisez pour écrêter une session en cours.

Conséquence pratique : envoyer un TxProfile pour une transaction déjà arrêtée n’est pas une erreur que vous remarquerez — la borne l’accepte et le met à la poubelle.

Empiler n’est pas additionner

stackLevel est un entier, et le plus élevé gagne. C’est la règle que l’on interprète le plus souvent de travers.

Des profils à des niveaux d’empilement différents ne s’additionnent pas, ne se moyennent pas et ne se mélangent pas. Au sein d’une même finalité, le profil valide au niveau d’empilement le plus élevé remplace entièrement ceux du dessous. Un profil au stackLevel 2 n’ajoute pas une contrainte par-dessus le stackLevel 1 ; il le supplante.

La superposition entre finalités est autre chose, et celle-là se comporte bien comme un plafond : la limite effective est la plus basse parmi le ChargePointMaxProfile applicable, le TxDefaultProfile gagnant et le TxProfile gagnant. Les finalités se plafonnent donc mutuellement, tandis que les niveaux d’empilement, au sein d’une finalité, se remplacent.

Un schéma de déploiement courant :

  • stackLevel 0 — TxDefaultProfile, la limite d’exploitation normale
  • stackLevel 1 — TxDefaultProfile, un planning nocturne dicté par le tarif
  • stackLevel 2 — TxProfile, un effacement demandé par l’exploitant pour une session

Retirez le profil de niveau 2 et le planning de niveau 1 reprend. Rien n’a besoin de redire ce qu’il remplaçait.

Absolute, Recurring, Relative

chargingProfileKind décide de ce que signifie startPeriod: 0.

Absolute ancre le planning sur startSchedule, un horodatage explicite. À utiliser pour une fenêtre unique : écrêter entre 18 h et 20 h ce soir.

Recurring se répète chaque jour ou chaque semaine, selon recurrencyKind. startSchedule fixe la phase — l’heure de la journée où le cycle commence. À utiliser pour les tarifs.

Relative ancre startPeriod: 0 sur l’instant où la transaction démarre, et ignore complètement startSchedule. À utiliser pour un comportement qui dépend de l’ancienneté de la session plutôt que de l’heure : plein courant la première heure, réduit ensuite.

Un bug fréquent consiste à envoyer Absolute sans startSchedule. La spécification l’exige pour Absolute et Recurring, et les bornes diffèrent : certaines refusent le profil, d’autres le traitent silencieusement comme Relative.

Ampères ou watts, et pourquoi cela compte

chargingRateUnit vaut A ou W, et une borne n’est pas tenue de gérer les deux. Un GetConfiguration sur ChargingScheduleAllowedChargingRateUnit vous dit lesquels sont disponibles.

En recharge alternative, la conversion dépend du nombre de phases, que le profil ne transporte pas. 32 A en monophasé 230 V font environ 7,4 kW ; les mêmes 32 A en triphasé font environ 22 kW. Si votre serveur raisonne en watts et la borne en ampères, l’hypothèse sur les phases vit quelque part dans votre code, et elle doit être explicite.

numberPhases, dans une période de planning, vaut 3 par défaut quand il est omis. Sur une installation monophasée ce défaut est faux, et une limite calculée à partir de lui sera trois fois trop élevée.

Vérifier ce que la borne a réellement fait

SetChargingProfile renvoie Accepted, Rejected ou NotSupported. Accepted veut dire que la borne a stocké le profil — pas que le profil est en vigueur, ni qu’il produit la limite que vous visiez.

Pour voir le résultat de toutes ces combinaisons, utilisez GetCompositeSchedule :

[2, "msg-02", "GetCompositeSchedule", {
  "connectorId": 1,
  "duration": 86400,
  "chargingRateUnit": "A"
}]

La borne renvoie le planning aplati qu’elle va réellement suivre, tous profils déjà résolus. C’est la seule façon fiable de contrôler votre logique d’empilement, et la première chose à regarder quand un effacement ne semble pas prendre effet.

Si le planning composite ne correspond pas à ce que vous attendiez, les causes habituelles sont un niveau d’empilement plus bas que quelque chose déjà installé, un TxProfile dont le transactionId ne correspond pas à la transaction en cours, ou un ChargePointMaxProfile qui vous plafonne par le haut.

Effacer des profils

ClearChargingProfile supprime par filtre, pas seulement par identifiant. Tous les champs sont optionnels, et les omettre tous efface tout :

[2, "msg-03", "ClearChargingProfile", {
  "connectorId": 1,
  "chargingProfilePurpose": "TxProfile"
}]

Cela efface les TxProfile du connecteur 1 et laisse les profils par défaut intacts. Envoyer {} efface tous les profils de la borne, ce qui est parfois ce que vous voulez et plus souvent une panne.

Tester tout cela

La recharge intelligente est difficile à tester sur du matériel réel parce que les cas intéressants dépendent du temps — un profil récurrent qui déraille à un changement de jour, un effacement qui arrive en pleine session, un planning composite qui ne se trompe qu’une fois trois profils empilés.

C’est exactement le genre de logique qui mérite d’être éprouvée en simulation. SimPilot peut maintenir une session ouverte pendant que vous y installez, empilez et effacez des profils, et TestPilot vérifie la façon dont une borne gère elle-même le profil Smart Charging au regard de la spécification. Le jeu de messages complet est documenté dans notre référence OCPP 1.6.

Articles liés