public async Task DigitalTwins_Lifecycle() { DigitalTwinsClient client = GetClient(); string roomTwinId = await GetUniqueTwinIdAsync(client, TestAssetSettings.RoomTwinIdPrefix).ConfigureAwait(false); string floorModelId = await GetUniqueModelIdAsync(client, TestAssetSettings.FloorModelIdPrefix).ConfigureAwait(false); string roomModelId = await GetUniqueModelIdAsync(client, TestAssetSettings.RoomModelIdPrefix).ConfigureAwait(false); try { // arrange // create room model string roomModel = TestAssetsHelper.GetRoomModelPayload(roomModelId, floorModelId); await client.CreateModelsAsync(new List <string> { roomModel }).ConfigureAwait(false); // act // create room twin string roomTwin = TestAssetsHelper.GetRoomTwinPayload(roomModelId); await client.CreateDigitalTwinAsync(roomTwinId, roomTwin).ConfigureAwait(false); // get twin await client.GetDigitalTwinAsync(roomTwinId).ConfigureAwait(false); // update twin string updateTwin = TestAssetsHelper.GetRoomTwinUpdatePayload(); await client.UpdateDigitalTwinAsync(roomTwinId, updateTwin).ConfigureAwait(false); // delete a twin await client.DeleteDigitalTwinAsync(roomTwinId).ConfigureAwait(false); // assert Func <Task> act = async() => { await client.GetDigitalTwinAsync(roomTwinId).ConfigureAwait(false); }; act.Should().Throw <RequestFailedException>() .And.Status.Should().Be((int)HttpStatusCode.NotFound); } finally { // cleanup try { if (!string.IsNullOrWhiteSpace(roomModelId)) { await client.DeleteModelAsync(roomModelId).ConfigureAwait(false); } } catch (Exception ex) { Assert.Fail($"Test clean up failed: {ex.Message}"); } } }
/// <summary> /// Loads all the models found in the Models directory into memory and uses CreateModelsAsync API to create all the models in the ADT service instance /// </summary> private async Task AddAllModelsAsync() { PrintHeader("CREATING MODELS"); List <string> modelsToCreate = FileHelper.LoadAllFilesInPath(s_modelsPath).Values.ToList(); if (modelsToCreate == null || !modelsToCreate.Any()) { throw new Exception("Could not load models from disk."); } try { Response <IReadOnlyList <ModelData> > response = await client.CreateModelsAsync(modelsToCreate); Console.WriteLine($"Created models. Response status: {response.GetRawResponse().Status}"); } catch (RequestFailedException ex) when(ex.Status == (int)HttpStatusCode.Conflict) { Console.WriteLine($"One or more models already exist. Continuing with the sample optimistically."); } catch (Exception ex) { FatalError($"Failed to create models due to:\n{ex}"); } }
async static Task Main(string[] args) { var builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile("appsettings.dev.json", optional: true, reloadOnChange: true); var configuration = builder.Build(); #region ADT app Sign-in string clientId = configuration["AADClientId"]; string clientSecret = configuration["AADClientSecret"]; string tenantId = configuration["AADTenantId"]; string adtInstanceUrl = configuration["ADTInstanceUrl"]; // var credentials = new InteractiveBrowserCredential(tenantId, clientId); var credentials = new ClientSecretCredential(tenantId, clientId, clientSecret); DigitalTwinsClient client = new DigitalTwinsClient(new Uri(adtInstanceUrl), credentials); Console.WriteLine($"Service client created – ready to go"); #endregion #region Upload ADT model Console.WriteLine(); Console.WriteLine($"Uploading model"); var typeList = new List <string>(); string dtdl = File.ReadAllText("Models/Autoclave.json"); typeList.Add(dtdl); // Upload the model to the service await client.CreateModelsAsync(typeList); #endregion }
static async Task Main(string[] args) { Console.WriteLine("Hello World!"); //string clientId = "5c694aad-e4ed-43a3-95cc-3d45af6685e5"; //string tenantId = "72f988bf-86f1-41af-91ab-2d7cd011db47"; string adtInstanceUrl = "https://digital-twin-demo-jc.api.wcus.digitaltwins.azure.net"; var credOpts = new DefaultAzureCredentialOptions() { ExcludeSharedTokenCacheCredential = true, ExcludeVisualStudioCodeCredential = true }; var cred = new DefaultAzureCredential(credOpts); DigitalTwinsClient client = new DigitalTwinsClient(new Uri(adtInstanceUrl), cred); //var credentials = new InteractiveBrowserCredential(tenantId, clientId); // DigitalTwinsClient client = new DigitalTwinsClient(new Uri(adtInstanceUrl), credentials); Console.WriteLine($"Service client created – ready to go"); Console.WriteLine(); Console.WriteLine($"Upload a model"); var typeList = new List <string>(); string dtdl = File.ReadAllText("SampleModel.json"); typeList.Add(dtdl); // Upload the model to the service await client.CreateModelsAsync(typeList); // Read a list of models back from the service AsyncPageable <ModelData> modelDataList = client.GetModelsAsync(); await foreach (ModelData md in modelDataList) { Console.WriteLine($"Type name: {md.DisplayName}: {md.Id}"); } }
private async Task UploadOrderedInterfaces(IEnumerable <DTInterfaceInfo> orderedInterfaces) { Log.Write("Uploaded interfaces:"); try { var credential = new InteractiveBrowserCredential(options.TenantId, options.ClientId); var client = new DigitalTwinsClient(new UriBuilder("https", options.HostName).Uri, credential); for (int i = 0; i < (orderedInterfaces.Count() / options.BatchSize) + 1; i++) { IEnumerable <DTInterfaceInfo> batch = orderedInterfaces.Skip(i * options.BatchSize).Take(options.BatchSize); Response <DigitalTwinsModelData[]> response = await client.CreateModelsAsync(batch.Select(i => i.GetJsonLdText())); foreach (DTInterfaceInfo @interface in batch) { Log.Ok(@interface.Id.AbsoluteUri); } } } catch (Exception ex) { Log.Error($"Upload failed."); Log.Error(ex.Message); } }
public async Task Models_Lifecycle() { DigitalTwinsClient client = GetClient(); string buildingModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.BuildingModelId).ConfigureAwait(false); string floorModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.FloorModelId).ConfigureAwait(false); string hvacModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.HvacModelId).ConfigureAwait(false); string wardModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.WardModelId).ConfigureAwait(false); try { string modelBuilding = TestAssetsHelper.GetBuildingModelPayload(buildingModelId, hvacModelId, floorModelId); string modelHvac = TestAssetsHelper.GetHvacModelPayload(hvacModelId, floorModelId); string modelWard = TestAssetsHelper.GetWardModelPayload(wardModelId); // CREATE models var modelsList = new List <string> { modelBuilding, modelHvac, modelWard }; await client.CreateModelsAsync(modelsList).ConfigureAwait(false); // GET one created model Response <DigitalTwinsModelData> buildingModel = await client.GetModelAsync(buildingModelId).ConfigureAwait(false); Console.WriteLine($"Got {buildingModelId} as {buildingModel.Value.DtdlModel}"); // LIST all models AsyncPageable <DigitalTwinsModelData> models = client.GetModelsAsync(); await foreach (DigitalTwinsModelData model in models) { Console.WriteLine($"{model.Id}"); } // DECOMMISSION a model await client.DecommissionModelAsync(buildingModelId).ConfigureAwait(false); } finally { // Test DELETE all models. try { await client.DeleteModelAsync(buildingModelId).ConfigureAwait(false); await client.DeleteModelAsync(hvacModelId).ConfigureAwait(false); await client.DeleteModelAsync(wardModelId).ConfigureAwait(false); } catch (Exception ex) { Assert.Fail($"Test clean up failed: {ex.Message}"); } } }
public ActionResult Upload(string instanceUrl, string tenantId, string clientId, string secret) { ADTModel adtModel = new ADTModel { InstanceUrl = instanceUrl, TenantId = tenantId, ClientId = clientId, Secret = secret }; try { // login to Azure using the Environment variables mechanism of DefaultAzureCredential Environment.SetEnvironmentVariable("AZURE_CLIENT_ID", clientId); Environment.SetEnvironmentVariable("AZURE_TENANT_ID", tenantId); Environment.SetEnvironmentVariable("AZURE_CLIENT_SECRET", secret); // create ADT client instance DigitalTwinsClient client = new DigitalTwinsClient(new Uri(instanceUrl), new DefaultAzureCredential(new DefaultAzureCredentialOptions { ExcludeVisualStudioCodeCredential = true })); // read generated DTDL models List <string> dtdlModels = new List <string>(); foreach (string dtdlFilePath in Directory.EnumerateFiles(Path.Combine(Directory.GetCurrentDirectory(), "JSON"), "*.dtdl.json")) { dtdlModels.Add(System.IO.File.ReadAllText(dtdlFilePath)); } // upload Azure.Response <DigitalTwinsModelData[]> response = client.CreateModelsAsync(dtdlModels).GetAwaiter().GetResult(); // clear secret Environment.SetEnvironmentVariable("AZURE_CLIENT_SECRET", ""); if (response.GetRawResponse().Status == 201) { adtModel.StatusMessage = "Upload successful!"; return(View("Index", adtModel)); } else { adtModel.StatusMessage = response.GetRawResponse().ReasonPhrase; return(View("Index", adtModel)); } } catch (Exception ex) { // clear secret Environment.SetEnvironmentVariable("AZURE_CLIENT_SECRET", ""); adtModel.StatusMessage = ex.Message; return(View("Index", adtModel)); } }
public static async Task CreateModels(DigitalTwinsClient client) { List <string> paths = new List <string>(); bool loop = true; while (loop) { Console.WriteLine("0 = Exit \r\n1 = Add full path to file"); Console.Write("Command: "); string s = Console.ReadLine(); if (s.Contains("1")) { Console.Write("Full path: "); s = Console.ReadLine(); paths.Add(s); } else { loop = false; } } if (paths.Count < 1) { Console.WriteLine("Please supply at least one model file name to upload to the service"); return; } try { List <string> dtdlList = new List <string>(); paths.ForEach(delegate(string filename) { StreamReader r = new StreamReader(filename); string dtdl = r.ReadToEnd(); r.Close(); dtdlList.Add(dtdl); }); Response <ModelData[]> res = await client.CreateModelsAsync(dtdlList); Console.WriteLine($"Model(s) created successfully!"); foreach (ModelData md in res.Value) { Console.WriteLine(md.Model); } } catch (RequestFailedException e) { Console.WriteLine($"Response {e.Status}: {e.Message}"); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } }
async public void CreateModelSingleAsync(string fileName, DigitalTwinsClient client) { // ------------------ CREATE MODEL (SINGLE) --------------------- // <CreateModel> // 'client' is an instance of DigitalTwinsClient // Read model file into string (not part of SDK) // fileName is the name of the JSON model file string dtdl = File.ReadAllText(fileName); await client.CreateModelsAsync(new[] { dtdl }); // </CreateModel> }
// This method is used as a helper method to accommodate for the lag on the service side between creating a new // model and creating a digital twin that implements this model. The work around is to list the model(s) after // creating them in order to accommodate for that lag. Once service side investigates and comes up with a solution, // there is no need to list the models after creating them. protected async Task CreateAndListModelsAsync(DigitalTwinsClient client, List <string> lists) { await client.CreateModelsAsync(lists).ConfigureAwait(false); // list the models AsyncPageable <DigitalTwinsModelData> models = client.GetModelsAsync(); await foreach (DigitalTwinsModelData model in models) { Console.WriteLine($"{model.Id}"); } }
public async Task Query_ValidQuery_Success() { DigitalTwinsClient client = GetClient(); string floorModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.FloorModelIdPrefix).ConfigureAwait(false); string roomModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.RoomModelIdPrefix).ConfigureAwait(false); try { // arrange // Create room model string roomModel = TestAssetsHelper.GetRoomModelPayload(roomModelId, floorModelId); await client.CreateModelsAsync(new List <string> { roomModel }).ConfigureAwait(false); // Create a room twin, with property "IsOccupied": true string roomTwinId = await GetUniqueTwinIdAsync(client, TestAssetDefaults.RoomTwinIdPrefix).ConfigureAwait(false); string roomTwin = TestAssetsHelper.GetRoomTwinPayload(roomModelId); await client.CreateDigitalTwinAsync(roomTwinId, roomTwin).ConfigureAwait(false); string queryString = "SELECT * FROM digitaltwins where IsOccupied = true"; // act AsyncPageable <string> asyncPageableResponse = client.QueryAsync(queryString); // assert await foreach (string response in asyncPageableResponse) { JsonElement jsonElement = JsonSerializer.Deserialize <JsonElement>(response); JsonElement isOccupied = jsonElement.GetProperty("IsOccupied"); isOccupied.GetRawText().Should().Be("true"); } } finally { // clean up try { if (!string.IsNullOrWhiteSpace(roomModelId)) { await client.DeleteModelAsync(roomModelId).ConfigureAwait(false); } } catch (Exception ex) { Assert.Fail($"Test clean up failed: {ex.Message}"); } } }
public async Task DigitalTwins_CreateOrReplaceTwinFailsWhenIfNoneMatchStar() { DigitalTwinsClient client = GetClient(); string roomTwinId = await GetUniqueTwinIdAsync(client, TestAssetDefaults.RoomTwinIdPrefix).ConfigureAwait(false); string floorModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.FloorModelIdPrefix).ConfigureAwait(false); string roomModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.RoomModelIdPrefix).ConfigureAwait(false); try { // arrange // create room model string roomModel = TestAssetsHelper.GetRoomModelPayload(roomModelId, floorModelId); await client.CreateModelsAsync(new List <string> { roomModel }).ConfigureAwait(false); // act // create room twin BasicDigitalTwin roomTwin = TestAssetsHelper.GetRoomTwinPayload(roomModelId); await client.CreateOrReplaceDigitalTwinAsync <BasicDigitalTwin>(roomTwinId, roomTwin).ConfigureAwait(false); // act Func <Task> act = async() => { // "ifNoneMatch = *" header should cause the server to throw 412 since an entity does match await client.CreateOrReplaceDigitalTwinAsync <BasicDigitalTwin>(roomTwinId, roomTwin, ETag.All).ConfigureAwait(false); }; // assert act.Should().Throw <RequestFailedException>() .And.Status.Should().Be((int)HttpStatusCode.PreconditionFailed); } finally { // cleanup try { if (!string.IsNullOrWhiteSpace(roomModelId)) { await client.DeleteModelAsync(roomModelId).ConfigureAwait(false); } } catch (Exception ex) { Assert.Fail($"Test clean up failed: {ex.Message}"); } } }
public static async Task CreateRoomModelAsync(DigitalTwinsClient client) { try { await client.CreateModelsAsync(new List <string> { GetRoomModel() }).ConfigureAwait(false); } catch (RequestFailedException ex) when(ex.Status == (int)HttpStatusCode.Conflict) { Console.WriteLine("Model already exists"); } }
async public void Run(DigitalTwinsClient client) { // <ClientExcerptModel> 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); // </ClientExcerptModel> }
public async Task Models_ModelAlreadyExists_ThrowsConflictException() { // arrange DigitalTwinsClient client = GetClient(); string wardModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.WardModelId).ConfigureAwait(false); string modelWard = TestAssetsHelper.GetWardModelPayload(wardModelId); var modelsList = new List <string> { modelWard }; // Create model once await client.CreateModelsAsync(modelsList).ConfigureAwait(false); // act Func <Task> act = async() => await client.CreateModelsAsync(modelsList).ConfigureAwait(false); // assert act.Should().Throw <RequestFailedException>() .And.Status.Should().Be((int)HttpStatusCode.Conflict); }
public async Task DigitalTwins_CreateOrReplaceTwinSucceedsWithNoIfNoneMatchHeader() { DigitalTwinsClient client = GetClient(); string roomTwinId = await GetUniqueTwinIdAsync(client, TestAssetDefaults.RoomTwinIdPrefix).ConfigureAwait(false); string floorModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.FloorModelIdPrefix).ConfigureAwait(false); string roomModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.RoomModelIdPrefix).ConfigureAwait(false); try { // arrange // create room model string roomModel = TestAssetsHelper.GetRoomModelPayload(roomModelId, floorModelId); await client.CreateModelsAsync(new List <string> { roomModel }).ConfigureAwait(false); // act // create room twin BasicDigitalTwin roomTwin = TestAssetsHelper.GetRoomTwinPayload(roomModelId); await client.CreateOrReplaceDigitalTwinAsync <BasicDigitalTwin>(roomTwinId, roomTwin).ConfigureAwait(false); // Deliberately not passing in ifNoneMatch header, request should succeed because of that await client.CreateOrReplaceDigitalTwinAsync <BasicDigitalTwin>(roomTwinId, roomTwin).ConfigureAwait(false); } catch (RequestFailedException ex) when(ex.Status == (int)HttpStatusCode.PreconditionFailed) { throw new AssertionException("CreateOrReplaceDigitalTwin should not fail with PreconditionFailed when ifNoneMatch header wasn't set", ex); } finally { // cleanup try { if (!string.IsNullOrWhiteSpace(roomModelId)) { await client.DeleteModelAsync(roomModelId).ConfigureAwait(false); } } catch (Exception ex) { Assert.Fail($"Test clean up failed: {ex.Message}"); } } }
async public void CreateModelMultiple(DigitalTwinsClient client, string sourceDirectory) { // ------------------ CREATE MODEL (MULTIPLE) --------------------- // <CreateModels_multi> var dtdlFiles = Directory.EnumerateFiles(sourceDirectory, "*.json"); var dtdlModels = new List <string>(); foreach (string fileName in dtdlFiles) { // Read model file into string (not part of SDK) string dtdl = File.ReadAllText(fileName); dtdlModels.Add(dtdl); } await client.CreateModelsAsync(dtdlModels); // </CreateModels_multi> }
private async Task CreateModelsAndTwins(DigitalTwinsClient client, string wifiModelId, string roomWithWifiModelId, string wifiComponentName, string roomWithWifiTwinId) { // Generate the payload needed to create the WiFi component model. string wifiModel = TestAssetsHelper.GetWifiModelPayload(wifiModelId); // Generate the payload needed to create the room with WiFi model. string roomWithWifiModel = TestAssetsHelper.GetRoomWithWifiModelPayload(roomWithWifiModelId, wifiModelId, wifiComponentName); // Create the room and WiFi models. await client.CreateModelsAsync(new List <string> { roomWithWifiModel, wifiModel }).ConfigureAwait(false); // Generate the payload needed to create the room with WiFi twin. BasicDigitalTwin roomWithWifiTwin = TestAssetsHelper.GetRoomWithWifiTwinPayload(roomWithWifiModelId, wifiComponentName); // Create the room with WiFi component digital twin. await client.CreateDigitalTwinAsync <BasicDigitalTwin>(roomWithWifiTwinId, roomWithWifiTwin).ConfigureAwait(false); }
public async Task UploadModelsAsync() { var appDir = Path.Combine(Directory.GetCurrentDirectory(), @"Models"); var models = new List <string>(); foreach (var file in Directory.EnumerateFiles(appDir, "*.json")) { var contents = File.ReadAllText(file); models.Add(contents); } var response = await _client.CreateModelsAsync(models); foreach (var model in response.Value) { _logger.LogInformation($"Model {model.Id} uploaded on {model.UploadedOn}"); } }
public async Task DigitalTwinOperationsWithCustomObjectSerializer_Succeeds() { // arrange var serializer = new TestObjectSerializer(); DigitalTwinsClientOptions options = new DigitalTwinsClientOptions { Serializer = serializer }; DigitalTwinsClient client = GetClient(options); serializer.WasDeserializeCalled.Should().BeFalse(); serializer.WasSerializeCalled.Should().BeFalse(); string roomTwinId = await GetUniqueTwinIdAsync(client, TestAssetDefaults.RoomTwinIdPrefix).ConfigureAwait(false); string floorModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.FloorModelIdPrefix).ConfigureAwait(false); string roomModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.RoomModelIdPrefix).ConfigureAwait(false); // create room model string roomModel = TestAssetsHelper.GetRoomModelPayload(roomModelId, floorModelId); await client.CreateModelsAsync(new List <string> { roomModel }).ConfigureAwait(false); // act // create room twin BasicDigitalTwin roomTwin = TestAssetsHelper.GetRoomTwinPayload(roomModelId); await client.CreateOrReplaceDigitalTwinAsync(roomTwinId, roomTwin).ConfigureAwait(false); roomTwin = await client.GetDigitalTwinAsync <BasicDigitalTwin>(roomTwinId).ConfigureAwait(false); // assert roomTwin.Should().NotBeNull(); serializer.WasDeserializeCalled.Should().BeTrue(); serializer.WasSerializeCalled.Should().BeTrue(); }
public async Task ModelData_DisplayNameAndDescription_Deserializes() { // arrange DigitalTwinsClient client = GetClient(); string wardModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.WardModelId).ConfigureAwait(false); // add a model with a single value for displayName and for description, neither of which were defined as a map string modelWard = TestAssetsHelper.GetWardModelPayload(wardModelId); await client.CreateModelsAsync(new[] { modelWard }).ConfigureAwait(false); // act // should not throw on deserialization Response <DigitalTwinsModelData> wardModel = await client.GetModelAsync(wardModelId).ConfigureAwait(false); // assert wardModel.Value.DisplayName.Count.Should().Be(1, "Should have 1 entry for display name"); wardModel.Value.DisplayName.Keys.First().Should().Be("en"); }
/// <summary> /// Create a temporary component model, twin model and digital twin instance. /// Publish a telemetry message and a component telemetry message to the digital twin instance. /// </summary> public async Task RunSamplesAsync(DigitalTwinsClient client) { PrintHeader("PUBLISH TELEMETRY MESSAGE SAMPLE"); // For the purpose of this example we will create temporary models using a random model Ids. // We will also create temporary twin instances to publish the telemetry to. string componentModelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryComponentModelPrefix, client); string modelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryModelPrefix, client); string twinId = await GetUniqueTwinIdAsync(SamplesConstants.TemporaryTwinPrefix, client); string newComponentModelPayload = SamplesConstants.TemporaryComponentModelPayload .Replace(SamplesConstants.ComponentId, componentModelId); string newModelPayload = SamplesConstants.TemporaryModelWithComponentPayload .Replace(SamplesConstants.ModelId, modelId) .Replace(SamplesConstants.ComponentId, componentModelId); // Then we create the models. await client .CreateModelsAsync(new[] { newComponentModelPayload, newModelPayload }); // Get the models we just created AsyncPageable <DigitalTwinsModelData> models = client.GetModelsAsync(); await foreach (DigitalTwinsModelData model in models) { Console.WriteLine($"Successfully created model '{model.Id}'"); } // Create digital twin with Component payload. string twinPayload = SamplesConstants.TemporaryTwinPayload .Replace(SamplesConstants.ModelId, modelId); BasicDigitalTwin basicDigitalTwin = JsonSerializer.Deserialize <BasicDigitalTwin>(twinPayload); Response <BasicDigitalTwin> createDigitalTwinResponse = await client.CreateOrReplaceDigitalTwinAsync <BasicDigitalTwin>(twinId, basicDigitalTwin); Console.WriteLine($"Created digital twin '{createDigitalTwinResponse.Value.Id}'."); try { #region Snippet:DigitalTwinsSamplePublishTelemetry // construct your json telemetry payload by hand. await client.PublishTelemetryAsync(twinId, Guid.NewGuid().ToString(), "{\"Telemetry1\": 5}"); Console.WriteLine($"Published telemetry message to twin '{twinId}'."); #endregion Snippet:DigitalTwinsSamplePublishTelemetry #region Snippet:DigitalTwinsSamplePublishComponentTelemetry // construct your json telemetry payload by serializing a dictionary. var telemetryPayload = new Dictionary <string, int> { { "ComponentTelemetry1", 9 } }; await client.PublishComponentTelemetryAsync( twinId, "Component1", Guid.NewGuid().ToString(), JsonSerializer.Serialize(telemetryPayload)); Console.WriteLine($"Published component telemetry message to twin '{twinId}'."); #endregion Snippet:DigitalTwinsSamplePublishComponentTelemetry } catch (Exception ex) { FatalError($"Failed to publish a telemetry message due to: {ex.Message}"); } try { // Delete the twin. await client.DeleteDigitalTwinAsync(twinId); // Delete the models. await client.DeleteModelAsync(modelId); await client.DeleteModelAsync(componentModelId); } catch (RequestFailedException ex) when(ex.Status == (int)HttpStatusCode.NotFound) { // Digital twin or models do not exist. } catch (RequestFailedException ex) { FatalError($"Failed to delete due to: {ex.Message}"); } }
public async Task Component_Lifecycle() { // arrange DigitalTwinsClient client = GetClient(); string wifiModelId = await GetUniqueModelIdAsync(client, TestAssetSettings.WifiModelIdPrefix).ConfigureAwait(false); string roomWithWifiModelId = await GetUniqueModelIdAsync(client, TestAssetSettings.RoomWithWifiModelIdPrefix).ConfigureAwait(false); string roomWithWifiTwinId = await GetUniqueTwinIdAsync(client, TestAssetSettings.RoomWithWifiTwinIdPrefix).ConfigureAwait(false); string wifiComponentName = "wifiAccessPoint"; try { // CREATE // create roomWithWifi model string wifiModel = TestAssetsHelper.GetWifiModelPayload(wifiModelId); // create wifi model string roomWithWifiModel = TestAssetsHelper.GetRoomWithWifiModelPayload(roomWithWifiModelId, wifiModelId, wifiComponentName); await client.CreateModelsAsync(new List <string> { roomWithWifiModel, wifiModel }).ConfigureAwait(false); // create room digital twin string roomWithWifiTwin = TestAssetsHelper.GetRoomWithWifiTwinPayload(roomWithWifiModelId, wifiModelId, wifiComponentName); await client.CreateDigitalTwinAsync(roomWithWifiTwinId, roomWithWifiTwin); // Get the component Response <string> getComponentResponse = await client .GetComponentAsync( roomWithWifiTwinId, wifiComponentName) .ConfigureAwait(false); // The response to the GET request should be 200 (OK) getComponentResponse.GetRawResponse().Status.Should().Be((int)HttpStatusCode.OK); // Patch component Response <string> updateComponentResponse = await client .UpdateComponentAsync( roomWithWifiTwinId, wifiComponentName, TestAssetsHelper.GetWifiComponentUpdatePayload()) .ConfigureAwait(false); // The response to the Patch request should be 204 (No content) updateComponentResponse.GetRawResponse().Status.Should().Be((int)HttpStatusCode.NoContent); } finally { // clean up try { if (!string.IsNullOrWhiteSpace(roomWithWifiTwinId)) { await client.DeleteDigitalTwinAsync(roomWithWifiTwinId).ConfigureAwait(false); } if (!string.IsNullOrWhiteSpace(roomWithWifiModelId)) { await client.DeleteModelAsync(roomWithWifiModelId).ConfigureAwait(false); } if (!string.IsNullOrWhiteSpace(wifiModelId)) { await client.DeleteModelAsync(wifiModelId).ConfigureAwait(false); } } catch (Exception ex) { Assert.Fail($"Test clean up failed: {ex.Message}"); } } }
static async Task Main(string[] args) { Console.WriteLine("Hello World!"); string adtInstanceUrl = "<youradturl>"; var credential = new DefaultAzureCredential(); DigitalTwinsClient client = new DigitalTwinsClient(new Uri(adtInstanceUrl), credential); Console.WriteLine($"Service client created – ready to go"); // uploading data Console.WriteLine(); Console.WriteLine($"Upload a model"); var typeList = new List <string>(); string dtdl = File.ReadAllText("new.json"); typeList.Add(dtdl); // Upload the model to the service try { await client.CreateModelsAsync(typeList); } catch (RequestFailedException rex) { Console.WriteLine($"Load model: {rex.Status}:{rex.Message}"); } // now lets add more models based on the one just uploaded // Initialize twin data BasicDigitalTwin 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: {prefix}{i}"); } catch (RequestFailedException rex) { Console.WriteLine($"Create twin error: {rex.Status}:{rex.Message}"); } } // Connect the twins with relationships await CreateRelationship(client, "sampleTwin-0", "sampleTwin-1"); await CreateRelationship(client, "sampleTwin-0", "sampleTwin-2"); //List the relationships await ListRelationships(client, "sampleTwin-0"); // Run a query for all twins string query = "SELECT * FROM digitaltwins"; AsyncPageable <BasicDigitalTwin> result = client.QueryAsync <BasicDigitalTwin>(query); Console.WriteLine("---------------"); await foreach (BasicDigitalTwin twin in result) { Console.WriteLine(JsonSerializer.Serialize(twin)); Console.WriteLine("---------------"); } }
/// <summary> /// Creates a new model with a random Id /// Decommission the newly created model and check for success /// </summary> public async Task RunSamplesAsync(DigitalTwinsClient client) { PrintHeader("MODEL LIFECYCLE SAMPLE"); // For the purpose of this example we will create temporary models using random model Ids and then decommission a model. // We have to make sure these model Ids are unique within the DT instance. string newComponentModelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryComponentModelPrefix, client); string sampleModelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryModelPrefix, client); string newComponentModelPayload = SamplesConstants.TemporaryComponentModelPayload .Replace(SamplesConstants.ComponentId, newComponentModelId); string newModelPayload = SamplesConstants.TemporaryModelWithComponentPayload .Replace(SamplesConstants.ModelId, sampleModelId) .Replace(SamplesConstants.ComponentId, newComponentModelId); // Then we create the model try { #region Snippet:DigitalTwinsSampleCreateModels Response <IReadOnlyList <ModelData> > response = await client.CreateModelsAsync(new[] { newComponentModelPayload, newModelPayload }); Console.WriteLine($"Successfully created a model with Id: {newComponentModelId}, {sampleModelId}, status: {response.GetRawResponse().Status}"); #endregion Snippet:DigitalTwinsSampleCreateModels } catch (RequestFailedException ex) when(ex.Status == (int)HttpStatusCode.Conflict) { Console.WriteLine($"One or more models already existed."); } catch (Exception ex) { FatalError($"Failed to create models due to:\n{ex}"); } // Get Model try { #region Snippet:DigitalTwinsSampleGetModel Response <ModelData> sampleModel = await client.GetModelAsync(sampleModelId); #endregion Snippet:DigitalTwinsSampleGetModel Console.WriteLine($"{sampleModel.Value.Id} has decommission status of {sampleModel.Value.Decommissioned}"); } catch (Exception ex) { FatalError($"Failed to get a model due to:\n{ex}"); } // Now we decommission the model #region Snippet:DigitalTwinsSampleDecommisionModel try { await client.DecommissionModelAsync(sampleModelId); Console.WriteLine($"Successfully decommissioned model {sampleModelId}"); } catch (RequestFailedException ex) { FatalError($"Failed to decommision model {sampleModelId} due to:\n{ex}"); } #endregion Snippet:DigitalTwinsSampleDecommisionModel // Now delete created model #region Snippet:DigitalTwinsSampleDeleteModel try { await client.DeleteModelAsync(sampleModelId); Console.WriteLine($"Deleted model {sampleModelId}"); } catch (Exception ex) { FatalError($"Failed to delete model {sampleModelId} due to:\n{ex}"); } #endregion Snippet:DigitalTwinsSampleDeleteModel }
public async Task CreateHouseTwin() { try { List <string> dtdlList = ParseDTDLModels(); Response <ModelData[]> res = await _client.CreateModelsAsync(dtdlList); Console.WriteLine($"Model(s) created successfully!"); } catch (RequestFailedException e) { Console.WriteLine($"Response {e.Status}: {e.Message}"); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } var metaData = new Dictionary <string, object>() { { "$model", "dtmi:demo:House;1" }, { "$kind", "DigitalTwin" } }; var twinData = new Dictionary <string, object>() { { "$metadata", metaData }, { "ConstructionYear", "1985" }, { "Owner", "Glenn Colpaert" } }; await _client.CreateDigitalTwinAsync("127.0.0.1", JsonSerializer.Serialize(twinData)); Console.WriteLine($"Localhost Twin created successfully!"); metaData = new Dictionary <string, object>() { { "$model", "dtmi:demo:Floor;1" }, { "$kind", "DigitalTwin" } }; twinData = new Dictionary <string, object>() { { "$metadata", metaData } }; await _client.CreateDigitalTwinAsync("Floor1", JsonSerializer.Serialize(twinData)); Console.WriteLine($"Floor1 Twin created successfully!"); await _client.CreateDigitalTwinAsync("Floor2", JsonSerializer.Serialize(twinData)); Console.WriteLine($"Floor2 Twin created successfully!"); await _client.CreateDigitalTwinAsync("Floor3", JsonSerializer.Serialize(twinData)); Console.WriteLine($"Floor3 Twin created successfully!"); metaData = new Dictionary <string, object>() { { "$model", "dtmi:demo:Room;1" }, { "$kind", "DigitalTwin" } }; twinData = new Dictionary <string, object>() { { "$metadata", metaData } }; await _client.CreateDigitalTwinAsync("Kitchen", JsonSerializer.Serialize(twinData)); Console.WriteLine($"Kitchen Twin created successfully!"); await _client.CreateDigitalTwinAsync("LivingRoom", JsonSerializer.Serialize(twinData)); Console.WriteLine($"LivingRoom Twin created successfully!"); await _client.CreateDigitalTwinAsync("Bedroom1", JsonSerializer.Serialize(twinData)); Console.WriteLine($"Bedroom1 Twin created successfully!"); await _client.CreateDigitalTwinAsync("Bedroom2", JsonSerializer.Serialize(twinData)); Console.WriteLine($"Bedroom2 Twin created successfully!"); await _client.CreateDigitalTwinAsync("Bathroom", JsonSerializer.Serialize(twinData)); Console.WriteLine($"Bathroom Twin created successfully!"); await _client.CreateDigitalTwinAsync("MasterBedroom", JsonSerializer.Serialize(twinData)); Console.WriteLine($"MasterBedroom Twin created successfully!"); metaData = new Dictionary <string, object>() { { "$model", "dtmi:demo:Sensor;1" }, { "$kind", "DigitalTwin" } }; //Yes you have to initialize Temp and Hum as default //Unless you do an add (instead of replace) as update operation to the query interface. twinData = new Dictionary <string, object>() { { "$metadata", metaData }, { "FirmwareVersion", "2020.ADT.5782.3" } //, // { "Temperature", 0 }, // { "Humidity", 0}, }; await _client.CreateDigitalTwinAsync("TStat001", JsonSerializer.Serialize(twinData)); Console.WriteLine($"TStat001 Twin created successfully!"); await _client.CreateDigitalTwinAsync("TStat002", JsonSerializer.Serialize(twinData)); Console.WriteLine($"TStat002 Twin created successfully!"); await _client.CreateDigitalTwinAsync("TStat003", JsonSerializer.Serialize(twinData)); Console.WriteLine($"TStat003 Twin created successfully!"); await _client.CreateDigitalTwinAsync("TStat004", JsonSerializer.Serialize(twinData)); Console.WriteLine($"TStat004 Twin created successfully!"); await _client.CreateDigitalTwinAsync("TStat005", JsonSerializer.Serialize(twinData)); Console.WriteLine($"TStat005 Twin created successfully!"); var body = new Dictionary <string, object>() { { "$targetId", "Floor1" }, { "$relationshipName", "floors" } }; await _client.CreateRelationshipAsync("127.0.0.1", "localhost_to_Floor1", JsonSerializer.Serialize(body)); Console.WriteLine($"Relationship localhost_to_Floor1 created successfully!"); body = new Dictionary <string, object>() { { "$targetId", "Floor2" }, { "$relationshipName", "floors" } }; await _client.CreateRelationshipAsync("127.0.0.1", "localhost_to_floor2", JsonSerializer.Serialize(body)); Console.WriteLine($"Relationship localhost_to_floor2 created successfully!"); body = new Dictionary <string, object>() { { "$targetId", "Floor3" }, { "$relationshipName", "floors" } }; await _client.CreateRelationshipAsync("127.0.0.1", "localhost_to_floor3", JsonSerializer.Serialize(body)); Console.WriteLine($"Relationship localhost_to_floor3 created successfully!"); body = new Dictionary <string, object>() { { "$targetId", "Kitchen" }, { "$relationshipName", "rooms" } }; await _client.CreateRelationshipAsync("Floor1", "Floor1_to_kitchen", JsonSerializer.Serialize(body)); Console.WriteLine($"Relationship Floor1_to_kitchen created successfully!"); body = new Dictionary <string, object>() { { "$targetId", "LivingRoom" }, { "$relationshipName", "rooms" } }; await _client.CreateRelationshipAsync("Floor1", "Floor1_to_livingroom", JsonSerializer.Serialize(body)); Console.WriteLine($"Relationship Floor1_to_livingroom created successfully!"); body = new Dictionary <string, object>() { { "$targetId", "Bathroom" }, { "$relationshipName", "rooms" } }; await _client.CreateRelationshipAsync("Floor2", "floor2_to_bathroom", JsonSerializer.Serialize(body)); Console.WriteLine($"Relationship floor2_to_bathroom created successfully!"); body = new Dictionary <string, object>() { { "$targetId", "Bedroom1" }, { "$relationshipName", "rooms" } }; await _client.CreateRelationshipAsync("Floor2", "floor2_to_bedroom1", JsonSerializer.Serialize(body)); Console.WriteLine($"Relationship floor2_to_bedroom1 created successfully!"); body = new Dictionary <string, object>() { { "$targetId", "Bedroom2" }, { "$relationshipName", "rooms" } }; await _client.CreateRelationshipAsync("Floor2", "floor2_to_bedroom2", JsonSerializer.Serialize(body)); Console.WriteLine($"Relationship floor2_to_bedroom2 created successfully!"); body = new Dictionary <string, object>() { { "$targetId", "MasterBedroom" }, { "$relationshipName", "rooms" } }; await _client.CreateRelationshipAsync("Floor3", "floor3_to_masterbedroom", JsonSerializer.Serialize(body)); Console.WriteLine($"Relationship floor3_to_masterbedroom created successfully!"); body = new Dictionary <string, object>() { { "$targetId", "TStat001" }, { "$relationshipName", "sensors" } }; await _client.CreateRelationshipAsync("Kitchen", "kitchen_to_tstat001", JsonSerializer.Serialize(body)); Console.WriteLine($"Relationship kitchen_to_tstat001 created successfully!"); body = new Dictionary <string, object>() { { "$targetId", "TStat001" }, { "$relationshipName", "sensors" } }; await _client.CreateRelationshipAsync("LivingRoom", "livingroom_to_tstat001", JsonSerializer.Serialize(body)); Console.WriteLine($"Relationship LivingRoom_to_tstat001 created successfully!"); body = new Dictionary <string, object>() { { "$targetId", "TStat002" }, { "$relationshipName", "sensors" } }; await _client.CreateRelationshipAsync("Bedroom1", "bedroom_to_tstat002", JsonSerializer.Serialize(body)); Console.WriteLine($"Relationship bedroom_to_tstat002 created successfully!"); body = new Dictionary <string, object>() { { "$targetId", "TStat003" }, { "$relationshipName", "sensors" } }; await _client.CreateRelationshipAsync("Bedroom2", "bedroom2_to_tstat003", JsonSerializer.Serialize(body)); Console.WriteLine($"Relationship bedroom2_to_tstat003 created successfully!"); body = new Dictionary <string, object>() { { "$targetId", "TStat004" }, { "$relationshipName", "sensors" } }; await _client.CreateRelationshipAsync("Bathroom", "bathroom_to_tstat004", JsonSerializer.Serialize(body)); Console.WriteLine($"Relationship bathroom_to_tstat004 created successfully!"); body = new Dictionary <string, object>() { { "$targetId", "TStat005" }, { "$relationshipName", "sensors" } }; await _client.CreateRelationshipAsync("MasterBedroom", "masterbedroom_to_tstat005", JsonSerializer.Serialize(body)); Console.WriteLine($"Relationship masterbedroom_to_tstat005 created successfully!"); }
/// <summary> /// Creates two digital twins, and connect them with relationships. /// </summary> public async Task RunSamplesAsync(DigitalTwinsClient client) { // For the purpose of keeping code snippets readable to the user, hardcoded string literals are used in place of assigned variables, eg Ids. // Despite not being a good code practice, this prevents code snippets from being out of context for the user when making API calls that accept Ids as parameters. PrintHeader("RELATIONSHIP SAMPLE"); // Create a building digital twin model. string buildingModelPayload = SamplesConstants.TemporaryModelWithRelationshipPayload .Replace(SamplesConstants.ModelId, "dtmi:samples:SampleBuilding;1") .Replace(SamplesConstants.ModelDisplayName, "Building") .Replace(SamplesConstants.RelationshipName, "contains") .Replace(SamplesConstants.RelationshipTargetModelId, "dtmi:samples:SampleFloor;1"); Response <IReadOnlyList <Models.ModelData> > createBuildingModelResponse = await client.CreateModelsAsync( new[] { buildingModelPayload }); Console.WriteLine($"Created model with Id dtmi:samples:SampleBuilding;1. Response status: {createBuildingModelResponse.GetRawResponse().Status}."); // Create a floor digital twin model. string floorModelPayload = SamplesConstants.TemporaryModelWithRelationshipPayload .Replace(SamplesConstants.ModelId, "dtmi:samples:SampleFloor;1") .Replace(SamplesConstants.ModelDisplayName, "Floor") .Replace(SamplesConstants.RelationshipName, "containedIn") .Replace(SamplesConstants.RelationshipTargetModelId, "dtmi:samples:SampleBuilding;1"); Response <IReadOnlyList <Models.ModelData> > createFloorModelResponse = await client.CreateModelsAsync( new[] { floorModelPayload }); Console.WriteLine($"Created model with Id dtmi:samples:SampleFloor;1. Response status: {createFloorModelResponse.GetRawResponse().Status}."); // Create a building digital twin. var buildingDigitalTwin = new BasicDigitalTwin { Id = "buildingTwinId", Metadata = { ModelId = "dtmi:samples:SampleBuilding;1" } }; string buildingDigitalTwinPayload = JsonSerializer.Serialize(buildingDigitalTwin); Response <string> createBuildingDigitalTwinResponse = await client.CreateDigitalTwinAsync("buildingTwinId", buildingDigitalTwinPayload); Console.WriteLine($"Created a digital twin with Id buildingTwinId. Response status: {createBuildingDigitalTwinResponse.GetRawResponse().Status}."); // Create a floor digital. var floorDigitalTwin = new BasicDigitalTwin { Id = "floorTwinId", Metadata = { ModelId = "dtmi:samples:SampleFloor;1" } }; string floorDigitalTwinPayload = JsonSerializer.Serialize(floorDigitalTwin); Response <string> createFloorDigitalTwinResponse = await client.CreateDigitalTwinAsync("floorTwinId", floorDigitalTwinPayload); Console.WriteLine($"Created a digital twin with Id floorTwinId. Response status: {createFloorDigitalTwinResponse.GetRawResponse().Status}."); // Create a relationship between building and floor using the BasicRelationship serialization helper. #region Snippet:DigitalTwinsSampleCreateBasicRelationship var buildingFloorRelationshipPayload = new BasicRelationship { Id = "buildingFloorRelationshipId", SourceId = "buildingTwinId", TargetId = "floorTwinId", Name = "contains", CustomProperties = { { "Prop1", "Prop1 value" }, { "Prop2", 6 } } }; string serializedRelationship = JsonSerializer.Serialize(buildingFloorRelationshipPayload); Response <string> createRelationshipResponse = await client.CreateRelationshipAsync("buildingTwinId", "buildingFloorRelationshipId", serializedRelationship); Console.WriteLine($"Created a digital twin relationship with Id buildingFloorRelationshipId from digital twin with Id buildingTwinId to digital twin with Id floorTwinId. " + $"Response status: {createRelationshipResponse.GetRawResponse().Status}."); #endregion Snippet:DigitalTwinsSampleCreateBasicRelationship // You can get a relationship and deserialize it into a BasicRelationship. #region Snippet:DigitalTwinsSampleGetBasicRelationship Response <string> getBasicRelationshipResponse = await client.GetRelationshipAsync("buildingTwinId", "buildingFloorRelationshipId"); if (getBasicRelationshipResponse.GetRawResponse().Status == (int)HttpStatusCode.OK) { BasicRelationship basicRelationship = JsonSerializer.Deserialize <BasicRelationship>(getBasicRelationshipResponse.Value); Console.WriteLine($"Retrieved relationship with Id {basicRelationship.Id} from digital twin with Id {basicRelationship.SourceId}. " + $"Response status: {getBasicRelationshipResponse.GetRawResponse().Status}.\n\t" + $"Prop1: {basicRelationship.CustomProperties["Prop1"]}\n\t" + $"Prop2: {basicRelationship.CustomProperties["Prop2"]}"); } #endregion Snippet:DigitalTwinsSampleGetBasicRelationship // Alternatively, you can create your own custom data types to serialize and deserialize your relationships. // This requires less code or knowledge of the type for interaction. // Create a relationship between floorTwinId and buildingTwinId using a custom data type. #region Snippet:DigitalTwinsSampleCreateCustomRelationship var floorBuildingRelationshipPayload = new CustomRelationship { Id = "floorBuildingRelationshipId", SourceId = "floorTwinId", TargetId = "buildingTwinId", Name = "containedIn", Prop1 = "Prop1 val", Prop2 = 4 }; string serializedCustomRelationship = JsonSerializer.Serialize(floorBuildingRelationshipPayload); Response <string> createCustomRelationshipResponse = await client.CreateRelationshipAsync("floorTwinId", "floorBuildingRelationshipId", serializedCustomRelationship); Console.WriteLine($"Created a digital twin relationship with Id floorBuildingRelationshipId from digital twin with Id floorTwinId to digital twin with Id buildingTwinId. " + $"Response status: {createCustomRelationshipResponse.GetRawResponse().Status}."); #endregion Snippet:DigitalTwinsSampleCreateCustomRelationship // Getting and deserializing a relationship into a custom data type is extremely easy. #region Snippet:DigitalTwinsSampleGetCustomRelationship Response <string> getCustomRelationshipResponse = await client.GetRelationshipAsync("floorTwinId", "floorBuildingRelationshipId"); if (getCustomRelationshipResponse.GetRawResponse().Status == (int)HttpStatusCode.OK) { CustomRelationship getCustomRelationship = JsonSerializer.Deserialize <CustomRelationship>(getCustomRelationshipResponse.Value); Console.WriteLine($"Retrieved and deserialized relationship with Id {getCustomRelationship.Id} from digital twin with Id {getCustomRelationship.SourceId}. " + $"Response status: {getCustomRelationshipResponse.GetRawResponse().Status}.\n\t" + $"Prop1: {getCustomRelationship.Prop1}\n\t" + $"Prop2: {getCustomRelationship.Prop2}"); } #endregion Snippet:DigitalTwinsSampleGetCustomRelationship // Get all relationships in the graph where buildingTwinId is the source of the relationship. #region Snippet:DigitalTwinsSampleGetAllRelationships AsyncPageable <string> relationships = client.GetRelationshipsAsync("buildingTwinId"); await foreach (var relationshipJson in relationships) { BasicRelationship relationship = JsonSerializer.Deserialize <BasicRelationship>(relationshipJson); Console.WriteLine($"Found relationship with Id {relationship.Id} with a digital twin source Id {relationship.SourceId} and " + $"a digital twin target Id {relationship.TargetId}. \n\t " + $"Prop1: {relationship.CustomProperties["Prop1"]}\n\t" + $"Prop2: {relationship.CustomProperties["Prop2"]}"); } #endregion Snippet:DigitalTwinsSampleGetAllRelationships // Get all incoming relationships in the graph where buildingTwinId is the target of the relationship. #region Snippet:DigitalTwinsSampleGetIncomingRelationships AsyncPageable <IncomingRelationship> incomingRelationships = client.GetIncomingRelationshipsAsync("buildingTwinId"); await foreach (IncomingRelationship incomingRelationship in incomingRelationships) { Console.WriteLine($"Found an incoming relationship with Id {incomingRelationship.RelationshipId} coming from a digital twin with Id {incomingRelationship.SourceId}."); } #endregion Snippet:DigitalTwinsSampleGetIncomingRelationships // Delete the contains relationship, created earlier in the sample code, from building to floor. #region Snippet:DigitalTwinsSampleDeleteRelationship Response deleteBuildingRelationshipResponse = await client.DeleteRelationshipAsync("buildingTwinId", "buildingFloorRelationshipId"); Console.WriteLine($"Deleted relationship with Id buildingFloorRelationshipId. Status response: {deleteBuildingRelationshipResponse.Status}."); #endregion Snippet:DigitalTwinsSampleDeleteRelationship // Delete the containedIn relationship, created earlier in the sample code, from floor to building. Response deleteFloorRelationshipResponse = await client.DeleteRelationshipAsync("floorTwinId", "floorBuildingRelationshipId"); Console.WriteLine($"Deleted relationship with Id floorBuildingRelationshipId. Status response: {deleteFloorRelationshipResponse.Status}."); // Clean up. try { // Delete all twins await client.DeleteDigitalTwinAsync("buildingTwinId"); await client.DeleteDigitalTwinAsync("floorTwinId"); } catch (RequestFailedException ex) { Console.WriteLine($"Failed to delete digital twin due to {ex}."); } try { await client.DeleteModelAsync("dtmi:samples:SampleBuilding;1"); await client.DeleteModelAsync("dtmi:samples:SampleFloor;1"); } catch (RequestFailedException ex) { Console.WriteLine($"Failed to delete model due to {ex}."); } }
/// <summary> /// Creates a digital twin with Component and upates Component /// </summary> public async Task RunSamplesAsync(DigitalTwinsClient client) { PrintHeader("COMPONENT SAMPLE"); // For the purpose of this example we will create temporary models using a random model Ids. // We have to make sure these model Ids are unique within the DT instance. string componentModelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryComponentModelPrefix, client); string modelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryModelPrefix, client); string basicDtId = await GetUniqueTwinIdAsync(SamplesConstants.TemporaryTwinPrefix, client); string newComponentModelPayload = SamplesConstants.TemporaryComponentModelPayload .Replace(SamplesConstants.ComponentId, componentModelId); string newModelPayload = SamplesConstants.TemporaryModelWithComponentPayload .Replace(SamplesConstants.ModelId, modelId) .Replace(SamplesConstants.ComponentId, componentModelId); // Then we create models await client.CreateModelsAsync( new[] { newComponentModelPayload, newModelPayload }); Console.WriteLine($"Created models {componentModelId} and {modelId}."); #region Snippet:DigitalTwinsSampleCreateBasicTwin // Create digital twin with component payload using the BasicDigitalTwin serialization helper var basicTwin = new BasicDigitalTwin { Id = basicDtId, // model Id of digital twin Metadata = { ModelId = modelId }, Contents = { // digital twin properties { "Prop1", "Value1" }, { "Prop2", 987 }, // component { "Component1", new BasicDigitalTwinComponent { // component properties Contents = { { "ComponentProp1", "Component value 1" }, { "ComponentProp2", 123 }, }, } }, }, }; Response <BasicDigitalTwin> createDigitalTwinResponse = await client.CreateOrReplaceDigitalTwinAsync(basicDtId, basicTwin); Console.WriteLine($"Created digital twin '{createDigitalTwinResponse.Value.Id}'."); #endregion Snippet:DigitalTwinsSampleCreateBasicTwin // You can also get a digital twin as a BasicDigitalTwin type. // It works well for basic stuff, but as you can see it gets more difficult when delving into // more complex properties, like components. #region Snippet:DigitalTwinsSampleGetBasicDigitalTwin Response <BasicDigitalTwin> getBasicDtResponse = await client.GetDigitalTwinAsync <BasicDigitalTwin>(basicDtId); if (getBasicDtResponse.GetRawResponse().Status == (int)HttpStatusCode.OK) { BasicDigitalTwin basicDt = getBasicDtResponse.Value; // Must cast Component1 as a JsonElement and get its raw text in order to deserialize it as a dictionary string component1RawText = ((JsonElement)basicDt.Contents["Component1"]).GetRawText(); IDictionary <string, object> component1 = JsonSerializer.Deserialize <IDictionary <string, object> >(component1RawText); Console.WriteLine($"Retrieved and deserialized digital twin {basicDt.Id}:\n\t" + $"ETag: {basicDt.ETag}\n\t" + $"Prop1: {basicDt.Contents["Prop1"]}\n\t" + $"Prop2: {basicDt.Contents["Prop2"]}\n\t" + $"ComponentProp1: {component1["ComponentProp1"]}\n\t" + $"ComponentProp2: {component1["ComponentProp2"]}"); } #endregion Snippet:DigitalTwinsSampleGetBasicDigitalTwin string customDtId = await GetUniqueTwinIdAsync(SamplesConstants.TemporaryTwinPrefix, client); // Alternatively, you can create your own custom data types to serialize and deserialize your digital twins. // By specifying your properties and types directly, it requires less code or knowledge of the type for // interaction. #region Snippet:DigitalTwinsSampleCreateCustomTwin var customTwin = new CustomDigitalTwin { Id = customDtId, Metadata = { ModelId = modelId }, Prop1 = "Prop1 val", Prop2 = 987, Component1 = new MyCustomComponent { ComponentProp1 = "Component prop1 val", ComponentProp2 = 123, }, }; Response <CustomDigitalTwin> createCustomDigitalTwinResponse = await client.CreateOrReplaceDigitalTwinAsync(customDtId, customTwin); Console.WriteLine($"Created digital twin '{createCustomDigitalTwinResponse.Value.Id}'."); #endregion Snippet:DigitalTwinsSampleCreateCustomTwin // Getting a digital twin as a custom data type is extremely easy. // Custom types provide the best possible experience. #region Snippet:DigitalTwinsSampleGetCustomDigitalTwin Response <CustomDigitalTwin> getCustomDtResponse = await client.GetDigitalTwinAsync <CustomDigitalTwin>(customDtId); CustomDigitalTwin customDt = getCustomDtResponse.Value; Console.WriteLine($"Retrieved and deserialized digital twin {customDt.Id}:\n\t" + $"ETag: {customDt.ETag}\n\t" + $"Prop1: {customDt.Prop1}\n\t" + $"Prop2: {customDt.Prop2}\n\t" + $"ComponentProp1: {customDt.Component1.ComponentProp1}\n\t" + $"ComponentProp2: {customDt.Component1.ComponentProp2}"); #endregion Snippet:DigitalTwinsSampleGetCustomDigitalTwin #region Snippet:DigitalTwinsSampleUpdateComponent // Update Component1 by replacing the property ComponentProp1 value, // using an optional utility to build the payload. var componentJsonPatchDocument = new JsonPatchDocument(); componentJsonPatchDocument.AppendReplace("/ComponentProp1", "Some new value"); await client.UpdateComponentAsync(basicDtId, "Component1", componentJsonPatchDocument); Console.WriteLine($"Updated component for digital twin '{basicDtId}'."); #endregion Snippet:DigitalTwinsSampleUpdateComponent // Get Component #region Snippet:DigitalTwinsSampleGetComponent await client.GetComponentAsync <MyCustomComponent>(basicDtId, SamplesConstants.ComponentName); Console.WriteLine($"Retrieved component for digital twin '{basicDtId}'."); #endregion Snippet:DigitalTwinsSampleGetComponent // Clean up try { await client.DeleteDigitalTwinAsync(basicDtId); await client.DeleteDigitalTwinAsync(customDtId); } catch (RequestFailedException ex) { Console.WriteLine($"Failed to delete digital twin due to {ex}"); } try { await client.DeleteModelAsync(modelId); await client.DeleteModelAsync(componentModelId); } catch (RequestFailedException ex) { Console.WriteLine($"Failed to delete models due to {ex}"); } }
/// <summary> /// Creates two digital twins, and connect them with relationships. /// </summary> public async Task RunSamplesAsync(DigitalTwinsClient client) { // For the purpose of keeping code snippets readable to the user, hardcoded string literals are used in place of assigned variables, eg Ids. // Despite not being a good code practice, this prevents code snippets from being out of context for the user when making API calls that accept Ids as parameters. PrintHeader("RELATIONSHIP SAMPLE"); string sampleBuildingModelId = "dtmi:com:samples:SampleBuilding;1"; string sampleFloorModelId = "dtmi:com:samples:SampleFloor;1"; await ModelLifecycleSamples.TryDeleteModelAsync(client, sampleBuildingModelId); await ModelLifecycleSamples.TryDeleteModelAsync(client, sampleFloorModelId); // Create a building digital twin model. string buildingModelPayload = SamplesConstants.TemporaryModelWithRelationshipPayload .Replace(SamplesConstants.RelationshipTargetModelId, sampleFloorModelId) .Replace(SamplesConstants.ModelId, sampleBuildingModelId) .Replace(SamplesConstants.ModelDisplayName, "Building") .Replace(SamplesConstants.RelationshipName, "contains"); await client.CreateModelsAsync( new[] { buildingModelPayload }); Console.WriteLine($"Created model '{sampleBuildingModelId}'."); // Create a floor digital twin model. string floorModelPayload = SamplesConstants.TemporaryModelWithRelationshipPayload .Replace(SamplesConstants.RelationshipTargetModelId, sampleBuildingModelId) .Replace(SamplesConstants.ModelId, sampleFloorModelId) .Replace(SamplesConstants.ModelDisplayName, "Floor") .Replace(SamplesConstants.RelationshipName, "containedIn"); await client.CreateModelsAsync(new[] { floorModelPayload }); // Get the model we just created Response <DigitalTwinsModelData> getFloorModelResponse = await client.GetModelAsync(sampleFloorModelId).ConfigureAwait(false); Console.WriteLine($"Created model '{getFloorModelResponse.Value.Id}'"); // Create a building digital twin. var buildingDigitalTwin = new BasicDigitalTwin { Id = "buildingTwinId", Metadata = { ModelId = sampleBuildingModelId } }; Response <BasicDigitalTwin> createDigitalTwinResponse = await client.CreateOrReplaceDigitalTwinAsync <BasicDigitalTwin>("buildingTwinId", buildingDigitalTwin); Console.WriteLine($"Created twin '{createDigitalTwinResponse.Value.Id}'."); // Create a floor digital. var floorDigitalTwin = new BasicDigitalTwin { Id = "floorTwinId", Metadata = { ModelId = sampleFloorModelId } }; Response <BasicDigitalTwin> createFloorDigitalTwinResponse = await client.CreateOrReplaceDigitalTwinAsync <BasicDigitalTwin>("floorTwinId", floorDigitalTwin); Console.WriteLine($"Created twin '{createFloorDigitalTwinResponse.Value.Id}'."); // Create a relationship between building and floor using the BasicRelationship serialization helper. #region Snippet:DigitalTwinsSampleCreateBasicRelationship var buildingFloorRelationshipPayload = new BasicRelationship { Id = "buildingFloorRelationshipId", SourceId = "buildingTwinId", TargetId = "floorTwinId", Name = "contains", Properties = { { "Prop1", "Prop1 value" }, { "Prop2", 6 } } }; Response <BasicRelationship> createBuildingFloorRelationshipResponse = await client .CreateOrReplaceRelationshipAsync <BasicRelationship>("buildingTwinId", "buildingFloorRelationshipId", buildingFloorRelationshipPayload); Console.WriteLine($"Created a digital twin relationship '{createBuildingFloorRelationshipResponse.Value.Id}' " + $"from twin '{createBuildingFloorRelationshipResponse.Value.SourceId}' to twin '{createBuildingFloorRelationshipResponse.Value.TargetId}'."); #endregion Snippet:DigitalTwinsSampleCreateBasicRelationship // You can get a relationship as a BasicRelationship type. #region Snippet:DigitalTwinsSampleGetBasicRelationship Response <BasicRelationship> getBasicRelationshipResponse = await client.GetRelationshipAsync <BasicRelationship>( "buildingTwinId", "buildingFloorRelationshipId"); if (getBasicRelationshipResponse.GetRawResponse().Status == (int)HttpStatusCode.OK) { BasicRelationship basicRelationship = getBasicRelationshipResponse.Value; Console.WriteLine($"Retrieved relationship '{basicRelationship.Id}' from twin {basicRelationship.SourceId}.\n\t" + $"Prop1: {basicRelationship.Properties["Prop1"]}\n\t" + $"Prop2: {basicRelationship.Properties["Prop2"]}"); } #endregion Snippet:DigitalTwinsSampleGetBasicRelationship // Alternatively, you can create your own custom data types and use these types when calling into the APIs. // This requires less code or knowledge of the type for interaction. // Create a relationship between floorTwinId and buildingTwinId using a custom data type. #region Snippet:DigitalTwinsSampleCreateCustomRelationship var floorBuildingRelationshipPayload = new CustomRelationship { Id = "floorBuildingRelationshipId", SourceId = "floorTwinId", TargetId = "buildingTwinId", Name = "containedIn", Prop1 = "Prop1 val", Prop2 = 4 }; Response <CustomRelationship> createCustomRelationshipResponse = await client .CreateOrReplaceRelationshipAsync <CustomRelationship>("floorTwinId", "floorBuildingRelationshipId", floorBuildingRelationshipPayload); Console.WriteLine($"Created a digital twin relationship '{createCustomRelationshipResponse.Value.Id}' " + $"from twin '{createCustomRelationshipResponse.Value.SourceId}' to twin '{createCustomRelationshipResponse.Value.TargetId}'."); #endregion Snippet:DigitalTwinsSampleCreateCustomRelationship // Getting a relationship as a custom data type is extremely easy. #region Snippet:DigitalTwinsSampleGetCustomRelationship Response <CustomRelationship> getCustomRelationshipResponse = await client.GetRelationshipAsync <CustomRelationship>( "floorTwinId", "floorBuildingRelationshipId"); CustomRelationship getCustomRelationship = getCustomRelationshipResponse.Value; Console.WriteLine($"Retrieved and deserialized relationship '{getCustomRelationship.Id}' from twin '{getCustomRelationship.SourceId}'.\n\t" + $"Prop1: {getCustomRelationship.Prop1}\n\t" + $"Prop2: {getCustomRelationship.Prop2}"); #endregion Snippet:DigitalTwinsSampleGetCustomRelationship // Get all relationships in the graph where buildingTwinId is the source of the relationship. #region Snippet:DigitalTwinsSampleGetAllRelationships AsyncPageable <BasicRelationship> relationships = client.GetRelationshipsAsync <BasicRelationship>("buildingTwinId"); await foreach (BasicRelationship relationship in relationships) { Console.WriteLine($"Retrieved relationship '{relationship.Id}' with source {relationship.SourceId}' and " + $"target {relationship.TargetId}.\n\t" + $"Prop1: {relationship.Properties["Prop1"]}\n\t" + $"Prop2: {relationship.Properties["Prop2"]}"); } #endregion Snippet:DigitalTwinsSampleGetAllRelationships // Get all incoming relationships in the graph where buildingTwinId is the target of the relationship. #region Snippet:DigitalTwinsSampleGetIncomingRelationships AsyncPageable <IncomingRelationship> incomingRelationships = client.GetIncomingRelationshipsAsync("buildingTwinId"); await foreach (IncomingRelationship incomingRelationship in incomingRelationships) { Console.WriteLine($"Found an incoming relationship '{incomingRelationship.RelationshipId}' from '{incomingRelationship.SourceId}'."); } #endregion Snippet:DigitalTwinsSampleGetIncomingRelationships // Delete the contains relationship, created earlier in the sample code, from building to floor. #region Snippet:DigitalTwinsSampleDeleteRelationship await client.DeleteRelationshipAsync("buildingTwinId", "buildingFloorRelationshipId"); Console.WriteLine($"Deleted relationship 'buildingFloorRelationshipId'."); #endregion Snippet:DigitalTwinsSampleDeleteRelationship // Delete the containedIn relationship, created earlier in the sample code, from floor to building. await client.DeleteRelationshipAsync("floorTwinId", "floorBuildingRelationshipId"); Console.WriteLine($"Deleted relationship 'floorBuildingRelationshipId'."); // Clean up. try { // Delete all twins await client.DeleteDigitalTwinAsync("buildingTwinId"); await client.DeleteDigitalTwinAsync("floorTwinId"); } catch (RequestFailedException ex) { Console.WriteLine($"Failed to delete twin due to {ex}."); } try { await client.DeleteModelAsync(sampleBuildingModelId); await client.DeleteModelAsync(sampleFloorModelId); } catch (RequestFailedException ex) { Console.WriteLine($"Failed to delete model due to {ex}."); } }
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:"); twin = await FetchAndPrintTwinAsync(twinId, client); Console.WriteLine("--------"); //Update twin data var updateTwinData = new JsonPatchDocument(); updateTwinData.AppendAdd("/Temperature", 25.0); // <UpdateTwinCall> await client.UpdateDigitalTwinAsync(twin_ID, updateTwinData); // </UpdateTwinCall> Console.WriteLine("Twin properties updated"); Console.WriteLine(); //Print twin again Console.WriteLine("--- Printing twin details (after update):"); FetchAndPrintTwin(twin_ID, client); Console.WriteLine("--------"); Console.WriteLine(); //Delete twin await DeleteTwin(client, twin_ID); }