Node-RED MQTT topic eşleştirme, cihazlarınızın zaten yayınladığı düz, üreticiye özgü topic'leri fabrikanın geri kalanının anlayabileceği temiz bir ISA-95 hiyerarşisine dönüştürmenin en hızlı yoludur. Bu eğitimde ham cihaz topic'lerine abone olan, her cihazı bir eşleme tablosunda arayan, payload'ı normalleştiren ve onu bir ConnectMQ broker üzerindeki yapılandırılmış bir ad alanına yeniden yayınlayan küçük bir Node-RED akışı oluşturacaksınız.
MQTT Topic'lerini Neden Yeniden Eşlemeli?
Mevcut (brownfield) kurulumların çoğu kendiliğinden büyür. Bir sıcaklık ağ geçidi dev/th-0042/temp topic'ine yayın yapar, bir enerji analizörü meter7/kw kullanır ve bir PLC ağ geçidi plc/line2/status yazar. Her topic, o cihazı yapılandıran kişi için anlamlıydı, ancak bir araya geldiklerinde bir tüketiciye verinin fabrikada nerede durduğu hakkında hiçbir şey söylemezler.
Unified Namespace bunu, genellikle ISA-95 seviyelerini izleyen tek bir hiyerarşi üzerinde anlaşarak çözer: kuruluş, tesis, alan, hat, hücre veya makine ve son olarak veri noktası. Her mesaj acme/izmir/packaging/line2/filler1/temperature gibi öngörülebilir bir yolda durduğunda, panolar, historian'lar ve analitik araçlar uzun bir istisna listesi tutmak yerine joker karakterlerle abone olabilir. Bu desenin arka planı Sparkplug B ve Unified Namespace rehberimizde ele alınıyor.
Çoğu zaman cihazların kendisini yeniden yapılandıramazsınız. Firmware kilitli olabilir, üretici ortadan kalkmış olabilir ya da bir üretim kontrolörüne dokunmak bu çeyrekte alamayacağınız bir değişiklik penceresi gerektirebilir. Node-RED ortada durur ve kaynağa dokunmadan çeviriyi yapar.
Hedef ISA-95 Topic Yapısını Tasarlamak
Kod yazmadan önce hedef yapıya karar verin. Bir eşleme akışı ancak yazdığı ad alanı kadar iyidir. Pratik bir düzen şöyle görünür:
| Seviye | Örnek değer | Notlar |
|---|---|---|
| Kuruluş | acme | Genellikle broker veya sabit bir ön ek tarafından ima edilir |
| Tesis | izmir | Her fiziksel fabrika için bir tane |
| Alan | packaging | Departman veya salon |
| Hat | line2 | Üretim hattı veya proses ünitesi |
| Makine | filler1 | Hücre, makine veya varlık |
| Veri noktası | temperature | Topic başına bir ölçüm veya durum |
Birkaç kural ad alanını zaman içinde sağlıklı tutar:
- Topic'lerin aboneliklerde ve filtrelerde kolayca yazılabilmesi için küçük harf, ASCII ve boşluksuz kullanın.
- Topic başına bir veri noktası ya da makine başına iyi tanımlanmış bir JSON nesnesi yayınlayın ve bu seçimi tutarlı tutun.
- Topic'in kendisine asla zaman damgası, sıra numarası ya da değer koymayın.
- Derinliği kontrol altında tutun. broker.connectmq.com adresindeki herkese açık MQTT test broker'ında bir topic en fazla 8 seviyeye sahip olabilir; bu yüzden bu eğitim üç seviyeli bir demo ön eki artı beş ISA-95 seviyesi kullanıyor.
Demo için ön ek olarak connectmq/demo/ab12cd (ab12cd yerine kendi rastgele dizenizi kullanın), ham giriş için connectmq/demo/ab12cd/raw/# ve yapılandırılmış çıkış için connectmq/demo/ab12cd/<site>/<area>/<line>/<machine>/<point> kullanacağız. Herkese açık alanın herkes tarafından okunabildiğini unutmayın; oraya yalnızca test verisi gönderin.
Node-RED MQTT Topic Eşleştirme Nasıl Çalışır?
Akışın dört parçası vardır:
- Bir mqtt in node'u ham topic'lere bir joker karakterle abone olur.
- Bir function node'u gelen topic'i böler, cihazı bir arama tablosunda bulur, yeni topic'i oluşturur ve payload'ı normalleştirir.
- Bir mqtt out node'u sonucu yayınlar. Kendi topic alanı boşsa
msg.topickullanır; istediğimiz de tam olarak budur. - Function node'unun ikinci çıkışı, eşlenmemiş mesajları bir debug node'una gönderir; böylece yeni ya da yanlış yapılandırılmış cihazları fark edebilirsiniz.
MQTT node'larının kendisine yeniyseniz Node-RED MQTT eğitimiyle başlayın ve sonra buraya dönün.
Eşleme tablosu
Eşlemeyi tek bir yerde tutun. Birkaç cihaz için function node'unun içindeki bir JavaScript nesnesi yeterlidir. Düzinelerce cihaz için onu bir dosyadan ya da retained bir MQTT mesajından global context'e yükleyin; böylece yeniden deploy etmeden güncelleyebilirsiniz.
Function node'u
Bunu bir function node'una yapıştırın ve 2 çıkış olarak ayarlayın:
// Ham topic'ler şöyle görünür: connectmq/demo/ab12cd/raw/<deviceId>/<rawPoint>
const PREFIX = "connectmq/demo/ab12cd";
// deviceId -> ISA-95 konumu
const devices = {
"th-0042": { site: "izmir", area: "packaging", line: "line2", machine: "filler1" },
"meter7": { site: "izmir", area: "utilities", line: "main", machine: "meter7" },
"plc-l2": { site: "izmir", area: "packaging", line: "line2", machine: "plc" }
};
// ham nokta adı -> normalleştirilmiş nokta adı ve birim
const points = {
"temp": { name: "temperature", unit: "C" },
"hum": { name: "humidity", unit: "%" },
"kw": { name: "power", unit: "kW" },
"status": { name: "state", unit: null }
};
const parts = msg.topic.split("/");
// parts: [connectmq, demo, ab12cd, raw, deviceId, rawPoint]
const deviceId = parts[4];
const rawPoint = parts[5];
const loc = devices[deviceId];
const point = points[rawPoint];
if (!loc || !point || parts.length !== 6) {
node.warn("Unmapped topic: " + msg.topic);
return [null, msg];
}
// Düz sayıları, dizeleri veya "value" alanı olan JSON nesnelerini kabul et
let value = msg.payload;
if (typeof value === "object" && value !== null && "value" in value) {
value = value.value;
}
const numeric = Number(value);
const out = {
topic: [PREFIX, loc.site, loc.area, loc.line, loc.machine, point.name].join("/"),
payload: {
value: isNaN(numeric) ? value : numeric,
unit: point.unit,
ts: new Date().toISOString(),
source: msg.topic
},
retain: true,
qos: 1
};
return [out, null];
retain: true ayarı, her yeni abonenin her veri noktasının son değerini hemen alması anlamına gelir; Unified Namespace tüketicilerinin çoğu ağacın böyle davranmasını bekler. source alanı orijinal topic'e geri bir iz bırakır; bu, hata ayıklarken çok yardımcı olur.
İçe aktarılabilir akış
Akışın tamamını Menu → Import ile içe aktarabilirsiniz. İçe aktardıktan sonra yukarıdaki function kodunu function node'una yapıştırın ve client ID ile ön eki kendi değerlerinizle değiştirin.
[
{"id":"b1","type":"mqtt-broker","name":"public broker","broker":"broker.connectmq.com","port":"1883","clientid":"nr-mapper-ab12cd","autoConnect":true,"usetls":false,"protocolVersion":"5","keepalive":"60","cleansession":true},
{"id":"in1","type":"mqtt in","name":"raw devices","topic":"connectmq/demo/ab12cd/raw/#","qos":"1","datatype":"auto-detect","broker":"b1","nl":false,"rap":true,"rh":0,"inputs":0,"x":140,"y":100,"wires":[["fn1"]]},
{"id":"fn1","type":"function","name":"map to ISA-95","func":"return [msg, null];","outputs":2,"x":340,"y":100,"wires":[["out1"],["dbg1"]]},
{"id":"out1","type":"mqtt out","name":"publish ISA-95","topic":"","qos":"","retain":"","broker":"b1","x":560,"y":80,"wires":[]},
{"id":"dbg1","type":"debug","name":"unmapped","active":true,"complete":"true","x":550,"y":140,"wires":[]}
]
mqtt out node'u qos ve retain alanlarını boş bırakır; böylece function node'unda ayarlanan değerler kullanılır.
Eşlemeyi mosquitto ile Test Etmek
Bir terminal açın ve ağacın yapılandırılmış tarafını izleyin:
mosquitto_sub -h broker.connectmq.com -p 1883 -i sub-ab12cd -v -t "connectmq/demo/ab12cd/izmir/#"
İkinci bir terminalde ham tarafta cihazları simüle edin:
mosquitto_pub -h broker.connectmq.com -p 1883 -i pub-ab12cd -t "connectmq/demo/ab12cd/raw/th-0042/temp" -m "23.7"
mosquitto_pub -h broker.connectmq.com -p 1883 -i pub-ab12cd -t "connectmq/demo/ab12cd/raw/meter7/kw" -m '{"value": 4.2}'
mosquitto_pub -h broker.connectmq.com -p 1883 -i pub-ab12cd -t "connectmq/demo/ab12cd/raw/unknown-1/temp" -m "19"
İlk iki mesaj izmir/packaging/line2/filler1/temperature ve izmir/utilities/main/meter7/power altında görünmelidir. Üçüncüsü Node-RED debug kenar çubuğunda eşlenmemiş olarak görünmelidir.
Döngülerden ve Diğer Tuzaklardan Kaçınmak
Yeniden eşleme akışlarındaki en yaygın hata, çıkışla da eşleşen bir joker karaktere abone olmaktır. mqtt in node'u connectmq/demo/ab12cd/# topic'ini dinliyor ve akış aynı ön ek altına geri yayın yapıyorsa, yeniden yayınlanan her mesaj tekrar alınır, tekrar eşlenir ve sonunda broker'ı mesaj yağmuruna tutar. Ham ve yapılandırılmış veriyi ağacın ayrı dallarında tutun ve yalnızca ham dala abone olun.
MQTT 5 ile mqtt in node'unda no local seçeneğini de etkinleştirebilirsiniz; böylece istemci kendi yayınladığı mesajları asla almaz. Bu bir güvenlik ağıdır, iyi topic tasarımının yerine geçmez, çünkü ikinci bir Node-RED örneği mesajları yine de görür.
Kontrol etmeye değer diğer tuzaklar:
| Belirti | Olası neden | Çözüm |
|---|---|---|
| Hiçbir şey yeniden yayınlanmıyor | Function her iki çıkışta da null döndürüyor |
Debug çıktısını ve parts.length kontrolünü inceleyin |
Çıkış topic'i undefined içeriyor |
Cihaz tabloda ama bir seviyesi eksik | Her tablo girdisinde dört seviyenin de olduğunu doğrulayın |
| Yeniden adlandırmadan sonra eski değerler tekrar beliriyor | Eski topic'teki retained message'lar | Temizlemek için eski topic'e boş bir retained payload yayınlayın |
| Aşağı akışta sayı yerine dizeler | Ham payload'da 23.7C gibi birimler vardı |
Number() öncesinde function node'unda birimleri ayıklayın |
| Herkese açık broker'da bağlantı kopmaları | İstemci başına saniyede 10'dan fazla mesaj | Bir delay node ile kısın ya da kendi broker'ınızı kullanın |
Akışı Üretime Taşımak
Herkese açık broker denemeler için uygundur, ancak üretim verisi kimlik bilgileri ve TLS kullanan özel bir broker'a aittir. ConnectMQ'da bir broker oluşturun, üretilen kullanıcı adını, parolayı ve client ID'yi portaldan kopyalayın ve broker yapılandırma node'unu şöyle değiştirin:
- Sunucu
broker.connectmq.com(ya da portaldaki broker host'unuz), port8883, Use TLS etkin - Client ID
YOUR_CLIENT_ID, kullanıcı adıYOUR_USERNAME, parolaYOUR_PASSWORD - Protokol MQTT V5
Broker sertifikası Let's Encrypt tarafından verildiği için Node-RED'in Node.js çalışma ortamındaki varsayılan güven deposu, bir CA dosyası yüklemeden onu doğrular. TLS üzerinden Node-RED MQTT rehberimiz TLS ayarlarını adım adım anlatıyor.
Yapılandırılmış topic'ler akmaya başladığında ConnectMQ portalı ISA-95 biçimli ad alanını algılar ve cihazlarınızı tesis, alan, hat ve makineye göre gruplanmış olarak gösterir; canlı topic gezgini de ayrı bir istemci açmadan ağacı kontrol etmenizi sağlar. Kaynaklarınızın bazıları zaten Sparkplug B konuşuyorsa, onlar için Node-RED'e hiç ihtiyacınız olmayabilir: broker Sparkplug B'yi çözümleyip ISA-95 topic'lerine yeniden yayınlayabilir; böylece Node-RED'in yalnızca düz topic'leri işlemesi gerekir. PLC kaynakları için Node-RED Modbus rehberi register'ların nasıl okunup aynı eşleme akışına besleneceğini gösteriyor.
Yönetilen bir broker çalışma süresini, sertifikaları ve bağlantı sınırlarını üstlendiği için eşleme akışı bakımını yaptığınız tek hareketli parça olur. Ad alanı büyüdükçe ekiplerin kendi barındırdıkları bir Mosquitto sunucusundan yönetilen bir MQTT broker'a geçmesinin büyük bir nedeni budur.
Eşleme Tablosunu Ölçeklendirmek
Cihaz sayısı bir function node'u içinde düzenlemek istediğinizden fazla büyüdüğünde tabloyu dışarı taşıyın:
- Retained yapılandırma topic'i: eşlemeyi örneğin
config/topic-maptopic'ine retained bir JSON mesajı olarak yayınlayın, ayrı bir akışta ona abone olun veglobal.set("topicMap", msg.payload)ile saklayın. Eşleme fonksiyonu onuglobal.get("topicMap")ile okur. Güncellemeler yeniden deploy etmeden geçerli olur. - Dosya veya veritabanı: başlangıçta bir file in node'uyla bir CSV ya da JSON dosyası okuyun veya küçük bir tabloyu sorgulayın; bu, zaten bir varlık kaydı yöneten ekiplere uygundur.
- Desen kuralları: cihaz kimlikleri
iz-pk-l2-filler1-tempgibi konumlarını kodluyorsa, bölmeye dayalı bir kural tablonun çoğunun yerini alabilir; istisnalar için küçük bir tablo yeterlidir.
Ne seçerseniz seçin, eşlenmemiş çıkışı görünür bir şeye bağlı tutun. Yeni cihazlar sessizce ortaya çıkar ve bir eşlenmemiş uyarısı çoğu zaman bir ağ geçidinin değiştirildiğinin ya da yeniden adlandırıldığının tek işaretidir.
Node-RED Topic Eşleştirmenizi ConnectMQ Üzerinde Çalıştırın
Temiz bir ad alanının altında güvenilir bir broker gerekir. app.connectmq.com adresinden kredi kartı gerektirmeyen ücretsiz Serverless planına kaydolun, bir broker oluşturun ve eşleme akışınızı 8883 portunda TLS ile ona yönlendirin. MQTT 5'i, her veri noktasının son değeri için retained message'ları ve ISA-95 seviyelerinizi ilk mesajdan itibaren anlayan bir cihaz görünümünü elde edersiniz. Barındırma seçeneklerine daha geniş bir bakış için bulut MQTT broker rehberimizi okuyun.
Sık Sorulan Sorular
Node-RED topic'leri function node olmadan yeniden yazabilir mi?
Evet. Bir change node'u msg.topic değerini bir JSONata ifadesiyle ayarlayabilir ve basit ön ek değişimleri için bu yeterlidir. Aynı adımda bir arama tablosuna, doğrulamaya ve payload normalleştirmeye ihtiyaç duyduğunuzda bir function node'unu okumak daha kolaydır.
Değer başına bir topic mi yoksa makine başına bir JSON nesnesi mi yayınlamalıyım?
Unified Namespace'te ikisi de çalışır. Topic başına bir değer panolar ve uyarı kuralları için daha basittir, makine başına bir nesne ise mesaj sayısını azaltır; bir kural seçin ve her yerde uygulayın.
Akışın kendi mesajlarını yeniden yayınlamasını nasıl engellerim?
Yalnızca akışın asla yazmadığı bir ham dala abone olun ve ek bir önlem olarak mqtt in node'unda MQTT 5 no local seçeneğini etkinleştirin.
ConnectMQ topic'leri kendi başına yeniden eşler mi?
Sparkplug B mesajlarını ISA-95 topic'lerine yeniden yayınlar, ancak keyfi topic yeniden yazma kuralları çalıştırmaz. Düz ya da üreticiye özgü topic'ler için eşlemeyi burada gösterildiği gibi Node-RED'de ya da başka bir MQTT istemcisinde çalıştırın.



