Hantera digitala tvillingar
Entiteter i din miljö representeras av digitala tvillingar. Att hantera dina digitala tvillingar kan vara att skapa, ändra och ta bort.
Den här artikeln fokuserar på att hantera digitala tvillingar. Information om hur du arbetar med relationer och tvillingdiagrammet som helhet finns i Hantera tvillingdiagrammet och relationerna.
Dricks
Alla SDK-funktioner finns i synkrona och asynkrona versioner.
Förutsättningar
För att arbeta med Azure Digital Twins i den här artikeln behöver du en Azure Digital Twins-instans och de behörigheter som krävs för att använda den. Om du redan har konfigurerat en Azure Digital Twins-instans kan du använda den instansen och gå vidare till nästa avsnitt. Annars följer du anvisningarna i Konfigurera en instans och autentisering. Anvisningarna innehåller information som hjälper dig att kontrollera att du har slutfört varje steg.
När du har konfigurerat instansen antecknar du instansens värdnamn. Du hittar värdnamnet i Azure-portalen.
Utvecklargränssnitt
Den här artikeln beskriver hur du slutför olika hanteringsåtgärder med hjälp av .NET (C#) SDK. Du kan också skapa samma hanteringsanrop med de andra språk-SDK:erna som beskrivs i Azure Digital Twins-API:er och SDK:er.
Andra utvecklargränssnitt som kan användas för att slutföra dessa åtgärder är:
Visualisering
Azure Digital Twins Explorer är ett visuellt verktyg för att utforska data i ditt Azure Digital Twins-diagram. Du kan använda utforskaren för att visa, fråga och redigera dina modeller, tvillingar och relationer.
Mer information om Azure Digital Twins Explorer-verktyget finns i Azure Digital Twins Explorer. Detaljerade anvisningar om hur du använder dess funktioner finns i Använda Azure Digital Twins Explorer.
Så här ser visualiseringen ut:
Skapa en digital tvilling
Om du vill skapa en tvilling använder CreateOrReplaceDigitalTwinAsync()
du metoden på tjänstklienten så här:
await client.CreateOrReplaceDigitalTwinAsync<BasicDigitalTwin>(twinId, initData);
Om du vill skapa en digital tvilling måste du ange:
- Ett ID-värde som du vill tilldela till den digitala tvillingen (du definierar det ID:t när tvillingen skapas)
- Den modell som du vill använda
- All önskad initiering av tvillingdata, inklusive...
- Egenskaper (initiering valfritt): Du kan ange inledande värden för egenskaperna för den digitala tvillingen om du vill. Egenskaper behandlas som valfria och kan anges senare, men observera att de inte visas som en del av en tvilling förrän de har angetts.
- Komponenter (initiering krävs om de finns på en tvilling): Om din tvilling innehåller några komponenter måste dessa initieras när tvillingen skapas. De kan vara tomma objekt, men själva komponenterna måste finnas.
Modellen och eventuella initiala egenskapsvärden tillhandahålls via parametern initData
, som är en JSON-sträng som innehåller relevanta data. Om du vill ha mer information om hur du strukturerar det här objektet fortsätter du till nästa avsnitt.
Dricks
När du har skapat eller uppdaterat en tvilling kan det finnas en svarstid på upp till 10 sekunder innan ändringarna återspeglas i frågor. GetDigitalTwin
API:et (som beskrivs senare i den här artikeln) upplever inte den här fördröjningen, så om du behöver ett omedelbart svar använder du API-anropet i stället för att fråga för att se dina nyligen skapade tvillingar.
Initiera modell och egenskaper
Du kan initiera egenskaperna för en tvilling när tvillingen skapas.
API:et för tvillingskapande accepterar ett objekt som serialiseras till en giltig JSON-beskrivning av tvillingegenskaperna. En beskrivning av JSON-formatet för en tvilling finns i Digital twins and the twin graph (Digitala tvillingar och tvillingdiagrammet ).
Först kan du skapa ett dataobjekt som representerar tvillingen och dess egenskapsdata. Du kan skapa ett parameterobjekt antingen manuellt eller med hjälp av en tillhandahållen hjälpklass. Här är ett exempel på var och en.
Skapa tvillingar med hjälp av manuellt skapade data
Utan att använda några anpassade hjälpklasser kan du representera en tvillings egenskaper i en Dictionary<string, object>
, där string
är namnet på egenskapen och object
är ett objekt som representerar egenskapen och dess värde.
// Define a custom model type for the twin to be created
internal class CustomDigitalTwin
{
[JsonPropertyName(DigitalTwinsJsonPropertyNames.DigitalTwinId)]
public string Id { get; set; }
[JsonPropertyName(DigitalTwinsJsonPropertyNames.DigitalTwinETag)]
public string ETag { get; set; }
[JsonPropertyName("temperature")]
public double Temperature { get; set; }
[JsonPropertyName("humidity")]
public double Humidity{ get; set; }
}
// Initialize properties and create the twin
public class TwinOperationsCreateTwin
{
public async Task CreateTwinAsync(DigitalTwinsClient client)
{
// Initialize the twin properties
var myTwin = new CustomDigitalTwin
{
Temperature = 25.0,
Humidity = 50.0,
};
// Create the twin
const string twinId = "<twin-ID>";
Response<CustomDigitalTwin> response = await client.CreateOrReplaceDigitalTwinAsync(twinId, myTwin);
Console.WriteLine($"Temperature value: {response.Value.Temperature}");
}
}
Skapa tvillingar med hjälpklassen
Med hjälpklassen BasicDigitalTwin
för kan du lagra egenskapsfält i ett "tvilling"-objekt direkt. Du kanske fortfarande vill skapa listan med egenskaper med hjälp av en Dictionary<string, object>
, som sedan kan läggas till i tvillingobjektet som dess CustomProperties
direkt.
string twinId = "myTwinID";
var initData = new BasicDigitalTwin
{
Id = twinId,
Metadata = { ModelId = "dtmi:example:Room;1" },
// Initialize properties
Contents =
{
{ "Temperature", 25.0 },
{ "Humidity", 50.0 },
},
};
await client.CreateOrReplaceDigitalTwinAsync<BasicDigitalTwin>(twinId, initData);
Kommentar
BasicDigitalTwin
objekt levereras med ett Id
fält. Du kan lämna det här fältet tomt, men om du lägger till ett ID-värde måste det matcha ID-parametern som skickas till anropet CreateOrReplaceDigitalTwinAsync()
. Till exempel:
twin.Id = "myRoomId";
Skapa tvillingar i bulk med API:et Importera jobb
Du kan använda API:et Importera jobb för att skapa många tvillingar samtidigt i ett enda API-anrop. Den här metoden kräver användning av Azure Blob Storage och skrivbehörigheter i din Azure Digital Twins-instans för tvillingar och massjobb.
Dricks
API:et Importera jobb gör också att modeller och relationer kan importeras i samma anrop för att skapa alla delar av ett diagram samtidigt. Mer information om den här processen finns i Ladda upp modeller, tvillingar och relationer i bulk med API:et Importera jobb.
Om du vill importera tvillingar i grupp måste du strukturera dina tvillingar (och andra resurser som ingår i massimportjobbet) som en NDJSON-fil . Avsnittet Twins
kommer efter avsnittet Models
(och före avsnittet Relationships
). Tvillingar som definierats i filen kan referera till modeller som antingen definieras i den här filen eller som redan finns i instansen, och de kan också inkludera initiering av tvillingens egenskaper.
Du kan visa en exempelimportfil och ett exempelprojekt för att skapa dessa filer i introduktionen för API:et Importera jobb.
Därefter måste filen laddas upp till en tilläggsblob i Azure Blob Storage. Anvisningar om hur du skapar en Azure Storage-container finns i Skapa en container. Ladda sedan upp filen med den uppladdningsmetod du föredrar (vissa alternativ är Kommandot AzCopy, Azure CLI eller Azure-portalen).
När NDJSON-filen har laddats upp till containern hämtar du dess URL i blobcontainern. Du använder det här värdet senare i brödtexten i API-anropet för massimport.
Här är en skärmbild som visar URL-värdet för en blobfil i Azure-portalen:
Sedan kan filen användas i ett API-anrop för importjobb. Du anger bloblagrings-URL:en för indatafilen och en ny bloblagrings-URL för att ange var du vill att utdataloggen ska lagras när tjänsten har skapat den.
Hämta data för en digital tvilling
Du kan komma åt information om alla digitala tvillingar genom att anropa GetDigitalTwin()
metoden så här:
Response<BasicDigitalTwin> twinResponse = await client.GetDigitalTwinAsync<BasicDigitalTwin>(twinId);
twin = twinResponse.Value;
Det här anropet returnerar tvillingdata som en starkt typ av objekttyp, till exempel BasicDigitalTwin
. BasicDigitalTwin
är en serialiseringshjälpklass som ingår i SDK:et, som returnerar metadata och egenskaper för kärntvillingar i preparsed-format. Du kan alltid deserialisera tvillingdata med hjälp av det JSON-bibliotek som du väljer, t.ex System.Text.Json
. eller Newtonsoft.Json
. För grundläggande åtkomst till en tvilling kan dock hjälpklasserna göra detta enklare.
Kommentar
BasicDigitalTwin
använder System.Text.Json
attribut. För att kunna använda BasicDigitalTwin
med din DigitalTwinsClient måste du antingen initiera klienten med standardkonstruktorn eller, om du vill anpassa serialiseraralternativet , använda JsonObjectSerializer.
Hjälpklassen BasicDigitalTwin
ger dig också åtkomst till egenskaper som definierats för tvillingen via en Dictionary<string, object>
. Om du vill visa egenskaper för tvillingen kan du använda:
BasicDigitalTwin twin;
Response<BasicDigitalTwin> twinResponse = await client.GetDigitalTwinAsync<BasicDigitalTwin>(twinId);
twin = twinResponse.Value;
Console.WriteLine($"Model id: {twin.Metadata.ModelId}");
foreach (string prop in twin.Contents.Keys)
{
if (twin.Contents.TryGetValue(prop, out object value))
Console.WriteLine($"Property '{prop}': {value}");
}
Endast egenskaper som har angetts minst en gång returneras när du hämtar en tvilling med GetDigitalTwin()
metoden .
Dricks
displayName
För en tvilling är en del av dess modellmetadata, så den visas inte när data hämtas för tvillinginstansen. Om du vill se det här värdet kan du hämta det från modellen.
Information om hur du hämtar flera tvillingar med ett enda API-anrop finns i Fråge-API-exemplen i Fråga tvillingdiagrammet.
Tänk på följande modell (skriven i DTDL (Digital Twins Definition Language) som definierar en måne:
{
"@id": "dtmi:example:Moon;1",
"@type": "Interface",
"@context": "dtmi:dtdl:context;3",
"contents": [
{
"@type": "Property",
"name": "radius",
"schema": "double",
"writable": true
},
{
"@type": "Property",
"name": "mass",
"schema": "double",
"writable": true
}
]
}
Resultatet av att anropa object result = await client.GetDigitalTwinAsync("my-moon");
en tvilling av måntyp kan se ut så här:
{
"$dtId": "myMoon-001",
"$etag": "W/\"e59ce8f5-03c0-4356-aea9-249ecbdc07f9\"",
"radius": 1737.1,
"mass": 0.0734,
"$metadata": {
"$model": "dtmi:example:Moon;1",
"radius": {
"lastUpdateTime": "2022-12-06T20:00:32.8209188Z"
},
"mass": {
"lastUpdateTime": "2022-12-04T12:04:43.3859361Z"
}
}
}
De definierade egenskaperna för den digitala tvillingen returneras som egenskaper på den digitala tvillingens översta nivå. Metadata eller systeminformation som inte ingår i DTDL-definitionen returneras med ett $
prefix. Metadataegenskaperna innehåller följande värden:
$dtId
: ID:t för den digitala tvillingen i den här Azure Digital Twins-instansen$etag
: Ett HTTP-standardfält som tilldelats av webbservern. Detta uppdateras till ett nytt värde varje gång tvillingen uppdateras, vilket kan vara användbart för att avgöra om tvillingens data har uppdaterats på servern sedan en tidigare kontroll. Du kan användaIf-Match
för att utföra uppdateringar och borttagningar som bara slutförs om entitetens etag matchar den angivna etag-koden. Mer information om dessa åtgärder finns i dokumentationen för DigitalTwins Update och DigitalTwins Delete.$metadata
: En uppsättning metadataegenskaper, som kan innehålla följande:$model
, DTMI för modellen för den digitala tvillingen.lastUpdateTime
för tvillingegenskaper. Det här är en tidsstämpel som anger datum och tid då Azure Digital Twins bearbetade egenskapsuppdateringsmeddelandetsourceTime
för tvillingegenskaper. Det här är en valfri, skrivbar egenskap som representerar tidsstämpeln när egenskapsuppdateringen observerades i verkligheten.
Du kan läsa mer om fälten som finns i en digital tvilling i JSON-format för digital tvilling. Du kan läsa mer om serialiseringshjälpklasserna, till exempel BasicDigitalTwin
i Azure Digital Twins API:er och SDK:er.
Visa alla digitala tvillingar
Om du vill visa alla digitala tvillingar i din instans använder du en fråga. Du kan köra en fråga med fråge-API:er eller CLI-kommandon.
Här är brödtexten i den grundläggande frågan som returnerar en lista över alla digitala tvillingar i instansen:
SELECT * FROM DIGITALTWINS
Uppdatera en digital tvilling
Om du vill uppdatera egenskaperna för en digital tvilling skriver du den information som du vill ersätta i JSON Patch-format . En fullständig lista över JSON-korrigeringsåtgärder som kan användas, inklusive , och , finns i Åtgärder för JSON-korrigering.remove
add
replace
När du har skapat JSON Patch-dokumentet med uppdateringsinformation skickar du dokumentet till UpdateDigitalTwin()
metoden:
await client.UpdateDigitalTwinAsync(twinId, updateTwinData);
Ett enda korrigeringsanrop kan uppdatera så många egenskaper på en enda tvilling som du vill (även alla). Om du behöver uppdatera egenskaper för flera tvillingar behöver du ett separat uppdateringsanrop för varje tvilling.
Dricks
När du har skapat eller uppdaterat en tvilling kan det finnas en svarstid på upp till 10 sekunder innan ändringarna återspeglas i frågor. API:et GetDigitalTwin
(som beskrivs tidigare i den här artikeln) upplever inte den här fördröjningen, så använd API-anropet i stället för att fråga för att se dina nyligen uppdaterade tvillingar om du behöver ett omedelbart svar.
Här är ett exempel på JSON-korrigeringskod. Det här dokumentet ersätter egenskapsvärdena för massa och radie för den digitala tvilling som den tillämpas på. Det här exemplet visar JSON Patch-åtgärden replace
, som ersätter värdet för en befintlig egenskap.
[
{
"op": "replace",
"path": "/mass",
"value": 0.0799
},
{
"op": "replace",
"path": "/radius",
"value": 0.800
}
]
När du uppdaterar en tvilling från ett kodprojekt med hjälp av .NET SDK kan du skapa JSON-korrigeringar med hjälp av Azure .NET SDK:s JsonPatchDocument. Här är ett exempel på hur du skapar ett JSON Patch-dokument och använder UpdateDigitalTwin()
i projektkod.
var updateTwinData = new JsonPatchDocument();
updateTwinData.AppendAdd("/Temperature", 25.0);
updateTwinData.AppendAdd("/myComponent/Property", "Hello");
// Un-set a property
updateTwinData.AppendRemove("/Humidity");
await client.UpdateDigitalTwinAsync("myTwin", updateTwinData).ConfigureAwait(false);
Dricks
Du kan underhålla källtidsstämplar på dina digitala tvillingar genom att uppdatera $metadata.<property-name>.sourceTime
fältet med den process som beskrivs i det här avsnittet. Mer information om det här fältet och andra fält som kan skrivas på digitala tvillingar finns i JSON-format för digital tvilling.
Uppdatera underegenskaper i digitala tvillingkomponenter
Kom ihåg att en modell kan innehålla komponenter, så att den kan bestå av andra modeller.
Om du vill korrigera egenskaper i en digital tvillings komponenter kan du använda sökvägssyntaxen i JSON Patch:
[
{
"op": "replace",
"path": "/mycomponentname/mass",
"value": 0.0799
}
]
Uppdatera underegenskaper i egenskaper av objekttyp
Modeller kan innehålla egenskaper som är av en objekttyp. Dessa objekt kan ha sina egna egenskaper och du kanske vill uppdatera en av de underegenskaper som tillhör egenskapen object-type. Den här processen liknar processen för att uppdatera underegenskaper i komponenter, men kan kräva några extra steg.
Överväg en modell med en egenskap av objekttyp, ObjectProperty
. ObjectProperty
har en strängegenskap med namnet StringSubProperty
.
När en tvilling skapas med den här modellen är det inte nödvändigt att instansiera den ObjectProperty
då. Om objektegenskapen inte instansieras när tvillingen skapas finns det ingen standardsökväg som har skapats för åtkomst ObjectProperty
och dess StringSubProperty
för en korrigeringsåtgärd. Du måste lägga till sökvägen till ObjectProperty
dig själv innan du kan uppdatera dess egenskaper.
Detta kan göras med en JSON-korrigeringsåtgärd add
, så här:
[
{
"op": "add",
"path": "/ObjectProperty",
"value": {"StringSubProperty":"<string-value>"}
}
]
Kommentar
Om ObjectProperty
har fler än en egenskap bör du inkludera alla i fältet för den value
här åtgärden, även om du bara uppdaterar en:
... "value": {"StringSubProperty":"<string-value>", "Property2":"<property2-value>", ...}
När detta har gjorts en gång finns en sökväg som StringSubProperty
kan uppdateras direkt från och med nu med en typisk replace
åtgärd:
[
{
"op": "replace",
"path": "/ObjectProperty/StringSubProperty",
"value": "<string-value>"
}
]
Även om det första steget inte är nödvändigt i fall där ObjectProperty
instansierades när tvillingen skapades, rekommenderar vi att du använder den varje gång du uppdaterar en underegenskap för första gången, eftersom du kanske inte alltid vet med säkerhet om objektegenskapen ursprungligen instansierades eller inte.
Uppdatera en digital tvillings modell
Funktionen UpdateDigitalTwin()
kan också användas för att migrera en digital tvilling till en annan modell.
Tänk till exempel på följande JSON Patch-dokument som ersätter den digitala tvillingens metadatafält $model
:
[
{
"op": "replace",
"path": "/$metadata/$model",
"value": "dtmi:example:foo;1"
}
]
Den här åtgärden lyckas bara om den digitala tvillingen som ändras av korrigeringen överensstämmer med den nya modellen.
Ta följande som exempel:
- Föreställ dig en digital tvilling med en modell av foo_old. foo_old definierar en obligatorisk egenskapsmassa.
- Den nya modellen foo_new definierar en egenskapsmassa och lägger till en ny obligatorisk egenskapstemperatur.
- Efter korrigeringen måste den digitala tvillingen ha både en mass- och temperaturegenskap.
Korrigeringen för den här situationen måste uppdatera både modellens och tvillingens temperaturegenskap, så här:
[
{
"op": "replace",
"path": "/$metadata/$model",
"value": "dtmi:example:foo_new;1"
},
{
"op": "add",
"path": "/temperature",
"value": 60
}
]
Uppdatera en egenskaps sourceTime
Du kan välja att använda sourceTime
fältet på tvillingegenskaper för att registrera tidsstämplar för när egenskapsuppdateringar observeras i verkligheten. Azure Digital Twins har inbyggt stöd sourceTime
för metadata för varje tvillingegenskap. Värdet sourceTime
måste uppfylla ISO 8601-datum- och tidsformatet. Mer information om det här fältet och andra fält på digitala tvillingar finns i JSON-format för digital tvilling.
Den lägsta stabila REST API-versionen som stöder det här fältet är versionen 2022-05-31 . Om du vill arbeta med det här fältet med hjälp av Azure Digital Twins SDK:er rekommenderar vi att du använder den senaste versionen av SDK:et för att se till att det här fältet ingår.
Här är ett exempel på ett JSON Patch-dokument som uppdaterar både värdet och fältet för sourceTime
en Temperature
egenskap:
[
{
"op": "replace",
"path": "/Temperature",
"value": "22.3"
},
{
"op": "replace",
"path": "/$metadata/Temperature/sourceTime",
"value": "2021-11-30T18:47:53.7648958Z"
}
]
Om du vill uppdatera fältet sourceTime
på en egenskap som ingår i en komponent tar du med komponenten i början av sökvägen. I exemplet ovan gör du detta genom att ändra sökvägsvärdet från /$metadata/Temperature/sourceTime
till myComponent/$metadata/Temperature/sourceTime
.
Kommentar
Om du uppdaterar både sourceTime
värdet och på en egenskap och senare endast uppdaterar egenskapens värde, kommer tidsstämpeln sourceTime
från den första uppdateringen att finnas kvar.
Hantera motstridiga uppdateringsanrop
Azure Digital Twins ser till att alla inkommande begäranden bearbetas en efter en. Det innebär att även om flera funktioner försöker uppdatera samma egenskap på en tvilling samtidigt behöver du inte skriva explicit låskod för att hantera konflikten.
Det här beteendet sker per tvilling.
Föreställ dig till exempel ett scenario där dessa tre anrop kommer samtidigt:
- Skriv egenskap A på Twin1
- Skriv egenskap B på Twin1
- Skriv egenskap A på Twin2
De två anropen som ändrar Twin1 körs en efter en och ändringsmeddelanden genereras för varje ändring. Anropet för att ändra Twin2 kan köras samtidigt utan konflikt, så snart det kommer.
Ta bort en digital tvilling
Du kan ta bort tvillingar med hjälp av DeleteDigitalTwin()
metoden . Du kan dock bara ta bort en tvilling när den inte har fler relationer. Ta därför först bort tvillingens inkommande och utgående relationer.
Här är ett exempel på koden för att ta bort tvillingar och deras relationer. DeleteDigitalTwin
SDK-anropet är markerat för att klargöra var det hamnar i det bredare exempelkontexten.
private static async Task CustomMethod_DeleteTwinAsync(DigitalTwinsClient client, string twinId)
{
await CustomMethod_FindAndDeleteOutgoingRelationshipsAsync(client, twinId);
await CustomMethod_FindAndDeleteIncomingRelationshipsAsync(client, twinId);
try
{
await client.DeleteDigitalTwinAsync(twinId);
Console.WriteLine("Twin deleted successfully");
}
catch (RequestFailedException ex)
{
Console.WriteLine($"*** Error:{ex.Message}");
}
}
private static async Task CustomMethod_FindAndDeleteOutgoingRelationshipsAsync(DigitalTwinsClient client, string dtId)
{
// Find the relationships for the twin
try
{
// GetRelationshipsAsync will throw an error if a problem occurs
AsyncPageable<BasicRelationship> rels = client.GetRelationshipsAsync<BasicRelationship>(dtId);
await foreach (BasicRelationship rel in rels)
{
await client.DeleteRelationshipAsync(dtId, rel.Id).ConfigureAwait(false);
Console.WriteLine($"Deleted relationship {rel.Id} from {dtId}");
}
}
catch (RequestFailedException ex)
{
Console.WriteLine($"*** Error {ex.Status}/{ex.ErrorCode} retrieving or deleting relationships for {dtId} due to {ex.Message}");
}
}
private static async Task CustomMethod_FindAndDeleteIncomingRelationshipsAsync(DigitalTwinsClient client, string dtId)
{
// Find the relationships for the twin
try
{
// GetRelationshipsAsync will throw an error if a problem occurs
AsyncPageable<IncomingRelationship> incomingRels = client.GetIncomingRelationshipsAsync(dtId);
await foreach (IncomingRelationship incomingRel in incomingRels)
{
await client.DeleteRelationshipAsync(incomingRel.SourceId, incomingRel.RelationshipId).ConfigureAwait(false);
Console.WriteLine($"Deleted incoming relationship {incomingRel.RelationshipId} from {dtId}");
}
}
catch (RequestFailedException ex)
{
Console.WriteLine($"*** Error {ex.Status}/{ex.ErrorCode} retrieving or deleting incoming relationships for {dtId} due to {ex.Message}");
}
}
Ta bort alla digitala tvillingar
Om du vill ha ett exempel på hur du tar bort alla tvillingar samtidigt laddar du ned exempelappen som används i Utforska grunderna med en exempelklientapp. Filen CommandLoop.cs gör detta i en CommandDeleteAllTwins()
funktion.
Kommentar
Om du vill ta bort alla modeller, tvillingar och relationer i en instans samtidigt använder du API:et Ta bort jobb.
Körbart kodexempel för digital tvilling
Du kan använda det körbara kodexemplet nedan för att skapa en tvilling, uppdatera dess information och ta bort tvillingen.
Konfigurera exempelprojektfiler
Kodfragmentet använder en exempelmodelldefinition, Room.json. Om du vill ladda ned modellfilen så att du kan använda den i koden använder du den här länken för att gå direkt till filen i GitHub. Högerklicka sedan var som helst på skärmen, välj Spara som i webbläsarens högerklicka-meny och använd fönstret Spara som för att spara filen som Room.json.
Skapa sedan ett nytt konsolappprojekt i Visual Studio eller valfri redigerare.
Kopiera sedan följande kod för det körbara exemplet till projektet:
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Azure;
using Azure.DigitalTwins.Core;
using Azure.Identity;
using System.IO;
namespace DigitalTwins_Samples
{
class TwinOperationsSample
{
public static async Task Main(string[] args)
{
Console.WriteLine("Hello World!");
// Create the Azure Digital Twins client for API calls
string adtInstanceUrl = "https://<your-instance-hostname>";
var credentials = new DefaultAzureCredential();
var client = new DigitalTwinsClient(new Uri(adtInstanceUrl), credentials);
Console.WriteLine($"Service client created – ready to go");
// Upload models
Console.WriteLine($"Upload a model");
string dtdl = File.ReadAllText("<path-to>/Room.json");
var models = new List<string> { dtdl };
// Upload the model to the service
await client.CreateModelsAsync(models);
// Create new digital twin
// <CreateTwin_withHelper>
string twinId = "myTwinID";
var initData = new BasicDigitalTwin
{
Id = twinId,
Metadata = { ModelId = "dtmi:example:Room;1" },
// Initialize properties
Contents =
{
{ "Temperature", 25.0 },
{ "Humidity", 50.0 },
},
};
// <CreateTwinCall>
await client.CreateOrReplaceDigitalTwinAsync<BasicDigitalTwin>(twinId, initData);
// </CreateTwinCall>
// </CreateTwin_withHelper>
Console.WriteLine("Twin created successfully");
//Print twin
Console.WriteLine("--- Printing twin details:");
await CustomMethod_FetchAndPrintTwinAsync(twinId, client);
Console.WriteLine("--------");
//Update twin data
var updateTwinData = new JsonPatchDocument();
updateTwinData.AppendAdd("/Temperature", 30.0);
// <UpdateTwinCall>
await client.UpdateDigitalTwinAsync(twinId, updateTwinData);
// </UpdateTwinCall>
Console.WriteLine("Twin properties updated");
Console.WriteLine();
//Print twin again
Console.WriteLine("--- Printing twin details (after update):");
await CustomMethod_FetchAndPrintTwinAsync(twinId, client);
Console.WriteLine("--------");
Console.WriteLine();
//Delete twin
await CustomMethod_DeleteTwinAsync(client, twinId);
}
private static async Task<BasicDigitalTwin> CustomMethod_FetchAndPrintTwinAsync(string twinId, DigitalTwinsClient client)
{
// <GetTwin>
BasicDigitalTwin twin;
// <GetTwinCall>
Response<BasicDigitalTwin> twinResponse = await client.GetDigitalTwinAsync<BasicDigitalTwin>(twinId);
twin = twinResponse.Value;
// </GetTwinCall>
Console.WriteLine($"Model id: {twin.Metadata.ModelId}");
foreach (string prop in twin.Contents.Keys)
{
if (twin.Contents.TryGetValue(prop, out object value))
Console.WriteLine($"Property '{prop}': {value}");
}
// </GetTwin>
return twin;
}
// <DeleteTwin>
private static async Task CustomMethod_DeleteTwinAsync(DigitalTwinsClient client, string twinId)
{
await CustomMethod_FindAndDeleteOutgoingRelationshipsAsync(client, twinId);
await CustomMethod_FindAndDeleteIncomingRelationshipsAsync(client, twinId);
try
{
await client.DeleteDigitalTwinAsync(twinId);
Console.WriteLine("Twin deleted successfully");
}
catch (RequestFailedException ex)
{
Console.WriteLine($"*** Error:{ex.Message}");
}
}
private static async Task CustomMethod_FindAndDeleteOutgoingRelationshipsAsync(DigitalTwinsClient client, string dtId)
{
// Find the relationships for the twin
try
{
// GetRelationshipsAsync will throw an error if a problem occurs
AsyncPageable<BasicRelationship> rels = client.GetRelationshipsAsync<BasicRelationship>(dtId);
await foreach (BasicRelationship rel in rels)
{
await client.DeleteRelationshipAsync(dtId, rel.Id).ConfigureAwait(false);
Console.WriteLine($"Deleted relationship {rel.Id} from {dtId}");
}
}
catch (RequestFailedException ex)
{
Console.WriteLine($"*** Error {ex.Status}/{ex.ErrorCode} retrieving or deleting relationships for {dtId} due to {ex.Message}");
}
}
private static async Task CustomMethod_FindAndDeleteIncomingRelationshipsAsync(DigitalTwinsClient client, string dtId)
{
// Find the relationships for the twin
try
{
// GetRelationshipsAsync will throw an error if a problem occurs
AsyncPageable<IncomingRelationship> incomingRels = client.GetIncomingRelationshipsAsync(dtId);
await foreach (IncomingRelationship incomingRel in incomingRels)
{
await client.DeleteRelationshipAsync(incomingRel.SourceId, incomingRel.RelationshipId).ConfigureAwait(false);
Console.WriteLine($"Deleted incoming relationship {incomingRel.RelationshipId} from {dtId}");
}
}
catch (RequestFailedException ex)
{
Console.WriteLine($"*** Error {ex.Status}/{ex.ErrorCode} retrieving or deleting incoming relationships for {dtId} due to {ex.Message}");
}
}
// </DeleteTwin>
}
}
Kommentar
Det finns för närvarande ett känt problem som påverkar omslutningsklassen DefaultAzureCredential
som kan leda till ett fel vid autentisering. Om du stöter på det här problemet kan du prova att instansiera DefaultAzureCredential
med följande valfria parameter för att lösa det: new DefaultAzureCredential(new DefaultAzureCredentialOptions { ExcludeSharedTokenCacheCredential = true });
Mer information om det här problemet finns i Kända problem med Azure Digital Twins.
Konfigurera projekt
Slutför sedan följande steg för att konfigurera projektkoden:
Lägg till den Room.json fil som du laddade ned tidigare till projektet och ersätt
<path-to>
platshållaren i koden för att tala om för programmet var det finns.Ersätt platshållaren
<your-instance-hostname>
med azure Digital Twins-instansens värdnamn.Lägg till två beroenden i projektet som behövs för att arbeta med Azure Digital Twins. Den första är paketet för Azure Digital Twins SDK för .NET och det andra innehåller verktyg för att hjälpa till med autentisering mot Azure.
dotnet add package Azure.DigitalTwins.Core dotnet add package Azure.Identity
Du måste också konfigurera lokala autentiseringsuppgifter om du vill köra exemplet direkt. Nästa avsnitt går igenom detta.
Konfigurera lokala Azure-autentiseringsuppgifter
Det här exemplet använder DefaultAzureCredential (en del av biblioteket) för att autentisera Azure.Identity
användare med Azure Digital Twins-instansen när du kör den på den lokala datorn. Mer information om olika sätt som en klientapp kan autentisera med Azure Digital Twins finns i Skriva kod för appautentisering.
Med DefaultAzureCredential
söker exemplet efter autentiseringsuppgifter i din lokala miljö, till exempel en Azure-inloggning i ett lokalt Azure CLI eller i Visual Studio eller Visual Studio Code. Därför bör du logga in på Azure lokalt via någon av dessa mekanismer för att konfigurera autentiseringsuppgifter för exemplet.
Om du använder Visual Studio eller Visual Studio Code för att köra kodexempel kontrollerar du att du är inloggad i redigeringsprogrammet med samma Azure-autentiseringsuppgifter som du vill använda för att komma åt din Azure Digital Twins-instans. Om du använder ett lokalt CLI-fönster kör az login
du kommandot för att logga in på ditt Azure-konto. När du sedan kör kodexemplet bör du autentiseras automatiskt.
Kör exemplet
Nu när installationen är klar kan du köra exempelkodprojektet.
Här är konsolens utdata från ovanstående program:
Nästa steg
Se hur du skapar och hanterar relationer mellan dina digitala tvillingar: