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}");
                }
            }
        }
Exemple #2
0
        /// <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}");
            }
        }
Exemple #3
0
        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
        }
Exemple #4
0
        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}");
            }
        }
Exemple #9
0
        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}");
                }
            }
        }
Exemple #12
0
        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);
        }
Exemple #16
0
        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}");
                }
            }
        }
Exemple #17
0
        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);
        }
Exemple #19
0
        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}");
            }
        }
Exemple #20
0
        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}");
            }
        }
Exemple #23
0
        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("---------------");
            }
        }
Exemple #25
0
        /// <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
        }
Exemple #26
0
        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!");
        }
Exemple #27
0
        /// <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}.");
            }
        }
Exemple #28
0
        /// <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}");
            }
        }
Exemple #29
0
        /// <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);
        }