Parsování a ověřování modelů pomocí knihovny analyzátoru DTDL
Tento článek popisuje, jak parsovat a ověřovat modely Azure Digital Twins pomocí knihovny analyzátoru .NET.
Modely ve službě Azure Digital Twins se definují pomocí jazyka DTDL (Digital Twins Definition Language) založeného na formátu JSON.LD.
Po vytvoření modelu se doporučuje před jejich nahráním do instance Služby Azure Digital Twins ověřit modely offline.
Pro účely ověření modelů se na NuGetu poskytuje knihovna analyzátoru DTDL na straně klienta .NET: DTDLParser. Knihovnu analyzátoru můžete použít přímo v kódu jazyka C#. Ukázkové použití analyzátoru můžete zobrazit také v souboru DTDLParserResolveSample na GitHubu.
Informace o knihovně analyzátoru .NET
Knihovna DTDLParser poskytuje přístup modelu k definicím DTDL, v podstatě funguje jako ekvivalent reflexe jazyka C# pro DTDL. Tuto knihovnu je možné používat nezávisle na jakékoli sadě Azure Digital Twins SDK, zejména pro ověřování DTDL ve vizuálu nebo textovém editoru. Před pokusem o nahrání do služby je užitečné zajistit platnost definičních souborů modelu.
Pokud chcete použít knihovnu analyzátoru, poskytnete ji sadě dokumentů DTDL. Obvykle byste tyto dokumenty modelu načetli ze služby, ale mohli byste je mít také k dispozici místně, pokud byl váš klient zodpovědný za jejich nahrání do služby na prvním místě.
Tady je obecný pracovní postup pro použití analyzátoru:
- Načtěte některé nebo všechny dokumenty DTDL ze služby.
- Předejte vrácené dokumenty DTDL v paměti analyzátoru.
- Analyzátor ověří sadu předaných dokumentů a vrátí podrobné informace o chybě. Tato schopnost je užitečná ve scénářích editoru.
- Pomocí rozhraní API analyzátoru můžete pokračovat v analýze modelů obsažených v sadě dokumentů.
Mezi možnosti analyzátoru patří:
- Získejte všechna implementovaná rozhraní modelu (obsah oddílu rozhraní
extends
). - Získejte všechny vlastnosti, telemetrii, příkazy, komponenty a relace deklarované v modelu. Tento příkaz také získá všechna metadata zahrnutá v těchto definicích a bere v úvahu dědičnost (
extends
oddíly). - Získejte všechny komplexní definice modelu.
- Určete, jestli je model možné přiřadit z jiného modelu.
Poznámka:
Zařízení ioT technologie Plug and Play používají k popisu svých funkcí malou syntaxi variantu. Tato varianta syntaxe je séanticky kompatibilní podmnožinou DTDL, která se používá ve službě Azure Digital Twins. Při použití knihovny analyzátoru nemusíte vědět, která varianta syntaxe byla použita k vytvoření DTDL pro vaše digitální dvojče. Analyzátor bude ve výchozím nastavení vždy vracet stejný model pro syntaxi ioT technologie Plug and Play i Azure Digital Twins.
Kód s využitím knihovny analyzátoru
Knihovnu analyzátoru můžete použít přímo, například ověřování modelů ve vaší vlastní aplikaci nebo generování dynamického, modelem řízeného uživatelského rozhraní, řídicích panelů a sestav.
Pokud chcete podporovat níže uvedený příklad kódu analyzátoru, zvažte několik modelů definovaných v instanci Služby Azure Digital Twins:
[
{
"@context": "dtmi:dtdl:context;3",
"@id": "dtmi:com:contoso:coffeeMaker;1",
"@type": "Interface",
"contents": [
{
"@type": "Component",
"name": "coffeeMaker",
"schema": "dtmi:com:contoso:coffeeMakerInterface;1"
}
]
},
{
"@context": "dtmi:dtdl:context;3",
"@id": "dtmi:com:contoso:coffeeMakerInterface;1",
"@type": "Interface",
"contents": [
{
"@type": "Property",
"name": "waterTemp",
"schema": "double"
}
]
},
{
"@context": "dtmi:dtdl:context;3",
"@id": "dtmi:com:contoso:coffeeBar;1",
"@type": "Interface",
"contents": [
{
"@type": "Relationship",
"name": "foo",
"target": "dtmi:com:contoso:coffeeMaker;1"
},
{
"@type": "Property",
"name": "capacity",
"schema": "integer"
}
]
}
]
Následující kód ukazuje příklad použití knihovny analyzátoru k vyjádření těchto definic v jazyce C#:
using Azure;
using Azure.DigitalTwins.Core;
using DTDLParser;
using DTDLParser.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DigitalTwins_Samples
{
public static class ListExtensions
{
public static async IAsyncEnumerable<T> AsAsyncEnumerable<T>(this IEnumerable<T> input)
{
foreach (var value in input)
{
yield return value;
}
await Task.Yield();
}
}
public class ParseModelsSample
{
public async Task ParseDemoAsync(DigitalTwinsClient client)
{
try
{
AsyncPageable<DigitalTwinsModelData> mdata = client.GetModelsAsync(new GetModelsOptions { IncludeModelDefinition = true });
var models = new List<string>();
await foreach (DigitalTwinsModelData md in mdata)
models.Add(md.DtdlModel);
var parser = new ModelParser();
IReadOnlyDictionary<Dtmi, DTEntityInfo> dtdlOM = await parser.ParseAsync(models.AsAsyncEnumerable());
var interfaces = new List<DTInterfaceInfo>();
IEnumerable<DTInterfaceInfo> ifenum =
from entity in dtdlOM.Values
where entity.EntityKind == DTEntityKind.Interface
select entity as DTInterfaceInfo;
interfaces.AddRange(ifenum);
foreach (DTInterfaceInfo dtif in interfaces)
{
PrintInterfaceContent(dtif, dtdlOM);
}
}
catch (RequestFailedException ex)
{
Console.WriteLine($"Failed due to {ex}");
throw;
}
}
public void PrintInterfaceContent(DTInterfaceInfo dtif, IReadOnlyDictionary<Dtmi, DTEntityInfo> dtdlOM, int indent = 0)
{
var sb = new StringBuilder();
for (int i = 0; i < indent; i++) sb.Append(" ");
Console.WriteLine($"{sb}Interface: {dtif.Id} | {dtif.DisplayName}");
IReadOnlyDictionary<string, DTContentInfo> contents = dtif.Contents;
foreach (DTContentInfo item in contents.Values)
{
switch (item.EntityKind)
{
case DTEntityKind.Property:
DTPropertyInfo pi = item as DTPropertyInfo;
Console.WriteLine($"{sb}--Property: {pi.Name} with schema {pi.Schema}");
break;
case DTEntityKind.Relationship:
DTRelationshipInfo ri = item as DTRelationshipInfo;
Console.WriteLine($"{sb}--Relationship: {ri.Name} with target {ri.Target}");
break;
case DTEntityKind.Telemetry:
DTTelemetryInfo ti = item as DTTelemetryInfo;
Console.WriteLine($"{sb}--Telemetry: {ti.Name} with schema {ti.Schema}");
break;
case DTEntityKind.Component:
DTComponentInfo ci = item as DTComponentInfo;
Console.WriteLine($"{sb}--Component: {ci.Id} | {ci.Name}");
DTInterfaceInfo component = ci.Schema;
PrintInterfaceContent(component, dtdlOM, indent + 1);
break;
}
}
}
}
}
Další kroky
Jakmile dokončíte psaní modelů, podívejte se, jak je nahrát (a provádět další operace správy) pomocí rozhraní API modelů Azure Digital Twins: