OCPP loglarına ilk kez baktığınızda köşeli parantezlerle başlayan, içinde sayılar ve rastgele görünen kimlikler barındıran satırlarla karşılaşırsınız. Bu satırlar OCPP-J'nin (JSON üzerinden OCPP) mesaj zarfıdır. Yapıyı bir kez anladığınızda, cihaz ile yönetim yazılımı arasında neler olduğunu loglardan rahatça okuyabilirsiniz.

Üç mesaj tipi

OCPP-J'de her mesaj bir JSON dizisidir ve dizinin ilk elemanı mesaj tipini belirten bir sayıdır (MessageTypeId):

  • 2 = CALL: Bir taraftan diğerine gönderilen istek.
  • 3 = CALLRESULT: İsteğe verilen başarılı cevap.
  • 4 = CALLERROR: İsteğin işlenemediğini bildiren hata cevabı.

Bu yapı OCPP 1.6J, 2.0.1 ve 2.1'de aynıdır. Değişen, mesajların içindeki alanlardır. (OCPP 2.1'de bunlara ek olarak bazı yeni mesaj tipleri tanımlanmıştır, ancak temel üçlü aynı kalır.)

CALL: istek mesajı

Bir CALL dört elemandan oluşur:

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

  1. 2 – mesaj tipi (CALL).
  2. "19223201" – MessageId. Gönderen tarafın ürettiği benzersiz kimlik.
  3. "BootNotification" – çağrılan işlemin (action) adı.
  4. {...} – işlemin yükü (payload). Alanları OCPP şeması belirler.

CALLRESULT: başarılı cevap

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

  1. 3 – mesaj tipi (CALLRESULT).
  2. Aynı MessageId – cevabın hangi isteğe ait olduğunu gösterir.
  3. Cevap yükü.

CALLRESULT'ta işlem adı yoktur; hangi isteğe cevap verildiği MessageId'den anlaşılır. Bu nedenle MessageId'nin her açık istek için benzersiz olması kritik önem taşır.

CALLERROR: hata cevabı

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

  1. 4 – mesaj tipi (CALLERROR).
  2. Aynı MessageId.
  3. Hata kodu – NotImplemented, FormationViolation, InternalError gibi standart değerler.
  4. Hata açıklaması – insan tarafından okunabilir kısa metin.
  5. Hata ayrıntıları – ek bilgi içeren nesne (boş olabilir).

Hata kodlarının anlamlarını OCPP CALLERROR hata türleri yazımızda tek tek açıkladık.

Önemli kurallar

  • Aynı anda tek istek: OCPP-J'de bir taraf, önceki isteğine cevap almadan aynı kanaldan yeni bir CALL göndermemelidir. Bu kural sırayı korur, ama yavaş cevap veren bir sistem kuyruğun büyümesine yol açabilir.
  • Zaman aşımı: Cevap belirli bir sürede gelmezse istek başarısız sayılır. Sürenin uzunluğu uygulamaya göre değişir.
  • Tutarlı MessageId: Kimlikler en fazla 36 karakter olabilir. UUID kullanımı yaygındır.
  • İş cevabı ile hata farklıdır: Örneğin bir kart reddedildiğinde CSMS CALLERROR göndermez; CALLRESULT içinde "status": "Invalid" döner. CALLERROR, mesajın teknik olarak işlenemediği durumlar içindir.

Loglarda pratik okuma

Bir sorunu incelerken önce CALL satırını bulun, ardından aynı MessageId'ye sahip cevabı arayın. Cevap hiç gelmiyorsa bağlantı veya zaman aşımı sorunu; CALLERROR geliyorsa mesaj formatı ya da desteklenmeyen işlem sorunu; CALLRESULT geliyor ama durum "Rejected" ise iş kuralı sorunu vardır. Üreticy'nin OCPP yazılımı, cihazla yapılan tüm bu haberleşmeyi aranabilir loglarda saklar ve MessageId ile eşleştirerek gösterir.

Kendi entegrasyonunuzu yazarken

Bir cihaz simülatörü ya da test aracı geliştiriyorsanız, gelen her mesajı önce yapısal olarak doğrulayın: dizinin uzunluğu, mesaj tipinin 2, 3 veya 4 olması ve MessageId'nin metin olması gerekir. Ardından yükü ilgili OCPP JSON şemasıyla kontrol edin. Şemaya uymayan bir yük için CALLERROR ile FormationViolation ya da TypeConstraintViolation döndürmek, karşı tarafa sorunun nerede olduğunu açıkça gösterir. Tanımadığınız bir işlem adı için NotImplemented veya NotSupported kullanın. Bu disiplin, farklı markaların cihazlarıyla çalışırken sorunları dakikalar içinde ayırt etmenizi sağlar.

Sonuç

OCPP-J'nin mesaj zarfı basittir: istek için 2, başarılı cevap için 3, hata için 4. Tüm iletişim bu üç tip ve MessageId eşleşmesi üzerine kuruludur. Bu yapıyı bilmek, entegrasyon sırasında ve sahadaki arızaları çözerken size ciddi zaman kazandırır.