ISA-95 MQTT topic'leri, tesisin ekipman hiyerarşisini doğrudan topic yoluna yerleştirir; böylece acme/dallas/packaging/line-02/filler/telemetry, her aboneye bir değerin tam olarak nereden geldiğini söyler. Bu rehberde her ISA-95 seviyesini nasıl kodlayacağınızı, topic'in yaprağını nasıl tasarlayacağınızı, joker karakterli abonelikleri ihtiyaç duymadan önce nasıl planlayacağınızı ve bir namespace üretime geçtikten sonra en çok yeniden işe yol açan tuzakları öğreneceksiniz.
ISA-95'i MQTT Topic'lerine Neden Kodlamalı?
MQTT topic'leri eğik çizgilerle ayrılmış serbest biçimli dizelerdir ve MQTT broker bunlara abonelik eşleştirmenin ötesinde bir anlam yüklemez. Bu özgürlük tesis ölçeğinde tehlikelidir. Her entegratör kendi yapısını icat ederse tüketiciler her kaynak için ayrı bir eşleme tablosuyla uğraşmak zorunda kalır.
ISA-95 ekipman hiyerarşisi, tesisin belgelerinde, MES'inde ve bakım sisteminde zaten var olan bir yapı sunarak bu sorunu çözer. Onu topic'lere kodlamak size üç özelliği bedavaya kazandırır:
- Keşfedilebilirlik. Tesisi tanıyan herkes ağaçta gezinerek bir değeri bulabilir.
- Bağlam. Topic varlığın adresini taşır; bu yüzden payload'ların onu tekrarlamasına gerek kalmaz.
- Seçici abonelik. Joker karakterler organizasyonel kapsamlarla doğal biçimde eşleşir: tek bir saha, tek bir alan, tüm dolum makineleri.
Seviyelerin kendisini hatırlamanız gerekiyorsa önce ISA-95 ekipman hiyerarşisi yazısını okuyun.
Temel Desen
Standart desen, seviyeleri en geniş kapsamdan en dar kapsama doğru sıralar ve ardından mesajın ne tür veri içerdiğini söyleyen bir ad alanı (namespace) ekler:
<enterprise>/<site>/<area>/<work center>/<work unit>/<namespace>[/<detail>]
acme/dallas/packaging/line-02/filler/telemetry
acme/dallas/packaging/line-02/filler/state
acme/dallas/packaging/line-02/filler/alarms
acme/dallas/packaging/line-02/filler/events/batch-complete
acme/dallas/packaging/line-02/filler/cmd/stop
Her Seviye İçin Kurallar
| Seviye | Kural | Örnek |
|---|---|---|
| Kuruluş (Enterprise) | Tek, kalıcı, kısa bir ad; yalnızca broker tek bir şirkete hizmet veriyorsa çıkarın | acme |
| Saha (Site) | Yeniden yapılanmalardan etkilenmeyen konum kodu | dallas, izmir |
| Alan (Area) | İşlev veya ürün alanı | packaging, utilities |
| İş merkezi (Work center) | Hat, hücre, proses hücresi, ünite veya depolama bölgesi | line-02, cell-03 |
| İş birimi (Work unit) | Makine veya ünite, ideal olarak varlık etiketiyle | filler, cnc-01 |
| Ad alanı (Namespace) | Sabit kelime dağarcığı | telemetry, state, alarms, events, cmd |
Ekipman topic'leri için derinliği sabit tutun. Her iş birimi beşinci seviyede durduğunda +/+/+/+/+/state, kuruluştaki tüm makine durumlarını döndürür ve her seviyenin yoldaki konumu garanti altına alınır.
Yaprağı Tasarlamak
Ad alanı ve ondan sonra gelen her şey, tasarım tartışmalarının çoğunun yaşandığı yerdir. Telemetri için iki yaygın seçenek vardır.
Ekipman başına tek nesne. Bir makinenin tüm güncel değerleri .../filler/telemetry üzerindeki tek bir JSON belgesine girer. Bu yaklaşım kompakttır, ilişkili değerleri zaman açısından tutarlı tutar ve makine başına yalnızca bir retained message gerektirir.
{ "ts": "2026-10-16T08:15:02Z", "speed_bpm": 118.4, "temp_c": 41.2, "good_count": 18342, "v": 1 }
Metrik başına tek topic. Her değerin kendi topic'i vardır; örneğin .../filler/telemetry/speed_bpm, skaler veya küçük bir JSON payload ile. Bu, SCADA sistemleri gibi etiket tabanlı araçlarla doğal biçimde eşleşir ve tüketiciler tam olarak ihtiyaç duydukları sinyallere abone olabilir.
İkisi de geçerlidir. Her ad alanı için birini seçin ve belgeleyin. Yaygın bir karma yaklaşım, telemetri için nesne; state ve birkaç kilit KPI için ise topic bazında retained değerler kullanır.
Joker Karakterli Aboneliklerinizi Planlayın
Yapıyı kesinleştirmeden önce tüketicilerinizin ihtiyaç duyacağı abonelikleri yazın ve her birinin tek bir joker karakter filtresiyle karşılandığını kontrol edin:
| Tüketici | İhtiyaç | Abonelik |
|---|---|---|
| Saha panosu | Bir sahadaki her şey | acme/dallas/# |
| Paketleme sorumlusu | Bir alandaki tüm durumlar | acme/dallas/packaging/+/+/state |
| Filo analitiği | Her yerdeki tüm dolum makineleri | acme/+/+/+/filler/telemetry |
| Alarm servisi | Tüm alarmlar | acme/+/+/+/+/alarms |
| Historian | Tüm telemetri | acme/+/+/+/+/telemetry |
İhtiyaç duyulan bir kapsam birden fazla abonelik veya istemci tarafında filtreleme gerektiriyorsa yapı size karşı çalışıyor demektir. Bu genellikle bir seviyenin eksik olduğu, tutarsız sıralandığı ya da yaprak kelime dağarcığının fazla gevşek olduğu anlamına gelir.
Koddan ISA-95 Topic'leri Yayınlamak
Topic'leri tek bir yerde üretmek, yazım hatalarının başıboş dallar oluşturmasını engeller. Bu Python yardımcısı yolu oluşturup doğrular, ardından retained durum ve telemetri yayınlar. İstemciyi pip install "paho-mqtt>=2.0" ile kurun. Betik herkese açık broker'ı bir demo önekiyle kullanır; özel bir broker'da PREFIX değerini kuruluş adınız yapın.
import json
import re
import threading
from dataclasses import dataclass
from datetime import datetime, timezone
import paho.mqtt.client as mqtt
PREFIX = "connectmq/demo/r8t5" # kendi broker'ınızda: "acme"
SAFE = re.compile(r"^[a-z0-9]+(-[a-z0-9]+)*$")
NAMESPACES = {"telemetry", "state", "alarms", "events", "cmd"}
@dataclass(frozen=True)
class Asset:
site: str
area: str
work_center: str
work_unit: str
def topic(self, namespace: str) -> str:
for level in (self.site, self.area, self.work_center, self.work_unit):
if not SAFE.match(level):
raise ValueError(f"invalid level: {level!r}")
if namespace not in NAMESPACES:
raise ValueError(f"unknown namespace: {namespace!r}")
return f"{PREFIX}/{self.site}/{self.area}/{self.work_center}/{self.work_unit}/{namespace}"
filler = Asset("dallas", "packaging", "line-02", "filler")
connected = threading.Event()
def on_connect(client, userdata, flags, reason_code, properties):
print("connected:", reason_code)
connected.set()
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="isa95-pub-r8t5")
client.on_connect = on_connect
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_start()
connected.wait(timeout=10)
client.publish(filler.topic("state"), "running", qos=1, retain=True).wait_for_publish()
telemetry = {"ts": datetime.now(timezone.utc).isoformat(), "speed_bpm": 118.4, "temp_c": 41.2, "v": 1}
client.publish(filler.topic("telemetry"), json.dumps(telemetry), qos=1, retain=True).wait_for_publish()
print("published to", filler.topic("telemetry"))
client.loop_stop()
client.disconnect()
Yukarıdaki tabloyla eşleşen bir joker karakterle doğrulayın:
mosquitto_sub -h broker.connectmq.com -p 1883 -i isa95-sub-r8t5 -t "connectmq/demo/r8t5/+/packaging/+/+/state" -v
Herkese açık MQTT test broker'ı herkes tarafından okunabilir ve 8 topic seviyesine izin verir; bu yüzden burada kuruluş seviyesinin yerini demo öneki alıyor. Gerçek varlık adlarını ve değerleri özel bir broker için saklayın.
Sparkplug B'yi ISA-95 Ağacına Taşımak
Sparkplug B topic'leri Protobuf payload'larla birlikte spBv1.0/<group>/<type>/<edge node>/<device> şeklinde sabit bir format izler. ISA-95'i takip etmezler ve Sparkplug'ı tanımayan tüketiciler bunları okuyamaz. Sahada Sparkplug'dan vazgeçmek yerine verisini ISA-95 ağacınıza yeniden yayınlayın.
ConnectMQ bunu otomatik olarak yapar: Protobuf veya JSON formatındaki Sparkplug B payload'larını çözer ve ISA-95 topic'lerine yeniden yayınlar. Örneğin spBv1.0/factory1/DDATA/line1/cnc1, connectmq/factory1/production/line1/cnc1/telemetry olarak yeniden yayınlanır. Ortaya çıkan ISA-95 yollarının okunabilir olması için anlamlı tesis adları taşıyan Sparkplug group ve edge node kimlikleri seçin. İki yaklaşım arasındaki ödünleşimler MQTT, Sparkplug B ve unified namespace yazısında ele alınıyor.
Kaçınılması Gereken Tuzaklar
- Baştaki eğik çizgi.
/acme/dallasboş bir ilk seviye oluşturur ve abonelikleri böler. - Karışık büyük-küçük harf. Topic'ler büyük-küçük harfe duyarlıdır;
Line-02veline-02farklı dallardır. - Yolda protokol veya tedarikçi adları.
acme/dallas/opcua/..., tüketicileri bugünkü entegrasyon teknolojisine bağımlı kılar. - Değişken derinlik. Bir makine için bir seviyeyi atlamak, konuma dayalı joker karakterleri bozar. Bunun yerine bir yer tutucu iş merkezi kullanın.
- Topic'lerde zaman damgası veya kimlik.
.../telemetry/20261016gibi topic'ler sınırsız dallar ve retained message karmaşası yaratır. - Olayları retained yapmak. Olay akışlarını değil, durumu retained yapın; yeni bir abone bayatlamış bir "batch complete" mesajı almamalıdır.
- İstek ve yanıt olmadan komutlar.
cmdiçin MQTT 5 yanıt topic'lerini ve korelasyon verisini kullanın; böylece talep eden taraf komutun başarılı olup olmadığını bilir. - Kısıtlı bağlantılarda derin yollar. Uzun topic'ler her mesaja bayt ekler. MQTT 5 topic alias'ları tasarımı değiştirmeden bu yükü azaltır.
Yaygınlaştırmadan Önce Standardı Belgeleyin
Yalnızca bir mühendisin kafasında yaşayan bir topic standardı, ikinci entegratör tarafından bozulur. İlk gateway devreye girmeden önce şunları kapsayan tek sayfalık bir standart yazın:
- Seviye sırası ve her seviyede izin verilen karakterler.
- Ad alanlarının listesi ve her birinin neler içerebileceği, örnek bir payload ile.
- Hangi topic'lerin retained olduğu, hangilerinin olmadığı.
- Zaman damgası formatı, saat dilimi ve birim kuralları.
- Yeni sahaları, alanları ve iş merkezlerini kimin onayladığı ve taleplerin nasıl yapıldığı.
Bu sayfayı, yukarıdaki topic yardımcısı veya kendi dillerindeki eşdeğeriyle birlikte her sistem entegratörüne ve gateway tedarikçisine verin. Standart ve kod uyumlu olduğunda hataların çoğu broker'a ulaşmadan yakalanır.
Güvenlik ayrı bir notu hak ediyor: her yayıncının tanımlanabilir ve erişiminin iptal edilebilir olması için her gateway ve uygulamaya bir kimlik bilgisi verin, laboratuvar dışındaki her yerde 8883 portunda TLS kullanın. Gerisini MQTT güvenliği en iyi uygulamaları yazımız ele alıyor.
Kopyalamaya hazır eksiksiz ağaçlar için UNS topic yapısı yazısına bakın. Etraflarındaki mimari için başlangıç noktası endüstriyel IoT MQTT rehberidir.
ISA-95 MQTT Topic'lerini ConnectMQ Üzerinde Çalıştırın
ConnectMQ, endüstriyel topic yapılarını anlayan bir barındırılan MQTT broker hizmetidir: ISA-95 ve unified namespace topic'lerini algılar, portalda cihazları ISA-95 seviyesine göre gösterir ve Sparkplug B'yi ağacınıza yeniden yayınlar. app.connectmq.com adresinde kredi kartı gerektirmeden ücretsiz Serverless planla bir broker oluşturun ve ilk ISA-95 dalınızı bugün yayınlayın.
Sık Sorulan Sorular
Kuruluş adı ilk topic seviyesi olmalı mı?
Broker bir gün birden fazla şirkete veya iş birimine hizmet verebilecekse evet. Tek şirketlik bir broker'da çıkarabilirsiniz, ancak sonradan eklemek her topic'i yeniden adlandırmak anlamına gelir.
Bir hatta ait olmayan makineleri nasıl ele alırım?
Onlara standalone veya shared gibi bir yer tutucu iş merkezi verin; böylece diğer her şeyle aynı derinlikte dururlar.
ISA-95 MQTT topic'lerinde boşluk veya büyük harf kullanabilir miyim?
MQTT bunlara izin verir, ancak fark edilmesi zor hatalara yol açarlar. Yalnızca küçük harf, rakam ve tire kullanın.
ISA-95 topic'leri MQTT 3.1.1 ile çalışır mı?
Evet. Topic tasarımı sürümden bağımsızdır. MQTT 5, topic alias'ları ve komutlar için yanıt topic'leri gibi faydalı ekler sunar.



