DTDL (Digital Twin Definition Language), bir dijital ikizin nelerden oluştuğunu tanımlamanın JSON tabanlı bir yoludur: yaydığı telemetri, tuttuğu özellikler, kabul ettiği komutlar ve diğer ikizlerle nasıl ilişkili olduğu. Bu makalede DTDL modellerinin nasıl yapılandırıldığını öğrenecek, eksiksiz bir örneği inceleyecek ve cihazların ve ikiz uygulamalarının tek bir net sözleşmeyi paylaşması için bu modeli MQTT topic'lerine nasıl eşleyeceğinizi göreceksiniz.
Modellerin genel resimde nereye oturduğunu görmek için dijital ikiz teknolojisi rehberimize bakın.
DTDL Nedir ve Neden Var
On ekip birbirinden bağımsız ikizler oluşturduğunda, her biri "bu pompanın dakikada litre cinsinden bir debisi ve bir başlatma komutu var" demenin kendi yolunu icat eder. DTDL bu tanımı standartlaştırır. Microsoft tarafından yayımlanan, JSON-LD tabanlı, Azure Digital Twins ve IoT Plug and Play tarafından kullanılan açık bir dildir; ancak dilin kendisinde sizi tek bir buluta bağlayan hiçbir şey yoktur. Bir DTDL dosyası yalnızca bir varlık türünü tanımlayan bir belgedir; onu kod üretmek, payload'ları doğrulamak, arayüz oluşturmak veya topic sözleşmelerini belgelemek için kullanabilirsiniz.
Dil birkaç sürümden geçmiştir; güncel sürüm DTDL v3'tür, mevcut projelerde ise v2 hâlâ yaygın olarak görülür. Resmi spesifikasyon DTDL GitHub deposunda bulunur.
Bir DTDL Modelinin Yapı Taşları
DTDL'deki her şey bir Interface (arayüz) içinde tanımlanır. Bir arayüzün bir tanımlayıcısı ve her biri aşağıdaki öğe türlerinden biri olan bir içerik listesi vardır:
| Öğe | Neyi tanımlar | Örnek |
|---|---|---|
| Telemetry | Durum olarak saklanmayan bir ölçüm akışı | Saniyede bir sıcaklık |
| Property | İsteğe bağlı olarak yazılabilir bir durum değeri | Firmware sürümü, ayar noktası |
| Command | İkizden yapması istenebilecek bir işlem | Başlat, durdur, sayacı sıfırla |
| Component | Başka bir arayüzün bu arayüz içinde yeniden kullanılması | Bir motor arayüzü içeren bir pompa |
| Relationship | Başka bir ikize bağlantı | Pompa isPartOf istasyon |
Her modelin ve öğenin dtmi:com:example:Pump;1 gibi bir DTMI'si (Digital Twin Model Identifier) vardır. Sondaki sayı sürümdür. Bir modeli uyumsuz bir şekilde değiştirdiğinizde, onu yerinde düzenlemek yerine sürümü artırırsınız.
Telemetri ve Özellik Farkı
Ekiplerin en sık yanlış yaptığı ayrım budur. Telemetri bir olay akışıdır: her örnek sizin için önemlidir ve ikiz platformu tarafından saklanan bir "güncel değer" yoktur. Özellikler ise durumdur: ikizin her zaman bir güncel değeri vardır ve yazılabilir bir özellik bulut tarafından ayarlanabilir (istenen değer), cihaz da gerçek değerini geri bildirir.
Temel kural: yeni bir görüntüleyicinin onu yüklemede hemen görmesi gerekiyorsa bir özelliktir; yalnızca zaman içindeki bir seri olarak önemliyse telemetridir.
Eksiksiz Bir DTDL Örneği
İşte bir santrifüj pompa için DTDL v3 arayüzü:
{
"@context": "dtmi:dtdl:context;3",
"@id": "dtmi:com:example:Pump;1",
"@type": "Interface",
"displayName": "Centrifugal Pump",
"contents": [
{
"@type": ["Telemetry", "VolumeFlowRate"],
"name": "flow",
"schema": "double",
"unit": "litrePerSecond"
},
{
"@type": ["Telemetry", "Pressure"],
"name": "dischargePressure",
"schema": "double",
"unit": "bar"
},
{
"@type": "Property",
"name": "running",
"schema": "boolean"
},
{
"@type": "Property",
"name": "speedSetpoint",
"schema": "double",
"writable": true
},
{
"@type": "Property",
"name": "firmwareVersion",
"schema": "string"
},
{
"@type": "Command",
"name": "resetRunHours"
},
{
"@type": "Relationship",
"name": "isPartOf",
"target": "dtmi:com:example:PumpingStation;1"
}
]
}
VolumeFlowRate gibi semantik türler ve litrePerSecond gibi birimler, DTDL nicel türler (quantitative types) uzantısından gelir. Araçların birimleri tahmin etmeden doğru şekilde göstermesini sağlarlar. Hedeflediğiniz sürümde geçerli olan semantik türlerin ve birimlerin tam listesi için spesifikasyonu kontrol edin.
DTDL'yi MQTT Topic'lerine Eşlemek
DTDL bir ikizin neler içerdiğini tanımlar; verinin nasıl taşındığını söylemez. MQTT doğal bir taşıma katmanıdır ve temiz bir eşleme DTDL modelinizi bir topic sözleşmesine dönüştürür. Pratik bir kural seti:
| DTDL öğesi | MQTT topic | Retained | QoS |
|---|---|---|---|
Telemetri flow |
<asset>/telemetry (tüm telemetri alanlarını içeren JSON) |
Hayır | 0 |
| Özellik (salt okunur) | <asset>/properties/reported |
Evet | 1 |
| Yazılabilir özelliğin istenen değeri | <asset>/properties/desired |
Evet | 1 |
Komut resetRunHours |
<asset>/commands/resetRunHours |
Hayır | 1 |
| Komut yanıtı | <asset>/commands/resetRunHours/response |
Hayır | 1 |
| İlişki | Kablo üzerinde değil, modelde veya kayıtta saklanır | Yok | Yok |
<asset>, acme/site1/water/station3/pump2 gibi bir ISA-95 yolu olduğunda, bir görüntüleyici acme/site1/water/# adresine abone olabilir ve modelden yola çıkarak her mesajı nasıl yorumlayacağını bilir.
Telemetriyi neden varlık başına tek bir mesajda birleştirmeli? Her telemetri alanı için ayrı bir topic yayınlamak, bilgi eklemeden mesaj sayısını katlar ve çoğu tüketici tüm alanları aynı zaman damgasıyla ister. Özellikler retained mesajlardan faydalanır; böylece ikiz görüntüleyicileri güncel durumu anında alır. Retained MQTT ile dijital ikiz eğitimi bunu uygulamada gösterir.
Payload'ları Bir DTDL Modeline Göre Doğrulamak
Bir modeliniz olduğunda onu kullanın. Küçük bir Python kontrolü, arayüzle eşleşmeyen telemetriyi geçmişinizi kirletmeden önce reddedebilir:
import json
import paho.mqtt.client as mqtt
with open("pump.json", encoding="utf-8") as f:
model = json.load(f)
TYPE_MAP = {"double": (int, float), "boolean": bool, "string": str, "integer": int}
telemetry = {
c["name"]: c["schema"]
for c in model["contents"]
if "Telemetry" in (c["@type"] if isinstance(c["@type"], list) else [c["@type"]])
}
def on_connect(client, userdata, flags, reason_code, properties):
client.subscribe("connectmq/demo/d41f/+/+/+/+/telemetry")
def on_message(client, userdata, msg):
data = json.loads(msg.payload)
for name, schema in telemetry.items():
if name not in data:
print(f"{msg.topic}: missing {name}")
elif not isinstance(data[name], TYPE_MAP[schema]):
print(f"{msg.topic}: {name} should be {schema}")
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="dtdl-validator-d41f")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 1883)
client.loop_forever()
Herkese açık MQTT test broker'ına örnek bir mesaj yayınlayarak test edin:
mosquitto_pub -h broker.connectmq.com -p 1883 -i dtdl-pub-d41f \
-t "connectmq/demo/d41f/acme/site1/station3/pump2/telemetry" \
-m '{"flow": 12.4, "dischargePressure": "4.1"}'
Doğrulayıcı, dischargePressure değerini double yerine string olduğu için işaretler; bu, aksi halde haftalar sonra bozuk bir grafik olarak ortaya çıkacak türden bir hatadır.
DTDL Modelleme Kontrol Listesi
- Varlık örneği başına değil, varlık türü başına bir arayüz.
- Akışlar için telemetri, durum için özellikler, aksiyonlar için komutlar.
- Motorlar veya sensörler gibi yeniden kullanılabilir parçalar için bileşenler kullanın.
- Mümkün olan her yerde birimleri semantik türler üzerinden ekleyin.
- DTMI'leri sürümleyin ve yayımlanmış bir sürümü asla bozmayın.
- MQTT eşlemesini modelin yanında, aynı depoda belgeleyin.
- Payload'ları yalnızca arayüzde değil, alım noktasında doğrulayın.
DTDL'nin Diğer İkiz Modelleriyle Karşılaştırması
DTDL tek seçenek değildir. Endüstri 4.0 dünyasından gelen Asset Administration Shell, endüstriyel varlıklar için standartlaştırılmış alt modellere odaklanır ve Avrupa üretim sektöründe yaygındır; bkz. Asset Administration Shell nedir. Eclipse Ditto, öznitelikler ve özellikler içeren kendi JSON "thing" yapısını kullanır. Pek çok ekip de varlık türü başına sade bir JSON Schema kullanır. En önemli olan, tek bir açık modele ve taşıma katmanına belgelenmiş bir eşlemeye sahip olmaktır; DTDL'nin iyi oynadığı rol de budur. Model katmanının mesajlaşma, durum ve görselleştirme katmanlarının yanında nasıl konumlandığı için dijital ikiz mimarisi yazısına bakın.
DTDL Tabanlı İkizinizi ConnectMQ Üzerinde Çalıştırmak
DTDL sözleşmeyi tanımlar; yine de güvenilir bir taşıma katmanına ihtiyacınız vardır. ConnectMQ; özellikler için retained mesajlar, cihazlar için 8883'te TLS ve tarayıcı ikizleri için 8084'te WSS ile MQTT 3.1.1 ve 5.0'ı destekleyen yönetilen bir MQTT broker'dır. Model doğrulama, kod üretimi ve ikiz grafikleri, ConnectMQ'ya normal MQTT istemcileri olarak bağlanan kendi araçlarınızda çalışır. Kredi kartı gerekmeden app.connectmq.com adresinde ücretsiz Serverless planla bir broker oluşturun ve DTDL yapısındaki ilk telemetrinizi dakikalar içinde yayınlayın.
Sık Sorulan Sorular
DTDL yalnızca Azure için mi?
Hayır. DTDL açık, JSON-LD tabanlı bir dildir. Azure Digital Twins onu yerel olarak kullanır, ancak DTDL modellerini herhangi bir broker üzerindeki MQTT dahil her taşıma katmanıyla kullanabilirsiniz.
DTDL özelliği ile telemetri arasındaki fark nedir?
Özellik, güncel bir değeri olan ve isteğe bağlı olarak yazılabilen bir durumdur; telemetri ise her örneğin önemli olduğu ancak güncel değerin saklanmadığı bir ölçüm akışıdır.
DTDL komutlarını MQTT üzerinden nasıl temsil ederim?
Komutu correlation ID ile QoS 1'de retained olmayan bir komut topic'ine yayınlayın ve cihazın sonucu bir yanıt topic'ine yayınlamasını sağlayın. MQTT 5'in response topic ve correlation data özellikleri bunu doğrudan destekler.
Hangi DTDL sürümünü kullanmalıyım?
Bağımlı olduğunuz bir araç yalnızca v2'yi desteklemiyorsa, yeni projeler için DTDL v3 kullanın.



