Endüstriyel IoT

Sparkplug Birth ve Death Sertifikaları: NBIRTH, NDEATH, DBIRTH ve DDEATH

Birth ve death sertifikaları, Sparkplug'ın neyin çevrimiçi olduğunu ve verinin güncel olup olmadığını bilmesini sağlar. Bu rehber NBIRTH, NDEATH, DBIRTH ve DDEATH mesajlarını, sıra numaralarını ve bdSeq'i çalışan bir Python simülatörüyle açıklıyor.

Bir edge node için NBIRTH, DBIRTH, veri mesajları ve NDEATH'i gösteren Sparkplug birth ve death sertifikaları zaman çizelgesi
Bunu kendi MQTT broker’ınızda çalıştırınFree planla özel, yönetilen bir MQTT broker alın ve hazır kod örnekleriyle başlayın.
Ücretsiz deneyin Kod örnekleri Kart gerekmez

Sparkplug birth ve death sertifikaları, her tüketiciye bir edge node'un veya cihazın ne zaman çevrimiçi olduğunu, hangi metriklere sahip olduğunu ve ne zaman ortadan kaybolduğunu bildiren mesajlardır. Bu rehberde NBIRTH, NDEATH, DBIRTH ve DDEATH'in seq ve bdSeq sayaçlarıyla birlikte nasıl çalıştığını öğrenecek ve tüm yaşam döngüsünü canlı bir broker'a yayınlayan küçük bir Python edge node simülatörü çalıştıracaksınız.

Sparkplug Neden Birth ve Death Mesajlarına İhtiyaç Duyar?

Düz MQTT bir subscriber'a yalnızca bir değerin geldiğini söyler. Göndericinin hâlâ hayatta olup olmadığını, son değerin hâlâ geçerli olup olmadığını veya başka hangi değerlerin bulunduğunu söylemez. Bir tesiste bu gerçek bir sorundur: gateway on dakika önce çevrimdışı olmuşsa, bir pompanın 1.450 rpm'de çalıştığını gösteren operatör ekranı tehlikelidir.

Sparkplug bunu iki MQTT özelliği üzerine kurulu bir durum modeliyle çözer: last will and testament ve tek bir bağlantı üzerinde sıralı teslimat. Her edge node, tüm metriklerini ve güncel değerlerini listeleyen bir birth sertifikasıyla kendini duyurur. Bağlantısı ister düzgün ister beklenmedik şekilde kesilsin, bir death sertifikası herkese bu değerlerin artık bayat olduğunu bildirir. Host uygulamaları da eski sayıları canlıymış gibi göstermek yerine tag'leri kötü kaliteli olarak işaretleyebilir.

Dört Sertifika

Mesaj Yayınlayan Ne zaman İçerik
NBIRTH Edge node Bağlandıktan hemen sonra Tüm node metrikleri, bdSeq, seq 0, Node Control metrikleri
NDEATH Last will aracılığıyla broker veya node Node oturumu sona erdiğinde NBIRTH ile eşleşen bdSeq
DBIRTH Edge node NBIRTH'ten sonra, her cihaz için Güncel değerleriyle tüm cihaz metrikleri
DDEATH Edge node Node'un arkasındaki bir cihaz kaybedildiğinde Yalnızca sıra numarası

Topic'ler Sparkplug topic namespace yapısını izler: node mesajları için spBv1.0/{group}/NBIRTH/{node}, cihazlar için spBv1.0/{group}/DBIRTH/{node}/{device}.

NBIRTH

Node birth, MQTT bağlantısı başarılı olduktan sonraki ilk mesajdır. Her node seviyesi metriği adı, veri tipi ve güncel değeriyle birlikte içermeli; ayrıca bir host'un yeni bir birth isteyebilmesi için bir bdSeq metriği ve bir Node Control/Rebirth boolean metriği barındırmalıdır. Metrik alias'ları kullanılıyorsa, adlar ile alias'lar NBIRTH'te eşleştirilir.

NDEATH

Node death, node bağlanırken MQTT will mesajı olarak kaydedilir; böylece TCP bağlantısı koparsa veya keepalive süresi dolarsa broker bunu otomatik olarak yayınlar. Düzgün şekilde kapanan bir node, bağlantıyı kesmeden önce bunu kendisi yayınlar. Retained değildir ve Sparkplug 3.0'da will QoS 1 kullanır.

