MTConnect'ten MQTT'ye köprü, bir CNC makinesinin standartlaştırılmış verisinden canlı panolara, uyarılara ve kullanım raporlarına giden en kısa yoldur. Bu eğitimde bir MTConnect agent'ının veriyi nasıl sunduğunu öğrenecek, ardından agent'ın sıra numaralarını hiçbir gözlemi kaçırmadan izleyen, çalışma durumu, iş mili devri ve parça sayısı gibi veri öğelerini okunabilir topic'lere eşleyen ve bunları MQTT üzerinden yayımlayan bir Python köprüsü kuracaksınız. Aynı köprü tek bir makine için de bütün bir hücre için de çalışır.
MTConnect Makine Verisini Nasıl Sunar?
MTConnect, üretim ekipmanları, özellikle takım tezgâhları için açık bir standarttır. Bir sözlük ("Execution", "SpindleSpeed" veya "PartCount"un ne anlama geldiği) ve bir agent tarafından sunulan salt okunur bir HTTP arayüzü tanımlar. Makineler agent ile, çoğu zaman kontrol üreticisi tarafından sağlanan veya kontrol ünitesine yerleşik olan bir adapter aracılığıyla konuşur; client'lar ise agent'tan okur.
Agent üç ana istek sunar:
| İstek | Döndürdüğü | Ne için kullanılır |
|---|---|---|
/probe |
Cihaz modeli: ID'leri, tipleri ve birimleriyle bileşenler ve veri öğeleri | Başlangıçta bir kez veri öğesi kataloğu oluşturmak |
/current |
Her veri öğesinin son değeri ve başlıktaki sıra bilgisi | Başlangıç durumu ve hatalardan sonra yeniden senkronizasyon |
/sample?from=N&count=M |
N sırasından itibaren en fazla M öğeye kadar her gözlem | Hiçbirini kaçırmadan değişiklikleri izlemek |
Her gözlem, agent tarafından atanan bir sequence numarası, bir timestamp ve bir dataItemId taşır. Yanıt başlığı firstSequence, lastSequence, nextSequence ve bir instanceId içerir. Bu dört değer güvenilir bir köprünün anahtarıdır: /current ile başlarsınız, nextSequence değerini hatırlarsınız ve oradan itibaren örnek istersiniz.
MTConnect gözlemleri, MQTT'de onlara nasıl davranmanız gerektiğiyle düzgün şekilde örtüşen üç kategoriye ayrılır:
- Sample'lar, iş mili devri, yük veya konum gibi sayısal ölçümlerdir.
- Event'ler, çalışma durumu, kontrol modu, program adı veya parça sayısı gibi ayrık durumlar ya da değerlerdir.
- Condition'lar sağlığı tanımlar:
Normal,Warning,FaultveyaUnavailable; çoğu zaman yerel bir alarm koduyla birlikte.
Değeri bilinmeyen bir veri öğesi UNAVAILABLE raporlar. Köprünüz bunu gizlememeli, olduğu gibi iletmelidir; çünkü "makine kapalı veya bağlantısı kopuk" önemli bir bilgidir.
MTConnect'i MQTT'ye Neden Köprülemeli?
MTConnect çekme (pull) tabanlıdır ve XML ağırlıklıdır. Tek bir pano için bu sorun değildir, ama her yeni tüketici agent'ı ayrı ayrı sorgular ve XML ayrıştırmak zorunda kalır. MQTT'ye köprülemek size itme (push) tabanlı iletim, tüketici dostu tek bir JSON biçimi, sonradan katılanlar için retained güncel durum ve makine verisini PLC, enerji ve kalite verisiyle tek bir topic hiyerarşisinde birleştirme imkânı verir. Bir Unified Namespace kuruyorsanız MTConnect makineleri onu besleyen kaynaklardan biri olur; ISA-95 MQTT topic'leri rehberimiz onları nereye yerleştireceğinizi gösteriyor.
MTConnect referans agent'ının yeni sürümleri, yerleşik bir MQTT sink aracılığıyla doğrudan bir MQTT broker'a da yayın yapabilir. Agent sürümünüz bunu destekliyorsa değerlendirmeye değer; yapılandırma anahtarları sürümler arasında farklılık gösterdiğinden agent'ın kendi dokümantasyonunu izleyin. Bu eğitimdeki köprü her agent sürümüyle çalışır ve topic adları ile payload biçimi üzerinde size tam kontrol sağlar.
Ön Koşullar
requestsvepaho-mqtt2.x yüklü Python 3.10 veya daha yenisi.http://192.168.10.50:5000gibi bir MTConnect agent URL'si. Bağlı bir makineniz yoksa referans agent projesi, yerel olarak çalıştırabileceğiniz örnek yapılandırmalar ve bir simülatör içerir.- Bir broker. Test için benzersiz bir topic önekiyle ücretsiz public MQTT broker'ı kullanın.
pip install requests "paho-mqtt>=2.0"
curl -s http://localhost:5000/probe | head -40 # agent'ın yanıt verdiğini kontrol edin ve veri öğelerini listeleyin
1. Adım: Veri Öğelerini Seçin
Modern bir CNC yüzlerce veri öğesi sunabilir. Her şeyi değil, tüketicilerin ihtiyaç duyduğunu yayımlayın. Kullanım ve durum panoları için pratik bir başlangıç seti:
| MTConnect tipi | Kategori | Örnek değerler | Neden önemli |
|---|---|---|---|
| AVAILABILITY | Event | AVAILABLE, UNAVAILABLE | Makine hiç bağlı mı |
| EXECUTION | Event | ACTIVE, READY, INTERRUPTED, FEED_HOLD, STOPPED | Kullanım takibinin özü |
| CONTROLLER_MODE | Event | AUTOMATIC, MANUAL, MANUAL_DATA_INPUT | Üretimi ayardan ayırır |
| PROGRAM | Event | O1234 | Hangi iş çalışıyor |
| PART_COUNT | Event | 1843 | Çıktı |
| ROTARY_VELOCITY (iş mili) | Sample | 12000 | Kesme faaliyeti |
| PATH_FEEDRATE_OVERRIDE | Event veya Sample | 100 | Operatör müdahalesi |
| Sistem ve mantık condition'ları | Condition | Normal, Warning, Fault | Alarmlar |
Agent'ınıza karşı /probe çalıştırın ve istediğiniz her veri öğesinin id değerini not edin. ID'ler agent'ı yapılandıran kişi tarafından seçilir; bu yüzden kurulumlar arasında farklılık gösterir.
2. Adım: MTConnect'ten MQTT'ye Köprü
Köprü veri öğesi ID'lerini topic adlarına çözümler, başlangıç durumu için /current okur, ardından /sample üzerinde döngüye girer. Agent yeniden başlatmalarını (yeni bir instanceId) ve tampon taşmalarını (firstSequence değerinden eski bir from) algılar ve iki durumda da yeniden senkronize olur.
# mtconnect_mqtt_bridge.py - bir MTConnect agent'ını izle ve gözlemleri MQTT'ye yayımla
import json, logging, time, uuid
import xml.etree.ElementTree as ET
import paho.mqtt.client as mqtt
import requests
logging.basicConfig(level=logging.INFO)
log = logging.getLogger("mtc")
AGENT = "http://localhost:5000"
TOPIC_ROOT = "connectmq/demo/f40b/shop1/cnc" # kendi rastgele id'niz
INTERVAL = 1.0 # /sample istekleri arasındaki saniye
MQTT_HOST, MQTT_PORT = "broker.connectmq.com", 1883 # üretim: TLS ile 8883
MQTT_USER, MQTT_PASS = None, None # üretim: "YOUR_USERNAME", "YOUR_PASSWORD"
CLIENT_ID = f"mtc-bridge-{uuid.uuid4().hex[:8]}" # üretim: "YOUR_CLIENT_ID"
# dataItemId -> topic yaprağı. ID'leri agent'ınızın /probe çıktısından alın.
WATCH = {
"avail": "availability",
"exec": "execution",
"mode": "controller_mode",
"program": "program",
"pc": "part_count",
"Sspeed": "spindle_speed",
"logic_cond": "logic_condition",
}
CONDITION_TAGS = {"Normal", "Warning", "Fault", "Unavailable"}
def local(tag):
"""Sürümlü MTConnect XML namespace'ini etiket adından ayıkla."""
return tag.rsplit("}", 1)[-1]
def fetch(path):
r = requests.get(f"{AGENT}{path}", timeout=10)
r.raise_for_status()
return ET.fromstring(r.content)
def parse(root):
header = next(e for e in root.iter() if local(e.tag) == "Header")
observations = []
for stream in root.iter():
if local(stream.tag) != "DeviceStream":
continue
device = stream.get("name")
for el in stream.iter():
item_id = el.get("dataItemId")
if item_id is None:
continue
tag = local(el.tag)
if tag in CONDITION_TAGS:
value = {"level": tag, "native_code": el.get("nativeCode"), "text": (el.text or "").strip()}
else:
value = (el.text or "").strip()
observations.append({
"device": device, "id": item_id, "value": value,
"ts": el.get("timestamp"), "seq": int(el.get("sequence", 0)),
})
observations.sort(key=lambda o: o["seq"])
return header, observations
def coerce(value):
if isinstance(value, dict) or value == "UNAVAILABLE":
return value
try:
return float(value) if "." in value else int(value)
except ValueError:
return value
def publish(mq, obs):
leaf = WATCH.get(obs["id"])
if not leaf:
return
topic = f"{TOPIC_ROOT}/{obs['device']}/{leaf}"
payload = {"value": coerce(obs["value"]), "ts": obs["ts"], "seq": obs["seq"]}
mq.publish(topic, json.dumps(payload), qos=1, retain=True)
log.info("%s = %s", topic, payload["value"])
def main():
mq = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID)
if MQTT_USER:
mq.username_pw_set(MQTT_USER, MQTT_PASS)
mq.tls_set()
mq.will_set(f"{TOPIC_ROOT}/bridge", "offline", qos=1, retain=True)
mq.on_connect = lambda c, u, f, rc, p: c.publish(f"{TOPIC_ROOT}/bridge", "online", qos=1, retain=True)
mq.connect(MQTT_HOST, MQTT_PORT, keepalive=30)
mq.loop_start()
instance, next_seq = None, None
while True:
try:
if next_seq is None: # /current'tan (yeniden) senkronize ol
header, obs = parse(fetch("/current"))
instance, next_seq = header.get("instanceId"), int(header.get("nextSequence"))
for o in obs:
publish(mq, o)
log.info("synchronised: instance %s, next %s", instance, next_seq)
else:
header, obs = parse(fetch(f"/sample?from={next_seq}&count=1000"))
if header.get("instanceId") != instance:
log.warning("agent restarted, resynchronising")
next_seq = None
continue
for o in obs:
publish(mq, o)
next_seq = int(header.get("nextSequence"))
except (ET.ParseError, StopIteration, TypeError) as exc:
# Hatalı XML veya normal Header içermeyen bir MTConnectError belgesi.
log.error("unexpected agent response: %s", exc)
next_seq = None
except requests.RequestException as exc:
# Ağ hataları veya aralık dışı bir "from" gibi bir hata durumu.
log.error("agent request failed: %s", exc)
next_seq = None
time.sleep(5)
time.sleep(INTERVAL)
if __name__ == "__main__":
main()
Tasarımla ilgili birkaç nokta:
- Sıra numarasına göre sıralama, XML gözlemleri bileşene göre gruplasa bile gözlemlerin agent'ın kaydettiği sırada yayımlanmasını garanti eder.
- Retained message'lar, vardiya ortasında açılan bir panonun güncel çalışma durumunu, programı ve parça sayısını anında göstermesi anlamına gelir.
- Condition'lar, seviye ve yerel alarm kodu içeren nesnelere dönüşür; böylece tüketiciler bir uyarıyı bir arızadan ayırt edebilir.
- Hatada yeniden senkronizasyon güvenlidir:
/currenten son durumu yeniden yayımlar, dolayısıyla birkaç ara örnek kaybolsa bile tüketiciler sonunda doğru duruma ulaşır.
3. Adım: Çalıştırın ve İzleyin
python mtconnect_mqtt_bridge.py
mosquitto_sub -h broker.connectmq.com -p 1883 -i mtc-viewer-f40b -t "connectmq/demo/f40b/#" -v
connectmq/demo/f40b/shop1/cnc/VMC-3Axis/execution {"value": "ACTIVE", "ts": "2026-10-16T11:02:44.501Z", "seq": 90213}
connectmq/demo/f40b/shop1/cnc/VMC-3Axis/spindle_speed {"value": 11980.0, "ts": "2026-10-16T11:02:44.612Z", "seq": 90215}
Public broker client başına saniyede on mesaja izin verir; bu, durum olayları için fazlasıyla yeterlidir ama eksen konumları gibi hızlı değişen örneklerle aşılabilir. WATCH listesini odaklı tutun veya report by exception yazımızda açıklandığı gibi örnekler için bir deadband ekleyin.
Bir Makine Durum Panosu Oluşturmak
Çalışma durumu, mod ve erişilebilirlik MQTT'de olduğunda temel bir kullanım görünümü, abone olup durum değişikliklerinin süresini ölçmekten ibarettir. Yaygın, sadeleştirilmiş bir eşleme:
- Çalışıyor: availability AVAILABLE, mode AUTOMATIC, execution ACTIVE.
- Boşta: erişilebilir, execution READY veya STOPPED.
- Kesintiye uğramış: execution INTERRUPTED, FEED_HOLD veya OPTIONAL_STOP; çoğu zaman operatör beklemesi.
- Alarm: Fault seviyesindeki herhangi bir condition.
- Çevrim dışı: availability UNAVAILABLE veya köprü durum topic'i
offlinegösteriyor.
MQTT destekli herhangi bir pano aracı bu durumları hesaplayabilir; aynı topic'lere abone olan bir historian da size vardiya ve iş raporları sağlar. MQTT historian rehberimiz akışın saklanmasını ele alıyor.
Üretim Notları
- Ağ konumlandırması. Köprüyü atölye ağında agent'ın yanında çalıştırın ve broker'a 8883 portu üzerinden dışa doğru bağlanmasına izin verin. Agent'ın HTTP portunu internete açmayın.
- Birden fazla makine. Tek bir agent çoğu zaman birkaç cihaza hizmet verir; köprü birden fazla
DeviceStreamöğesini zaten işler ve her cihazı kendi dalına koyar. - Saat kalitesi. MTConnect zaman damgaları agent'tan veya adapter'dan gelir. Bu sunucuların NTP kullandığından emin olun, aksi hâlde süre hesaplamaları kayar.
- Özel broker. Public broker herkese açıktır; bu yüzden gerçek makine verisi özel bir yönetilen MQTT broker'a aittir. ConnectMQ üzerinde cihaz görünümü makinelerinizi ISA-95 seviyesine göre gruplar; 3B dijital ikiz demosu da güvenli WebSocket üzerinde kurabileceğiniz türden canlı CNC görselleştirmesini gösterir.
Makine verisinin, PLC'lerin ve gateway'lerin nasıl bir araya geldiğinin tam resmi için endüstriyel IoT MQTT rehberini okuyun.
ConnectMQ ile Başlayın
CNC verinizi dakikalar içinde özel bir broker'a taşıyın. app.connectmq.com adresinde kaydolun, ücretsiz Serverless planı seçin (kredi kartı gerekmez), bir broker oluşturun ve oluşturulan kullanıcı adını, şifreyi ve client ID'yi köprüye yapıştırın. Ardından ConnectMQ portalında, örneğin iş mili devri için bir eşik uyarı kuralı tanımlayın ve makine çalışırken uyarı günlüğünü izleyin.
Sık Sorulan Sorular
MTConnect MQTT'yi yerel olarak destekliyor mu?
MTConnect standardı bir HTTP arayüzü etrafında kurulmuştur, ancak referans agent'ın yeni sürümleri gözlemleri bir broker'a yayımlayan bir MQTT sink içerir. Yukarıdaki gibi küçük bir köprü her agent sürümüyle çalışır.
Neden /current'ı sorgulamak yerine /sample kullanmalı?
/current'ı sorgulamak yalnızca son değeri gösterir ve sorgulamalar arasındaki kısa durumları kaçırabilir. nextSequence'tan itibaren /sample'ı izlemek her gözlemi sırasıyla döndürür; böylece kısa alarmlar veya duruşlar kaybolmaz.
MTConnect'te UNAVAILABLE ne anlama gelir?
Agent'ın değeri şu anda bilmediği anlamına gelir; genellikle makine veya adapter bağlı olmadığı için. Panoların makineyi çevrim dışı gösterebilmesi için onu olduğu gibi yayımlayın.
MTConnect üzerinden bir CNC'ye yazabilir miyim?
Hayır. MTConnect, izleme için salt okunur bir standarttır. Makineye komut göndermek, kontrol üreticisinin kendi arayüzlerini gerektirir.



