La première fois que vous consultez des journaux OCPP, vous voyez des lignes qui commencent par des crochets et contiennent des nombres et des identifiants d'apparence aléatoire. Ces lignes constituent l'enveloppe des messages OCPP-J (OCPP sur JSON). Une fois la structure comprise, vous pouvez lire directement dans les journaux ce qui se passe entre la borne et le logiciel de gestion.

Trois types de messages

En OCPP-J, chaque message est un tableau JSON dont le premier élément est un nombre identifiant le type de message (MessageTypeId) :

  • 2 = CALL : une requête envoyée d'une partie à l'autre.
  • 3 = CALLRESULT : une réponse réussie à la requête.
  • 4 = CALLERROR : une réponse d'erreur indiquant que la requête n'a pas pu être traitée.

Cette structure est identique en OCPP 1.6J, 2.0.1 et 2.1. Ce qui change, ce sont les champs à l'intérieur des messages. (L'OCPP 2.1 définit aussi quelques nouveaux types de messages, mais le trio de base demeure.)

CALL : le message de requête

Un CALL comporte quatre éléments :

[2, "19223201", "BootNotification", {"chargePointVendor": "MarqueExemple", "chargePointModel": "AC22"}]

  1. 2 – type de message (CALL).
  2. "19223201" – le MessageId, un identifiant unique généré par l'émetteur.
  3. "BootNotification" – le nom de l'action appelée.
  4. {...} – la charge utile de l'action. Ses champs sont définis par le schéma OCPP.

CALLRESULT : la réponse réussie

[3, "19223201", {"status": "Accepted", "currentTime": "2026-10-02T09:00:00Z", "interval": 300}]

  1. 3 – type de message (CALLRESULT).
  2. Le même MessageId – indique à quelle requête la réponse se rapporte.
  3. La charge utile de la réponse.

Un CALLRESULT ne contient pas de nom d'action ; la requête concernée se déduit du MessageId. C'est pourquoi le MessageId doit être unique pour chaque requête en cours.

CALLERROR : la réponse d'erreur

[4, "19223201", "FormationViolation", "Payload is not valid", {}]

  1. 4 – type de message (CALLERROR).
  2. Le même MessageId.
  3. Code d'erreur – des valeurs standard comme NotImplemented, FormationViolation ou InternalError.
  4. Description de l'erreur – un court texte lisible.
  5. Détails de l'erreur – un objet contenant des informations supplémentaires (peut être vide).

Nous expliquons chaque code d'erreur dans notre article sur les types d'erreur CALLERROR d'OCPP.

Règles importantes

  • Une requête à la fois : en OCPP-J, une partie ne doit pas envoyer un nouveau CALL sur le même canal avant d'avoir reçu la réponse à sa requête précédente. Cela préserve l'ordre, mais un système lent à répondre peut faire grossir la file d'attente.
  • Délai d'expiration : si la réponse n'arrive pas dans un certain délai, la requête est considérée comme échouée. La durée dépend de l'implémentation.
  • MessageId cohérent : les identifiants peuvent comporter jusqu'à 36 caractères. Les UUID sont courants.
  • Une réponse métier n'est pas une erreur : lorsqu'un badge est refusé, par exemple, le CSMS n'envoie pas de CALLERROR ; il renvoie "status": "Invalid" dans un CALLRESULT. Le CALLERROR est réservé aux cas où le message n'a pas pu être traité techniquement.

Lire les journaux en pratique

Pour analyser un problème, repérez d'abord la ligne CALL, puis cherchez la réponse portant le même MessageId. Si la réponse n'arrive jamais, il s'agit d'un problème de connexion ou de délai ; si un CALLERROR arrive, d'un problème de format de message ou d'action non prise en charge ; si un CALLRESULT arrive avec le statut « Rejected », d'un problème de règle métier. Le logiciel OCPP d'Üreticy conserve toute cette communication avec la borne dans des journaux consultables et l'affiche en associant les messages par MessageId.

Si vous développez votre propre intégration

Si vous développez un simulateur de borne ou un outil de test, validez d'abord la structure de chaque message entrant : la longueur du tableau, un type de message égal à 2, 3 ou 4 et un MessageId de type texte. Vérifiez ensuite la charge utile avec le schéma JSON OCPP correspondant. Renvoyer un CALLERROR avec FormationViolation ou TypeConstraintViolation pour une charge utile non conforme indique clairement à l'autre partie où se situe le problème. Utilisez NotImplemented ou NotSupported pour un nom d'action que vous ne reconnaissez pas. Cette rigueur vous permet d'identifier les problèmes en quelques minutes lorsque vous travaillez avec des bornes de différentes marques.

Conclusion

L'enveloppe des messages OCPP-J est simple : 2 pour une requête, 3 pour une réponse réussie, 4 pour une erreur. Toute la communication repose sur ces trois types et sur la correspondance des MessageId. Connaître cette structure vous fait gagner beaucoup de temps lors de l'intégration et de la résolution des pannes sur le terrain.