ERETEK
BİLGİ SİSTEMLERİ

MQTT Sparkplug B: Topic Yapısı, Birth/Death Mesajları ve Durum Yönetimi

MQTT Sparkplug B sahada: spBv1.0 topic yapısı, NBIRTH/NDEATH, bdSeq ve seq, alias, Primary Host Application, düz MQTT farkları ve devreye alma listesi.

Bu makalede8 bölüm
Teknik özet
Teknoloji
MQTT 3.1.1, MQTT 5.0, Sparkplug B 3.0, Protocol Buffers, Mosquitto
Konu
Sparkplug B ile durum farkındalığı olan MQTT veri akışı
Seviye
Orta–ileri
Ön koşullar
  • MQTT publish/subscribe, QoS ve retained mesaj kavramları
  • Edge gateway ile PLC verisi toplama temeli

MQTT, üretim verisini sahadan merkeze taşımak için hafif ve esnek bir taşıyıcıdır. Ama topic yapısını, payload biçimini ve “bu cihaz şu an gerçekten çevrim içi mi” sorusunun cevabını tanımlamaz. Bu boşluğu her proje kendi kafasına göre doldurunca birkaç ay sonra elinizde birbirine benzemeyen on gateway olur. Sparkplug B, Eclipse Foundation’ın yayımladığı ve ISO/IEC 20237 olarak da standartlaşan spesifikasyondur; topic yapısını, birth/death mekanizmasını, sıra numarasını, alias’ı ve Primary Host Application davranışını sabitler. Aşağıda bunları devreye almada karşılaştığımız sorunlarla birlikte anlatıyoruz.

Düz MQTT sahada nerede tıkanır

Düz MQTT ile başlayan projelerde birkaç ay içinde hep aynı sorunlar çıkar:

  • Topic ve payload anlaşması yok: Her gateway kendi topic ağacını ve JSON alanlarını kullanır; tüketici tarafında her kaynak için ayrı ayrıştırıcı yazılır.
  • Bayat veri: Retained mesaj son değeri saklar, ama cihaz kapandığında bu değer güncelmiş gibi durmaya devam eder. SCADA iki saat önceki sıcaklığı canlı değer sanar.
  • Keşif yok: Yeni cihaz eklendiğinde hangi değişkenleri, hangi veri tipi ve birimle yayınlayacağını tüketici önceden bilmez.
  • Kayıp mesaj tespiti yok: QoS 0 ile gönderilen bir değişim kaybolursa tüketici bunu fark etmez.
  • Kesinti sonrası belirsizlik: Bağlantı geri geldiğinde aradaki verinin tamponlanıp gönderildiği tanımsızdır.

Sparkplug B bunları yeni bir protokol icat ederek değil, MQTT’nin mevcut özelliklerini (Last Will and Testament, QoS, retained mesaj) belirli kurallarla kullanarak ve binary bir payload şeması tanımlayarak çözer. Protokol kararı henüz verilmediyse önce OPC UA ile MQTT karşılaştırmasına bakın.

Topic namespace yapısı

Sparkplug B’de topic serbest değildir; şu kalıbı izler:

spBv1.0/<group_id>/<message_type>/<edge_node_id>[/<device_id>]

# Örnekler
spBv1.0/Fabrika1/NBIRTH/Hat3-Edge
spBv1.0/Fabrika1/DDATA/Hat3-Edge/Dolum01
spBv1.0/Fabrika1/DCMD/Hat3-Edge/Dolum01
spBv1.0/STATE/scada-primary

group_id edge node’ları mantıksal olarak gruplar (tesis veya bölüm). edge_node_id MQTT bağlantısını kuran gateway veya PLC’dir. device_id o edge node’un arkasındaki cihazdır. Mesaj tipleri:

Mesaj Yön Amaç
NBIRTH / DBIRTH Edge → Host Node veya cihazın çevrim içi olduğunu ve tüm metrik tanımlarını bildirir
NDATA / DDATA Edge → Host Değişen metrik değerleri
NDEATH / DDEATH Edge → Host Node veya cihazın çevrim dışı olduğunu bildirir
NCMD / DCMD Host → Edge Yazma komutu veya rebirth isteği
STATE Host Host uygulamasının çevrim içi/dışı durumu

Topic’in sabit ve düz olması bilinçli bir tercihtir: alan, hat, hücre gibi hiyerarşik bilgi topic’te değil, metrik isimlerinde ve birth mesajındaki tanımlarda taşınır. ISA-95 hiyerarşisine göre topic ağacı kurmak isteyen ekiplerle en çok burada tartışırız. İki yaklaşımın birlikte nasıl yaşayabileceğini Unified Namespace mimarisi yazısında anlattık.

Birth ve death mesajlarıyla durum yönetimi