DBIRTH ve DDEATH

Cihazların kendi MQTT bağlantıları yoktur, bu nedenle will kullanamazlar. Edge node, kendi NBIRTH'ünden sonra her cihaz için bir DBIRTH yayınlar ve bir cihazla iletişimi kaybettiğinde, örneğin bir Modbus zaman aşımında, bir DDEATH yayınlar. Node'un kendisi öldüğünde tüm cihazları da örtük olarak ölü kabul edilir; ayrı ayrı DDEATH mesajlarına gerek yoktur.

Sıra Numaraları: seq ve bdSeq

İki sayaç host uygulamalarını doğru yolda tutar.

seq, 0 ile 255 arasında bir payload alanıdır. NBIRTH her zaman seq 0'a sahiptir ve o node'dan gelen her sonraki mesaj (DBIRTH, NDATA, DDATA, DDEATH) bunu bir artırır; 255'ten sonra 0'a döner. Bir atlama gören host, bir mesajı kaçırdığını ve görünümünün yanlış olabileceğini anlar.

bdSeq (birth/death sırası) bir payload alanı değil, bir metriktir. Node her yeni MQTT oturumu başlattığında artar. Node, aynı bdSeq değerini hem bağlanırken kaydettiği NDEATH will'ine hem de bağlandıktan sonra yayınladığı NBIRTH'e koyar. Bir will gecikmeli teslim edilebildiği için, aksi takdirde host yeni bir NBIRTH'ten sonra eski bir NDEATH alıp canlı bir node'u yanlışlıkla çevrimdışı olarak işaretleyebilirdi. Eşleşen bdSeq değerleri, host'un önceki bir oturuma ait death mesajını yok saymasını sağlar.

Adım Adım Yaşam Döngüsü

  1. Edge node bdSeq'i artırır ve bunu içeren bir NDEATH payload'ı oluşturur.
  2. Clean session kullanarak, bu NDEATH'i will olarak (QoS 1, retained değil) ayarlayıp broker'a bağlanır.
  3. Rebirth ve yazma komutlarını alabilmek için NCMD ve DCMD topic'lerine abone olur.
  4. Bir primary host uygulamasını izleyecek şekilde yapılandırılmışsa, o host'un STATE mesajı çevrimiçi diyene kadar bekler.
  5. seq 0 ve aynı bdSeq ile NBIRTH yayınlar.
  6. Her cihaz için bir DBIRTH yayınlar.
  7. NDATA ve DDATA'yı değişiklik olduğunda (report by exception) yayınlar ve her seferinde seq'i artırır.
  8. Kapanırken NDEATH yayınlar; çökme durumunda broker will'i onun yerine yayınlar.

Python'da Bir Birth ve Death Simülatörü Çalıştırın

Aşağıdaki betik bu yaşam döngüsünü paho-mqtt 2.x ile uygular. Eclipse Tahu sparkplug_b.proto dosyasından üretilmiş Python sınıflarına ihtiyaç duyar. Proto dosyasını Tahu deposundan indirin ve sınıfları bir kez üretin:

pip install "paho-mqtt>=2.0" protobuf grpcio-tools
curl -O https://raw.githubusercontent.com/eclipse/tahu/master/sparkplug_b/sparkplug_b.proto
python -m grpc_tools.protoc -I. --python_out=. sparkplug_b.proto

Bu, proto dosyasının yanında sparkplug_b_pb2.py dosyasını oluşturur. Simülatörü aynı klasöre edge_sim.py olarak kaydedin:

import random
import time
import uuid

import paho.mqtt.client as mqtt
import sparkplug_b_pb2 as spb

BROKER = "broker.connectmq.com"
PORT = 1883
GROUP = "demo-" + uuid.uuid4().hex[:6]   # herkese açık broker'da benzersiz grup
NODE = "line1"
DEVICE = "cnc1"

# Sparkplug veri tipi kodları
INT64, DOUBLE, BOOLEAN = 4, 10, 11

seq = 0
bd_seq = 0


def now_ms():
    return int(time.time() * 1000)


def next_seq():
    global seq
    value = seq
    seq = (seq + 1) % 256
    return value


