Tutoriel : Codage avec le SDK Azure Digital Twins
Les développeurs travaillant avec Azure Digital Twins écrivent généralement des applications clientes pour interagir avec leur instance du service Azure Digital Twins. Ce tutoriel destiné aux développeurs fournit une introduction à la programmation par rapport au service Azure Digital Twins à l’aide du SDK Azure Digital Twins pour .NET (C#). Il décrit étape par étape comment écrire une application console cliente C# à partir de rien.
- Configurer le projet
- Démarrer avec le code de projet
- Exemple de code complet
- Nettoyer les ressources
- Étapes suivantes
Prérequis
Ce tutoriel sur Azure Digital Twins utilise la ligne de commande pour la création et la configuration du projet. Ainsi, vous pouvez utiliser n’importe quel éditeur de code pour effectuer les exercices.
Pour commencer, il vous faut :
- Un éditeur de code.
- .NET Core 3.1 sur votre ordinateur de développement. Vous pouvez télécharger cette version du kit SDK .NET Core pour plusieurs plateformes à partir du site Télécharger .NET Core 3.1.
Préparer une instance Azure Digital Twins
Pour utiliser Azure Digital Twins dans cet article, vous avez besoin d’une instance Azure Digital Twins et des autorisations requises pour l’utiliser. Si vous disposez déjà d’une instance Azure Digital Twins configurée, vous pouvez utiliser cette instance et passer à la section suivante. Dans le cas contraire, suivez les instructions indiquées dans Configurer une instance et l’authentification. Les instructions contiennent des informations qui vous aideront à vérifier que vous avez correctement effectué chaque étape.
Une fois l’instance configurée, notez son nom d’hôte. Vous trouverez le nom d’hôte dans le portail Azure.
Configurer les informations d’identification Azure locales
Cet exemple utilise DefaultAzureCredential (qui fait partie de la bibliothèque Azure.Identity
) pour authentifier les utilisateurs auprès de l’instance Azure Digital Twins quand vous l’exécutez sur votre ordinateur local. Pour plus d’informations sur les différentes façons dont une application cliente peut s’authentifier auprès d’Azure Digital Twins, consultez Écrire le code d’authentification de l’application.
Avec DefaultAzureCredential
, l’exemple recherche les informations d’identification dans votre environnement local, comme une connexion Azure dans une interface de ligne de commande Azure locale ou dans Visual Studio ou Visual Studio Code. C’est la raison pour laquelle vous devez vous connecter à Azure localement via l’un de ces mécanismes afin de configurer les informations d’identification pour l’exemple.
Si vous utilisez Visual Studio ou Visual Studio Code pour exécuter des exemples de code, vérifiez que vous êtes connecté à cet éditeur avec les mêmes informations d’identification Azure que celles que vous souhaitez utiliser pour accéder à votre instance Azure Digital Twins. Si vous utilisez une fenêtre CLI locale, exécutez la commande az login
pour vous connecter à votre compte Azure. Après cela, lorsque vous exécutez votre échantillon de code, vous devriez être authentifié automatiquement.
Configurer le projet
Une fois que vous êtes prêt à utiliser votre instance Azure Digital Twins, commencez à configurer le projet d’application cliente.
Ouvrez une fenêtre de console sur votre machine, puis créez un répertoire de projet vide dans lequel vous souhaitez stocker votre travail au cours de ce tutoriel. Nommez le répertoire comme vous le souhaitez (par exemple DigitalTwinsCodeTutorial).
Accédez au nouveau répertoire.
Une fois dans le répertoire du projet, créez un projet d’application console .NET vide. Dans la fenêtre de commande, vous pouvez exécuter la commande suivante afin de créer un projet C# minimal pour la console :
dotnet new console
Cette commande créera plusieurs fichiers dans votre répertoire, notamment un nommé Program.cs où vous écrirez la majeure partie de votre code.
Laissez la fenêtre de commande ouverte parce que vous allez l’utiliser tout au long du tutoriel.
Ensuite, ajouter deux dépendances à votre projet qui seront nécessaires pour utiliser Azure Digital Twins. La première est le package pour le SDK Azure Digital Twins pour .NET, tandis que la seconde fournit des outils facilitant l’authentification auprès d’Azure.
dotnet add package Azure.DigitalTwins.Core
dotnet add package Azure.Identity
Démarrer avec le code de projet
Dans cette section, vous allez commencer à écrire le code de votre nouveau projet d’application pour fonctionner avec Azure Digital Twins. Les actions couvertes sont les suivantes :
- Authentification auprès du service
- Chargement d’un modèle
- Interception des erreurs
- Création de jumeaux numériques
- Création de relations
- Interrogation de jumeaux numériques
Vous trouverez également une section contenant le code complet à la fin du tutoriel. Vous pouvez utiliser cette section en guise de référence pour vérifier votre programme au fur et à mesure.
Pour commencer, ouvrez le fichier Program.cs dans un éditeur de code de votre choix. Vous verrez un modèle de code minimal qui ressemble à ceci :
Tout d’abord, ajoutez des lignes using
en haut du code pour tirer les dépendances nécessaires.
using Azure.DigitalTwins.Core;
using Azure.Identity;
Ensuite, vous allez ajouter du code à ce fichier pour activer certaines fonctionnalités.
S’authentifier auprès du service
La première chose que votre application doit faire, c’est s’authentifier auprès du service Azure Digital Twins. Vous pouvez ensuite créer une classe cliente de service pour accéder aux fonctions du SDK.
Pour vous authentifier, vous avez besoin du nom d’hôte de votre instance Azure Digital Twins.
Dans Program.cs, collez le code suivant sous la ligne d’impression « Hello, World ! » dans la méthode Main
.
Définissez adtInstanceUrl
sur le nom d’hôte de votre instance Azure Digital Twins.
string adtInstanceUrl = "https://<your-Azure-Digital-Twins-instance-hostName>";
var credential = new DefaultAzureCredential();
var client = new DigitalTwinsClient(new Uri(adtInstanceUrl), credential);
Console.WriteLine($"Service client created – ready to go");
Enregistrez le fichier.
Dans votre fenêtre de commande, exécutez le code avec cette commande :
dotnet run
Cette commande restaure les dépendances lors de la première exécution, puis exécute le programme.
- Si aucune erreur ne se produit, le programme imprimera : « Service client created - ready to go ».
- Étant donné qu’il n’y a pas encore de gestion des erreurs dans ce projet, si un problème quelconque se produit, une exception est levée par le code.
Notes
Il existe actuellement un problème connu affectant la classe wrapper DefaultAzureCredential
susceptible d’entraîner une erreur lors de l’authentification. Si vous rencontrez ce problème, vous pouvez essayer d’instancier DefaultAzureCredential
avec le paramètre facultatif suivant afin de le résoudre : new DefaultAzureCredential(new DefaultAzureCredentialOptions { ExcludeSharedTokenCacheCredential = true });
Pour plus d’informations sur ce problème, consultez Problèmes connus d’Azure Digital Twins.
Charger un modèle
Azure Digital Twins n’a aucun vocabulaire de domaine intrinsèque. C’est vous qui définissez, à l’aide de modèles, les types d’éléments de votre environnement que vous pouvez représenter dans Azure Digital Twins. Les modèles sont similaires aux classes dans les langages de programmation orientés objet. Ils fournissent des modèles de jumeaux numériques définis par l’utilisateur à suivre et à instancier ultérieurement. Ils sont écrits dans un langage de type JSON appelé DTDL (Digital Twins Definition Language) .
La première étape de la création d’une solution Azure Digital Twins consiste à définir au moins un modèle dans un fichier DTDL.
Dans le répertoire où vous avez créé votre projet, créez un fichier .json nommé SampleModel.json. Collez-y le corps de fichier suivant :
{
"@id": "dtmi:example:SampleModel;1",
"@type": "Interface",
"displayName": "SampleModel",
"contents": [
{
"@type": "Relationship",
"name": "contains"
},
{
"@type": "Property",
"name": "data",
"schema": "string"
}
],
"@context": "dtmi:dtdl:context;3"
}
Conseil
Si vous utilisez Visual Studio pour ce tutoriel, vous souhaiterez peut-être sélectionner le nouveau fichier JSON et affecter la valeur Copier si plus récent ou Toujours copier à la propriété Copier dans le répertoire de sortie dans l’inspecteur de propriété. Cela permettra à Visual Studio de trouver le fichier JSON avec le chemin par défaut quand vous exécuterez le programme avec F5 lors des étapes suivantes du tutoriel.
Conseil
Vous pouvez case activée des documents de modèle pour vous assurer que le DTDL est valide à l’aide de la bibliothèque DTDLParser. Pour plus d’informations sur l’utilisation de cette bibliothèque, consultez Analyser et valider des modèles.
Ensuite, ajoutez du code à Program.cs pour charger le modèle que vous avez créé dans votre instance Azure Digital Twins.
Tout d’abord, ajoutez quelques instructions using
au début du fichier :
using System.Threading.Tasks;
using System.IO;
using System.Collections.Generic;
using Azure;
Ensuite, préparez l’utilisation des méthodes asynchrones dans le SDK de service C# en modifiant la signature de la méthode Main
pour autoriser l’exécution asynchrone.
static async Task Main(string[] args)
{
Notes
L’utilisation de async
n’est pas strictement nécessaire, car le SDK fournit également des versions synchrones de tous les appels. Ce tutoriel utilise async
.
Vient ensuite le premier bloc de code qui interagit avec le service Azure Digital Twins. Ce code charge le fichier DTDL que vous avez créé à partir de votre disque, puis le charge sur votre instance de service Azure Digital Twins.
Collez le code suivant sous le code d’autorisation que vous avez ajouté plus tôt.
Console.WriteLine();
Console.WriteLine($"Upload a model");
string dtdl = File.ReadAllText("SampleModel.json");
var models = new List<string> { dtdl };
// Upload the model to the service
await client.CreateModelsAsync(models);
Dans votre fenêtre de commande, exécutez le programme avec cette commande :
dotnet run
La mention « Upload a model » sera affichée dans la sortie, indiquant que ce code a été atteint, mais il n’existe pas encore de sortie pour préciser si le chargement a été effectué correctement.
Pour ajouter une instruction print indiquant tous les modèles chargés avec succès sur l’instance, ajoutez le code suivant juste après la section précédente :
// Read a list of models back from the service
AsyncPageable<DigitalTwinsModelData> modelDataList = client.GetModelsAsync();
await foreach (DigitalTwinsModelData md in modelDataList)
{
Console.WriteLine($"Model: {md.Id}");
}
Avant de réexécuter le programme pour tester ce nouveau code, rappelez-vous que la dernière fois que vous avez exécuté le programme, vous avez déjà chargé votre modèle. Azure Digital Twins ne vous permet pas de charger deux fois le même modèle. Par conséquent, si vous tentez de charger à nouveau le même modèle, le programme doit lever une exception.
Avec ces informations en tête, réexécutez le programme avec cette commande dans votre fenêtre de commande :
dotnet run
Le programme doit lever une exception. Quand vous essayez de charger un modèle qui a déjà été chargé, le service retourne une erreur de « requête incorrecte » par le biais de l’API REST. Par conséquent, le SDK client Azure Digital Twins lèvera à son tour une exception pour chaque code de retour de service autre qu’un succès.
La section suivante traite des exceptions de ce type et explique comment les gérer dans votre code.
Intercepter les erreurs
Pour empêcher que le programme se plante, vous pouvez ajouter du code d’exception autour du code de chargement du modèle. Encapsulez l’appel client existant await client.CreateModelsAsync(typeList)
dans un gestionnaire try/catch comme suit :
try
{
await client.CreateModelsAsync(models);
Console.WriteLine("Models uploaded to the instance:");
}
catch (RequestFailedException e)
{
Console.WriteLine($"Upload model error: {e.Status}: {e.Message}");
}
Réexécutez le programme avec dotnet run
dans votre fenêtre de commande. Vous obtiendrez davantage de détails sur le problème de chargement du modèle, y compris un code d’erreur indiquant ceci : ModelIdAlreadyExists
.
Désormais, ce tutoriel encapsulera tous les appels aux méthodes de service dans des gestionnaires try/catch.
Créer des jumeaux numériques
Maintenant que vous avez chargé un modèle dans Azure Digital Twins, vous pouvez utiliser cette définition de modèle pour créer des jumeaux numériques. Les jumeaux numériques sont des instances d’un modèle ; ils représentent les entités au sein de votre environnement d’entreprise (par exemple les capteurs dans une ferme, les salles d’un bâtiment ou les voyants d’une voiture). Cette section crée quelques jumeaux numériques basés sur le modèle que vous avez chargé.
Ajoutez le code suivant à la fin de la méthode Main
pour créer et initialiser trois jumeaux numériques basés sur ce modèle.
var twinData = new BasicDigitalTwin();
twinData.Metadata.ModelId = "dtmi:example:SampleModel;1";
twinData.Contents.Add("data", $"Hello World!");
string prefix = "sampleTwin-";
for (int i = 0; i < 3; i++)
{
try
{
twinData.Id = $"{prefix}{i}";
await client.CreateOrReplaceDigitalTwinAsync<BasicDigitalTwin>(twinData.Id, twinData);
Console.WriteLine($"Created twin: {twinData.Id}");
}
catch(RequestFailedException e)
{
Console.WriteLine($"Create twin error: {e.Status}: {e.Message}");
}
}
Dans votre fenêtre de commande, exécutez le programme avec dotnet run
. Dans la sortie, recherchez les messages print indiquant que sampleTwin-0, sampleTwin-1 et sampleTwin-2 ont été créés.
Ensuite, réexécutez le programme.
Notez qu’aucune erreur n’est générée quand les jumeaux sont créés la deuxième fois, bien qu’ils existent déjà après la première exécution. Contrairement à la création de modèle, la création de jumeau est, au niveau REST, un appel PUT avec une sémantique upsert. L’utilisation de ce type d’appel REST signifie que si un jumeau existe déjà, une tentative de création du même jumeau remplacera simplement le jumeau d’origine. Aucune erreur n’est levée.
Créer des relations
Ensuite, vous pouvez créer des relations entre les jumeaux que vous avez créés, afin de les raccorder sur un graphe de jumeaux. Les graphes de jumeaux servent à représenter votre environnement entier.
Ajoutez une nouvelle méthode statique à la classe Program
, sous la méthode Main
(le code a désormais deux méthodes) :
public async static Task CreateRelationshipAsync(DigitalTwinsClient client, string srcId, string targetId)
{
var relationship = new BasicRelationship
{
TargetId = targetId,
Name = "contains"
};
try
{
string relId = $"{srcId}-contains->{targetId}";
await client.CreateOrReplaceRelationshipAsync(srcId, relId, relationship);
Console.WriteLine("Created relationship successfully");
}
catch (RequestFailedException e)
{
Console.WriteLine($"Create relationship error: {e.Status}: {e.Message}");
}
}
Ensuite, ajoutez le code suivant à la fin de la méthode Main
pour appeler la méthode CreateRelationship
et utiliser le code que vous venez d’écrire :
// Connect the twins with relationships
await CreateRelationshipAsync(client, "sampleTwin-0", "sampleTwin-1");
await CreateRelationshipAsync(client, "sampleTwin-0", "sampleTwin-2");
Dans votre fenêtre de commande, exécutez le programme avec dotnet run
. Dans la sortie, recherchez des instructions print indiquant que les deux relations ont été créées avec succès.
Azure Digital Twins ne vous permet pas de créer une relation s’il en existe déjà une portant le même ID. Par conséquent, si vous exécutez le programme plusieurs fois, vous verrez des exceptions lors de la création de la relation. Ce code intercepte les exceptions et les ignore.
Lister les relations
Le code que vous allez ensuite ajouter vous permet d’afficher la liste des relations que vous avez créées.
Ajoutez la nouvelle méthode suivante à la classe Program
:
public async static Task ListRelationshipsAsync(DigitalTwinsClient client, string srcId)
{
try
{
AsyncPageable<BasicRelationship> results = client.GetRelationshipsAsync<BasicRelationship>(srcId);
Console.WriteLine($"Twin {srcId} is connected to:");
await foreach (BasicRelationship rel in results)
{
Console.WriteLine($" -{rel.Name}->{rel.TargetId}");
}
}
catch (RequestFailedException e)
{
Console.WriteLine($"Relationship retrieval error: {e.Status}: {e.Message}");
}
}
Ensuite, ajoutez le code suivant à la fin de la méthode Main
pour appeler le code ListRelationships
:
//List the relationships
await ListRelationshipsAsync(client, "sampleTwin-0");
Dans votre fenêtre de commande, exécutez le programme avec dotnet run
. Vous devez voir une liste de toutes les relations que vous avez créées dans une instruction de sortie similaire à celle-ci :
Interroger des jumeaux numériques
L’une des principales fonctionnalités d’Azure Digital Twins est la capacité à interroger facilement et efficacement votre graphe de jumeaux pour répondre à des questions sur votre environnement.
La dernière section de code à ajouter dans ce tutoriel exécute une requête sur l’instance Azure Digital Twins. La requête utilisée dans cet exemple retourne tous les jumeaux numériques de l’instance.
Ajoutez cette instruction using
pour permettre l’utilisation de la classe JsonSerializer
pour présenter plus aisément les informations de jumeau numérique :
using System.Text.Json;
Ensuite, ajoutez le code suivant à la fin de la méthode Main
:
// Run a query for all twins
string query = "SELECT * FROM digitaltwins";
AsyncPageable<BasicDigitalTwin> queryResult = client.QueryAsync<BasicDigitalTwin>(query);
await foreach (BasicDigitalTwin twin in queryResult)
{
Console.WriteLine(JsonSerializer.Serialize(twin));
Console.WriteLine("---------------");
}
Dans votre fenêtre de commande, exécutez le programme avec dotnet run
. La sortie doit afficher tous les jumeaux numériques de cette instance.
Notes
Vous pouvez constater une latence jusqu’à 10 secondes pour que les changements que vous apportez aux données de votre graphe prennent effet dans les requêtes.
L’API DigitalTwins reflète les changements tout de suite, donc si vous avez besoin d’une réponse instantanée, utilisez une demande d’API DigitalTwins GetById ou un appel de SDK (GetDigitalTwin) pour obtenir des données de jumeau au lieu d’une requête.
Exemple de code complet
À ce stade du tutoriel, vous disposez d’une application cliente complète, capable d’effectuer des actions de base sur Azure Digital Twins. Pour référence, le code complet du programme dans Program.cs est indiqué ci-dessous :
using System;
// <Azure_Digital_Twins_dependencies>
using Azure.DigitalTwins.Core;
using Azure.Identity;
// </Azure_Digital_Twins_dependencies>
// <Model_dependencies>
using System.Threading.Tasks;
using System.IO;
using System.Collections.Generic;
using Azure;
// </Model_dependencies>
// <Query_dependencies>
using System.Text.Json;
// </Query_dependencies>
namespace DigitalTwins_Samples
{
class DigitalTwinsClientAppSample
{
// <Async_signature>
static async Task Main(string[] args)
{
// </Async_signature>
Console.WriteLine("Hello World!");
// <Authentication_code>
string adtInstanceUrl = "https://<your-Azure-Digital-Twins-instance-hostName>";
var credential = new DefaultAzureCredential();
var client = new DigitalTwinsClient(new Uri(adtInstanceUrl), credential);
Console.WriteLine($"Service client created – ready to go");
// </Authentication_code>
// <Model_code>
Console.WriteLine();
Console.WriteLine("Upload a model");
string dtdl = File.ReadAllText("SampleModel.json");
var models = new List<string> { dtdl };
// Upload the model to the service
// <Model_try_catch>
try
{
await client.CreateModelsAsync(models);
Console.WriteLine("Models uploaded to the instance:");
}
catch (RequestFailedException e)
{
Console.WriteLine($"Upload model error: {e.Status}: {e.Message}");
}
// </Model_try_catch>
// <Print_model>
// Read a list of models back from the service
AsyncPageable<DigitalTwinsModelData> modelDataList = client.GetModelsAsync();
await foreach (DigitalTwinsModelData md in modelDataList)
{
Console.WriteLine($"Model: {md.Id}");
}
// </Print_model>
// </Model_code>
// <Initialize_twins>
var twinData = new BasicDigitalTwin();
twinData.Metadata.ModelId = "dtmi:example:SampleModel;1";
twinData.Contents.Add("data", $"Hello World!");
string prefix = "sampleTwin-";
for (int i = 0; i < 3; i++)
{
try
{
twinData.Id = $"{prefix}{i}";
await client.CreateOrReplaceDigitalTwinAsync<BasicDigitalTwin>(twinData.Id, twinData);
Console.WriteLine($"Created twin: {twinData.Id}");
}
catch(RequestFailedException e)
{
Console.WriteLine($"Create twin error: {e.Status}: {e.Message}");
}
}
// </Initialize_twins>
// <Use_create_relationship>
// Connect the twins with relationships
await CreateRelationshipAsync(client, "sampleTwin-0", "sampleTwin-1");
await CreateRelationshipAsync(client, "sampleTwin-0", "sampleTwin-2");
// </Use_create_relationship>
// <Use_list_relationships>
//List the relationships
await ListRelationshipsAsync(client, "sampleTwin-0");
// </Use_list_relationships>
// <Query_twins>
// Run a query for all twins
string query = "SELECT * FROM digitaltwins";
AsyncPageable<BasicDigitalTwin> queryResult = client.QueryAsync<BasicDigitalTwin>(query);
await foreach (BasicDigitalTwin twin in queryResult)
{
Console.WriteLine(JsonSerializer.Serialize(twin));
Console.WriteLine("---------------");
}
// </Query_twins>
}
// <Create_relationship>
public async static Task CreateRelationshipAsync(DigitalTwinsClient client, string srcId, string targetId)
{
var relationship = new BasicRelationship
{
TargetId = targetId,
Name = "contains"
};
try
{
string relId = $"{srcId}-contains->{targetId}";
await client.CreateOrReplaceRelationshipAsync(srcId, relId, relationship);
Console.WriteLine("Created relationship successfully");
}
catch (RequestFailedException e)
{
Console.WriteLine($"Create relationship error: {e.Status}: {e.Message}");
}
}
// </Create_relationship>
// <List_relationships>
public async static Task ListRelationshipsAsync(DigitalTwinsClient client, string srcId)
{
try
{
AsyncPageable<BasicRelationship> results = client.GetRelationshipsAsync<BasicRelationship>(srcId);
Console.WriteLine($"Twin {srcId} is connected to:");
await foreach (BasicRelationship rel in results)
{
Console.WriteLine($" -{rel.Name}->{rel.TargetId}");
}
}
catch (RequestFailedException e)
{
Console.WriteLine($"Relationship retrieval error: {e.Status}: {e.Message}");
}
}
// </List_relationships>
}
}
Nettoyer les ressources
À l’issue de ce tutoriel, vous pourrez choisir les ressources à supprimer, en fonction de ce que vous souhaitez faire ensuite.
- Si vous envisagez de passer au tutoriel suivant, vous pourrez y réutiliser l’instance utilisée dans ce tutoriel. Vous pouvez conserver les ressources Azure Digital Twins que vous avez configurées ici et ignorer le reste de cette section.
Si vous souhaitez continuer à utiliser l’instance Azure Digital Twins à partir de cet article, mais souhaitez effacer tous ses modèles, jumeaux et relations, exécutez la commande CLI az dt job suppression suivante :
az dt job deletion create -n <name-of-Azure-Digital-Twins-instance> -y
Si vous souhaitez uniquement supprimer certains de ces éléments, vous pouvez utiliser les commandes suppression de relation de jumeau az dt, az dt twin delete et az dt model delete pour supprimer sélectivement uniquement les éléments que vous souhaitez supprimer.
Si vous n’avez besoin d’aucune des ressources que vous avez créées dans ce tutoriel, vous pouvez supprimer l’instance Azure Digital Twins et toutes les autres ressources de cet article à l’aide de la commande CLI az group delete. Cette opération supprime toutes les ressources Azure d’un groupe de ressources ainsi que ce dernier.
Important
La suppression d’un groupe de ressources est irréversible. Le groupe de ressources et toutes les ressources qu’il contient sont supprimés définitivement. Veillez à ne pas supprimer accidentellement les mauvaises ressources ou le mauvais groupe de ressources.
Ouvrez Azure Cloud Shell ou une fenêtre CLI locale, puis exécutez la commande suivante pour supprimer le groupe de ressources et tout ce qu’il contient.
az group delete --name <your-resource-group>
Vous pouvez également supprimer le dossier de projet de votre ordinateur local.
Étapes suivantes
Dans ce tutoriel, vous avez créé une application console cliente .NET à partir de rien. Vous avez écrit du code pour cette application cliente afin d’effectuer les actions de base sur une instance Azure Digital Twins.
Passez au tutoriel suivant pour découvrir les opérations que vous pouvez effectuer avec cet exemple d’application cliente :