Temel fikir şu: her veri bir oturumun içinde anlam kazanır. Akış:

  1. Edge node broker’a bağlanırken MQTT Will mesajı olarak NDEATH’i kaydeder (QoS 1, retain kapalı). Payload’da bir bdSeq (birth/death sıra numarası) metriği bulunur.
  2. Bağlantı kurulunca NBIRTH yayımlar. NBIRTH, node’un tüm metriklerinin adını, veri tipini, ilk değerini ve aynı bdSeq değerini içerir.
  3. Arkasındaki her cihaz için DBIRTH yayımlanır; cihaz metrikleri burada tanımlanır.
  4. Sonra yalnız değişen değerler NDATA/DDATA ile gider.
  5. Bir cihazla haberleşme koparsa edge node DDEATH yayımlar. Edge node’un kendisi beklenmedik şekilde düşerse broker kayıtlı Will mesajını, yani NDEATH’i yayımlar.

Host NDEATH aldığında o node’a ve altındaki tüm cihazlara ait metrikleri bayat olarak işaretler. bdSeq eşleşmesi, eski bir oturumdan gecikmeli gelen NDEATH’in yeni oturumu yanlışlıkla kapatmasını önler; host yalnız son NBIRTH ile aynı bdSeq’e sahip NDEATH’i dikkate alır. Gateway sık yeniden başlıyorsa bu eşleşme olmadan ekranda canlı makine “çevrim dışı” görünür.

Birth mesajları retained gönderilmez. Host sonradan bağlanırsa güncel durumu öğrenmek için rebirth ister: ilgili edge node’a Node Control/Rebirth metriği true olan bir NCMD gönderir, edge node da NBIRTH ve DBIRTH’leri yeniden yayımlar.

Sıra numarası, alias ve payload kodlaması

Edge node’un yayımladığı her mesaj 0–255 arasında artan, 255’ten sonra 0’a dönen bir seq değeri taşır; spesifikasyonun 3.0 sürümünde NBIRTH’te sıra 0’dan başlar. Host bu değeri izleyerek arada kaybolan mesajı yakalar. Boşluk saptanır ve beklenen mesaj makul sürede gelmezse host, durumu yeniden eşitlemek için rebirth ister. QoS 0 ile gönderilen veride bile kayıp sessiz kalmaz.

Payload, Google Protocol Buffers ile kodlanmış binary bir yapıdır. Her metrik ad, isteğe bağlı alias, zaman damgası (Unix epoch, milisaniye), veri tipi ve değer içerir; ayrıca is_historical, is_null gibi bayraklar ve birim gibi bilgiler için özellik (property) kümeleri taşıyabilir. Karmaşık yapılar için şablon (template) tanımı da desteklenir.

Alias bant genişliği içindir. Birth mesajında her metriğe bir tamsayı alias atanır; sonraki DATA mesajlarında uzun metrik adı yerine yalnız bu alias gider. “Hat3/Dolum01/Proses/UrunSicakligi” yerine birkaç baytlık bir tamsayı taşımak, binlerce metrik yayımlayan bir gateway’de mesaj boyutunu belirgin şekilde düşürür. Bedeli de açık: birth mesajını görmemiş tüketici DATA mesajlarını yorumlayamaz. Rebirth bu yüzden var.

Binary payload hata ayıklamayı zorlaştırır. mosquitto_sub -h broker -t 'spBv1.0/#' -v topic’leri gösterir ama payload ekranda anlamsız karakterler olarak akar. Sparkplug çözümleyicisi olan bir MQTT istemcisi ya da protobuf şemasıyla çalışan küçük bir betik bulundurun; arıza anında aramaya başlamayın.

Primary Host Application ve yeniden bağlanma

Verinin asıl tüketicisi, genellikle SCADA veya veri platformu, Primary Host Application olarak tanımlanabilir. Host bağlanırken spBv1.0/STATE/<host_id> topic’ine çevrim içi olduğunu bildiren retained bir mesaj yayımlar ve aynı topic’e “çevrim dışı” içerikli bir Will mesajı kaydeder. Sürüm 3.0’da bu payload, online ve timestamp alanları olan bir JSON nesnesidir.

Edge node bu STATE topic’ine abone olur ve şu kurala uyar: primary host çevrim içi değilse veri yayımlamaz; host düşerse bağlantısını keser ve varsa listesindeki bir sonraki broker’a geçer. Bu sürede üretilen veriyi tamponlar (store-and-forward) ve host geri geldiğinde is_historical bayrağıyla gönderir. Böylece asıl tüketici yokken broker’a giden verinin boşa akması önlenir. Tampon kapasitesi gateway donanımına bağlı bir sınırdır; hesabı edge gateway seçim kriterleri yazısında örnekle verdik.

Yedekli broker tasarımında edge node’lar bir broker listesiyle yapılandırılır; host da her broker’a ayrı ayrı STATE yayımlar. Edge node, primary host’un çevrim içi göründüğü broker’a bağlanır. Broker kümelemesi kullanıyorsanız Will ve retained mesajların küme genelinde tutarlı davrandığını ayrıca test edin. Kâğıt üzerinde değil, bir düğümü fişten çekerek.

Düz MQTT ile karşılaştırma

Konu Düz MQTT Sparkplug B
Topic yapısı Serbest, projeye özgü spBv1.0/group/type/node/device
Payload Serbest (çoğunlukla JSON) Protocol Buffers, tanımlı şema
Çevrim içi durumu Projeye özgü LWT kullanımı NBIRTH/NDEATH, DBIRTH/DDEATH, STATE
Metrik keşfi Yok Birth mesajında tüm tanımlar
Kayıp mesaj tespiti Yok seq ile
Kesinti sonrası veri Tanımsız Store-and-forward, is_historical
Okunabilirlik Yüksek (JSON) Düşük; çözümleyici gerekir
Hiyerarşik topic ile gezinme Mümkün Topic düz; hiyerarşi metrik adlarında

Sparkplug B, çok sayıda gateway’in tek bir SCADA veya veri platformuna yazdığı ve durum farkındalığının şart olduğu kurulumlarda güçlüdür. Tüketicilerin çoğu genel amaçlı IT uygulamalarıysa ve okunabilir JSON bekleniyorsa, sahada Sparkplug B kullanıp merkezde bir dönüştürücüyle hiyerarşik JSON topic’lere yayımlamak yaygın bir orta yoldur. Spesifikasyonun güncel metni Eclipse Sparkplug sitesinde, MQTT’nin kendi kaynakları mqtt.org adresindedir.

Devreye alma kontrol listesi

  • Broker MQTT 3.1.1 veya 5.0 destekliyor; Will ve retained mesaj davranışı test edildi.
  • Edge node’lar temiz oturumla bağlanıyor (3.1.1’de Clean Session, 5.0’da Clean Start ve sıfır oturum süresi).
  • group_id, edge_node_id ve device_id için isimlendirme kuralı yazılı; MQTT’de özel anlamı olan +, #, / karakterleri kimliklerde yok.
  • Keep-alive süresi, kopmanın kabul edilebilir sürede fark edilmesine göre seçildi.
  • Primary host STATE yayımlıyor; edge node’lar bu host’a göre davranacak şekilde yapılandırıldı.
  • Store-and-forward kapasitesi, beklenen en uzun merkez kesintisine göre hesaplandı.
  • Rebirth isteği ve seq boşluğu senaryosu test edildi.
  • Broker’da TLS ve kullanıcı/sertifika doğrulaması açık; her edge node yalnız kendi topic’lerine yazabiliyor.

Son madde için Mosquitto’da örnek bir ACL tanımı:

user edge-hat3
topic write spBv1.0/Fabrika1/+/Hat3-Edge/#
topic read  spBv1.0/Fabrika1/NCMD/Hat3-Edge
topic read  spBv1.0/Fabrika1/DCMD/Hat3-Edge/#
topic read  spBv1.0/STATE/#

Bu kural, ele geçirilen bir gateway’in başka node’lar adına sahte veri veya NDEATH yayımlamasını engeller. ACL yoksa tek bir gateway bütün hattı “çevrim dışı” gösterebilir. Sparkplug B tabanlı veri toplama mimarisi ve gateway yapılandırması için OPC UA, MQTT ve veri entegrasyonu ile edge gateway ve protokol dönüşümü sayfalarımıza bakabilirsiniz.

Sık sorulan sorular

Sparkplug B için özel bir broker gerekir mi?

Hayır. Sparkplug B, MQTT 3.1.1 veya 5.0 destekleyen standart bir broker üzerinde çalışır. Broker’ın Will ve retained mesajları doğru işlemesi yeterlidir; Sparkplug’a özgü ek işlevler sunan broker’lar da var ama zorunlu değil.

Sparkplug B mesajlarını neden okunabilir göremiyorum?

Payload, Google Protocol Buffers ile kodlanmış binary bir yapıdır. Okumak için Sparkplug çözümleyicisi olan bir MQTT istemcisi veya protobuf şemasıyla çalışan bir betik gerekir. DATA mesajlarında alias kullanılıyorsa birth mesajını da görmeniz şarttır.

Sparkplug B’de son değeri retained mesajla saklayabilir miyiz?

Spesifikasyon birth ve data mesajlarının retained gönderilmemesini öngörür; yalnız STATE mesajı retained’dır. Sonradan bağlanan uygulama güncel durumu rebirth isteğiyle alır. Bu kural, bayat değerin canlı veri gibi görünmesini önler.

Sparkplug B ile Unified Namespace birlikte kullanılabilir mi?

Evet. Yaygın yaklaşım şudur: sahadan merkeze taşımada Sparkplug B’nin durum yönetimini kullanırsınız, merkezde ise metrikleri ISA-95 hiyerarşisine göre düzenlenmiş okunabilir topic’lere dönüştürüp yayımlarsınız.

Teknik özet
Teknoloji
MQTT 3.1.1, MQTT 5.0, Sparkplug B 3.0, Protocol Buffers, Mosquitto
Konu
Sparkplug B ile durum farkındalığı olan MQTT veri akışı
Seviye
Orta–ileri
Ön koşullar
  • MQTT publish/subscribe, QoS ve retained mesaj kavramları
  • Edge gateway ile PLC verisi toplama temeli
Eretek uzman desteği

Bu sorunu kendi hattınızda mı yaşıyorsunuz?

Mevcut yapıyı yerinde inceleriz. Bulguya dayalı, bakım ekibinizin sürdürebileceği bir plan öneririz.