def add_metric(payload, name, datatype, value):
    m = payload.metrics.add()
    m.name = name
    m.timestamp = now_ms()
    m.datatype = datatype
    if datatype == INT64:
        m.long_value = value
    elif datatype == DOUBLE:
        m.double_value = value
    elif datatype == BOOLEAN:
        m.boolean_value = value


def topic(msg_type, device=None):
    base = f"spBv1.0/{GROUP}/{msg_type}/{NODE}"
    return f"{base}/{device}" if device else base


def ndeath_payload():
    p = spb.Payload()
    p.timestamp = now_ms()
    add_metric(p, "bdSeq", INT64, bd_seq)
    return p.SerializeToString()


def publish_births(client):
    global seq
    seq = 0
    nbirth = spb.Payload(timestamp=now_ms(), seq=next_seq())
    add_metric(nbirth, "bdSeq", INT64, bd_seq)
    add_metric(nbirth, "Node Control/Rebirth", BOOLEAN, False)
    add_metric(nbirth, "Properties/Uptime", INT64, 0)
    client.publish(topic("NBIRTH"), nbirth.SerializeToString(), qos=0)

    dbirth = spb.Payload(timestamp=now_ms(), seq=next_seq())
    add_metric(dbirth, "Spindle/Speed", DOUBLE, 0.0)
    add_metric(dbirth, "Spindle/Running", BOOLEAN, False)
    client.publish(topic("DBIRTH", DEVICE), dbirth.SerializeToString(), qos=0)
    print(f"births published for {GROUP}/{NODE}/{DEVICE} (bdSeq={bd_seq})")


def on_connect(client, userdata, flags, reason_code, properties):
    if reason_code.is_failure:
        print("connect failed:", reason_code)
        return
    client.subscribe(f"spBv1.0/{GROUP}/NCMD/{NODE}", qos=0)
    client.subscribe(f"spBv1.0/{GROUP}/DCMD/{NODE}/#", qos=0)
    publish_births(client)


def on_message(client, userdata, msg):
    cmd = spb.Payload()
    cmd.ParseFromString(msg.payload)
    for m in cmd.metrics:
        if m.name == "Node Control/Rebirth" and m.boolean_value:
            print("rebirth requested")
            publish_births(client)


client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
                     client_id=f"edge-sim-{uuid.uuid4().hex[:8]}",
                     clean_session=True)
client.on_connect = on_connect
client.on_message = on_message
client.will_set(topic("NDEATH"), ndeath_payload(), qos=1, retain=False)
client.connect(BROKER, PORT, keepalive=30)
client.loop_start()

try:
    while True:
        time.sleep(2)
        ddata = spb.Payload(timestamp=now_ms(), seq=next_seq())
        add_metric(ddata, "Spindle/Speed", DOUBLE, round(random.uniform(1400, 1500), 1))
        add_metric(ddata, "Spindle/Running", BOOLEAN, True)
        client.publish(topic("DDATA", DEVICE), ddata.SerializeToString(), qos=0)
except KeyboardInterrupt:
    ddeath = spb.Payload(timestamp=now_ms(), seq=next_seq())
    client.publish(topic("DDEATH", DEVICE), ddeath.SerializeToString(), qos=0)
    client.publish(topic("NDEATH"), ndeath_payload(), qos=1).wait_for_publish()
    client.disconnect()
    client.loop_stop()

Betiği python edge_sim.py ile çalıştırın. Grubu mosquitto_sub -h broker.connectmq.com -p 1883 -i watcher-1234 -t "spBv1.0/demo-xxxxxx/#" -v ile izleyin; grup adını betiğin yazdırdığıyla değiştirin. Will'i iş başında görmek için Ctrl+C'ye basmak yerine süreci sonlandırın: keepalive süresi dolduktan sonra broker, node adına NDEATH yayınlar.

Herkese açık MQTT test broker'ı herkes tarafından okunabilir ve client başına saniyede 10 mesaja izin verir; bu yüzden yayın aralığını rahat tutun ve asla gerçek tesis verisi göndermeyin. Gerçek bir kurulum için TLS ile 8883 portuna geçin ve portaldan aldığınız YOUR_USERNAME, YOUR_PASSWORD ve YOUR_CLIENT_ID değerlerini kullanın.

Birth ve Death Mesajlarını Çözülmüş Olarak Görmek

Payload'lar Protobuf olduğu için mosquitto_sub çıktısı kısmen binary görünecektir. ConnectMQ'da topic gezgini Sparkplug B'yi çözer; böylece NBIRTH'ü açıp bdSeq, Node Control/Rebirth ve her cihaz metriğini adıyla görebilirsiniz. Bu, NDEATH'teki bdSeq'in NBIRTH ile eşleştiğini ve seq'in boşluksuz arttığını doğrulamanın en hızlı yoludur. Kendi decoder'ınızı yazmak istiyorsanız Python ile Sparkplug B çözme yazısını izleyin.

Yaygın Hatalar

Hata Etkisi Çözüm
Will, bağlandıktan sonra ayarlanmış Çökmede NDEATH yok will_set çağrısını connect öncesinde yapın
NBIRTH ile NDEATH arasında bdSeq farklı Host death mesajlarını yok sayar veya yanlış uygular Bir oturum için aynı değeri kullanın
DBIRTH'ten önce DDATA Host'ta metrik tanımı yok Her zaman önce birth mesajlarını yayınlayın
Rebirth'te seq sıfırlanmamış Host sahte boşluklar algılar NBIRTH her zaman seq 0 kullanır
Retained birth mesajları Bayat birth'ler yeni host'lara yeniden oynatılır Birth ve death mesajları asla retained olmaz
Kalıcı oturum Eski abonelikler ve kuyrukta bekleyen komutlar Clean session kullanın

Birth ve Death Mimarinize Nasıl Oturur?

Birth ve death sertifikaları, bir yığın MQTT topic'ini güvenilir ve durumdan haberdar bir veri katmanına dönüştüren şeydir; Sparkplug'ın Unified Namespace tasarımlarında ve SCADA'da yaygın olmasının nedeni de budur. Daha geniş bir resim için MQTT ile Endüstriyel IoT rehberine göz atın. Üretimde will mekanizmasının güvenilirliği broker'a da bağlıdır; bu nedenle çoğu ekip Sparkplug'ı masanın altındaki bir kutu yerine yönetilen bir MQTT broker üzerinde çalıştırır.

ConnectMQ ile Başlayın

app.connectmq.com adresinde kredi kartı gerekmeden ücretsiz bir Serverless broker oluşturun. Simülatörü oluşturulan kimlik bilgileriyle kendi broker'ınıza yönlendirin; ardından NBIRTH, DBIRTH, DDATA ve NDEATH mesajlarını ConnectMQ portalında canlı ve çözülmüş olarak izleyin.

Sık Sorulan Sorular

Sparkplug birth sertifikaları retained mıdır?

Hayır. Birth ve death mesajları retain bayrağı olmadan yayınlanır. Daha sonra başlayan bir host, retained mesajlara güvenmek yerine güncel birth mesajlarını almak için bir rebirth komutu gönderir.

NDEATH mesajını kim yayınlar?

Genellikle broker, çünkü NDEATH edge node'un MQTT will'i olarak kaydedilir. Düzgün şekilde kapanan bir node, bağlantıyı kesmeden önce bunu kendisi yayınlayabilir.

Node öldüğünde her cihaz için DDEATH gerekir mi?

Hayır. NDEATH geldiğinde host, o node'un altındaki tüm cihazları çevrimdışı kabul eder. DDEATH yalnızca node bağlı kalırken tek bir cihaz kaybedildiğinde gerekir.

seq 255'e ulaştığında ne olur?

0'a döner ve devam eder. Onu yalnızca NBIRTH kasıtlı olarak sıfırlar; bunun dışındaki her beklenmedik atlama, kaçırılmış bir mesaja işaret eder.

İlgili yazılar

CODESYS MQTT Client: PLC Değişkenlerini Bir Broker'a Yayınlama

CODESYS IIoT MQTT Client kütüphanesini PLC değişkenlerini JSON olarak yayınlayacak şekilde yapılandırın, broker.connectmq.com üzerinde doğrulayın, ardından kimlik bilgileri ve TLS içeren özel bir broker'a geçin.

6 dk okuma

Tüm yazılar →

Özel MQTT broker’ınız birkaç tık uzağınızda

Hesabınızı oluşturun, broker kimlik bilgilerinizi alın ve ilk cihazınızı bağlayın — kurulacak, yamalanacak ya da ölçeklendirilecek sunucu yok.