// <Create_relationship> public async static Task CreateRelationshipAsync(DigitalTwinsClient client, string srcId, string targetId) { var relationship = new BasicRelationship { TargetId = targetId, Name = "contains" }; try { string relId = $"{srcId}-contains->{targetId}"; await client.CreateOrReplaceRelationshipAsync(srcId, relId, relationship); Console.WriteLine("Created relationship successfully"); } catch (RequestFailedException e) { Console.WriteLine($"Create relationship error: {e.Status}: {e.Message}"); } }
/// <summary> /// Deletes all outgoing and incoming relationships from a specified digital twin /// </summary> public static async Task DeleteAllRelationshipsAsync(DigitalTwinsClient client, string dtId, ILogger log) { AsyncPageable <BasicRelationship> relationships = client.GetRelationshipsAsync <BasicRelationship>(dtId); await foreach (BasicRelationship relationship in relationships) { await client.DeleteRelationshipAsync(dtId, relationshipId.Id, relationship.ETag); log.LogInformation($"Twin '{dtId}' relationship '{relationship.Id}' deleted in DT"); } AsyncPageable <IncomingRelationship> incomingRelationships = client.GetIncomingRelationshipsAsync(dtId); await foreach (IncomingRelationship incomingRelationship in incomingRelationships) { await client.DeleteRelationshipAsync(incomingRelationship.SourceId, incomingRelationship.RelationshipId); log.LogInformation($"Twin '{dtId}' incoming relationship '{relationship.Id}' from '{incomingRelationship.SourceId}' deleted in DT"); } }
public static async Task UpdateTwinProperty(DigitalTwinsClient client, string twinId, string propertyPath, object value, ILogger log) { // If the twin does not exist, this will log an error try { // Update twin property List <Dictionary <string, object> > ops = new List <Dictionary <string, object> >(); ops.Add(new Dictionary <string, object>() { { "op", "replace" }, { "path", propertyPath }, { "value", value } }); await client.UpdateDigitalTwinAsync(twinId, JsonConvert.SerializeObject(ops)); } catch (RequestFailedException exc) { log.LogInformation($"*** Error:{exc.Status}/{exc.Message}"); } }
// <CreateRelationshipMethod> private async static Task CreateRelationship(DigitalTwinsClient client, string srcId, string targetId, string relName) { var relationship = new BasicRelationship { TargetId = targetId, Name = relName }; try { string relId = $"{srcId}-{relName}->{targetId}"; await client.CreateOrReplaceRelationshipAsync <BasicRelationship>(srcId, relId, relationship); Console.WriteLine($"Created {relName} relationship successfully"); } catch (RequestFailedException rex) { Console.WriteLine($"Create relationship error: {rex.Status}:{rex.Message}"); } }
public static async Task UpdateTwinProperty(DigitalTwinsClient client, string twinId, string operation, string propertyPath, string schema, string value, ILogger log) { // Update twin property try { List <object> twinData = new List <object>(); twinData.Add(new Dictionary <string, object>() { { "op", operation }, { "path", propertyPath }, { "value", ConvertStringToType(schema, value) } }); await client.UpdateDigitalTwinAsync(twinId, JsonConvert.SerializeObject(twinData)); } catch (RequestFailedException exc) { log.LogInformation($"*** Error:{exc.Status}/{exc.Message}"); } }
static async Task Main() { SetWindowSize(); Uri adtInstanceUrl; try { // Read configuration data from the IConfiguration config = new ConfigurationBuilder() .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false) .Build(); adtInstanceUrl = new Uri(config["instanceUrl"]); } catch (Exception ex) when(ex is FileNotFoundException || ex is UriFormatException) { Log.Error($"Could not read configuration. Have you configured your ADT instance URL in appsettings.json?\n\nException message: {ex.Message}"); return; } Log.Ok("Authenticating..."); var credential = new DefaultAzureCredential(); client = new DigitalTwinsClient(adtInstanceUrl, credential); Log.Ok($"Service client created – ready to go"); Log.Out($"Initializing Building Scenario..."); var CommandLoopInst = new CommandLoop(client); string[] dummy = new string[1]; await CommandLoopInst.CommandDeleteAllModels(dummy); var b = new BuildingScenario(CommandLoopInst); await b.InitBuilding(); // //await CommandLoopInst.CliCommandInterpreter(); }
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 CreateAndListModelsAsync(client, 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(); }
private async Task UpdateDigitalTwinProperty(DigitalTwinsClient client, string deviceId, JToken body, string propertyName) { var propertyToken = body[propertyName]; if (propertyToken != null) { if (Constants.Telemetries.Contains(propertyName.ToUpper())) { var data = new Dictionary <string, double>(); data.Add(propertyName, propertyToken.Value <double>()); await client.PublishTelemetryAsync(deviceId, JsonConvert.SerializeObject(data)); } else { // Update twin using device property var uou = new UpdateOperationsUtility(); uou.AppendReplaceOp($"/{propertyName}", propertyToken.Value <double>()); await client.UpdateDigitalTwinAsync(deviceId, uou.Serialize()); } } }
// <CreateRelationshipMethod> private async static Task CustomMethod_CreateRelationshipAsync(DigitalTwinsClient client, string srcId, string targetId, string relName, IDictionary <string, object> inputProperties) { var relationship = new BasicRelationship { TargetId = targetId, Name = relName, Properties = inputProperties }; try { string relId = $"{srcId}-{relName}->{targetId}"; await client.CreateOrReplaceRelationshipAsync <BasicRelationship>(srcId, relId, relationship); Console.WriteLine($"Created {relName} relationship successfully. Relationship ID is {relId}."); } catch (RequestFailedException rex) { Console.WriteLine($"Create relationship error: {rex.Status}:{rex.Message}"); } }
public static async Task ListModels(DigitalTwinsClient client) { string[] dependenciesFor = null; try { AsyncPageable <ModelData> results = client.GetModelsAsync(dependenciesFor, false); await foreach (ModelData md in results) { Console.WriteLine(md.Id); } } catch (RequestFailedException e) { Console.WriteLine($"Response {e.Status}: {e.Message}"); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } }
private static async Task FindAndDeleteIncomingRelationshipsAsync(DigitalTwinsClient client, string dtId) { // Find the relationships for the twin try { // GetRelationshipsAsync will throw an error if a problem occurs AsyncPageable <IncomingRelationship> incomingRels = client.GetIncomingRelationshipsAsync(dtId); await foreach (IncomingRelationship incomingRel in incomingRels) { await client.DeleteRelationshipAsync(incomingRel.SourceId, incomingRel.RelationshipId).ConfigureAwait(false); Console.WriteLine($"Deleted incoming relationship {incomingRel.RelationshipId} from {dtId}"); } } catch (RequestFailedException ex) { Console.WriteLine($"*** Error {ex.Status}/{ex.ErrorCode} retrieving or deleting incoming relationships for {dtId} due to {ex.Message}"); } }
public static async Task <string> FindParentAsync(DigitalTwinsClient client, string child, string relname, ILogger log) { // Find parent using incoming relationships try { AsyncPageable <IncomingRelationship> rels = client.GetIncomingRelationshipsAsync(child); await foreach (IncomingRelationship ie in rels) { if (ie.RelationshipName == relname) { return(ie.SourceId); } } } catch (RequestFailedException exc) { log.LogInformation($"*** Error in retrieving parent:{exc.Status}:{exc.Message}"); } return(null); }
/// <summary> /// Illustrates how to construct a <see cref="DigitalTwinsClient"/>, using the <see cref="DefaultAzureCredential"/> /// implementation of <see cref="Azure.Core.TokenCredential"/>. /// </summary> /// <param name="adtEndpoint">The endpoint of the digital twins instance.</param> private static DigitalTwinsClient GetDigitalTwinsClient(string tenantId, string clientId, string clientSecret, string adtEndpoint) { // These environment variables are necessary for DefaultAzureCredential to use application Id and client secret to login. Environment.SetEnvironmentVariable("AZURE_CLIENT_SECRET", clientSecret); Environment.SetEnvironmentVariable("AZURE_CLIENT_ID", clientId); Environment.SetEnvironmentVariable("AZURE_TENANT_ID", tenantId); #region Snippet:DigitalTwinsSampleCreateServiceClientWithClientSecret // DefaultAzureCredential supports different authentication mechanisms and determines the appropriate credential type based of the environment it is executing in. // It attempts to use multiple credential types in an order until it finds a working credential. var tokenCredential = new DefaultAzureCredential(); var client = new DigitalTwinsClient( new Uri(adtEndpoint), tokenCredential); #endregion Snippet:DigitalTwinsSampleCreateServiceClientWithClientSecret return client; }
public static async Task DeleteRelationship(DigitalTwinsClient client) { Console.Write("source twinId: "); string sourceTwinId = Console.ReadLine(); Console.Write("relationshipId: "); string relationshipId = Console.ReadLine(); try { await client.DeleteRelationshipAsync(sourceTwinId, relationshipId); } catch (RequestFailedException e) { Console.WriteLine($"Error {e.Status}: {e.Message}"); } catch (Exception ex) { Console.WriteLine($"Error: {ex}"); } }
public static async Task ReadProperty(DigitalTwinsClient client) { string dtID; string prop; Console.Write("Digital twin ID: "); dtID = Console.ReadLine(); Console.Write("Property name: "); prop = Console.ReadLine(); string q = string.Format("SELECT v.{0}, v.$metadata.{0}.lastUpdateTime FROM DIGITALTWINS v WHERE v.$dtId = '{1}' AND IS_PRIMITIVE(v.{0}) and IS_PRIMITIVE(v.$metadata.{0}.lastUpdateTime)", prop, dtID); Console.WriteLine("Query: {0}\n\r", q); AsyncPageable <string> result = client.QueryAsync(q); await foreach (string s in result) { Console.WriteLine(s); } }
public async Task SetPropertyValuesAsync(DigitalTwinsClient client) { // ------------------ SET TAG PROPERTY VALUES: CSHARP --------------------- // <TagPropertiesCsharp> IDictionary <string, bool> tags = new Dictionary <string, bool> { { "oceanview", true }, { "VIP", true } }; var twin = new BasicDigitalTwin { Metadata = { ModelId = "dtmi:example:Room;1" }, Contents = { { "Temperature", 75 }, { "tags", tags }, }, }; await client.CreateOrReplaceDigitalTwinAsync <BasicDigitalTwin>("myTwinID", twin); // </TagPropertiesCsharp> }
/// <summary> /// Illustrates how to construct a <see cref="DigitalTwinsClient"/>, using the <see cref="ClientSecretCredential"/> /// implementation of <see cref="Azure.Core.TokenCredential"/>. /// </summary> /// <param name="tenantId">The Id of the tenant of the application Id.</param> /// <param name="clientId">The application Id.</param> /// <param name="clientSecret">A client secret for the application Id.</param> /// <param name="adtEndpoint">The endpoint of the digital twins instance.</param> private static DigitalTwinsClient GetDigitalTwinsClient(string tenantId, string clientId, string clientSecret, string adtEndpoint) { #region Snippet:DigitalTwinsSampleCreateServiceClientWithClientSecret // By using the ClientSecretCredential, a specified application Id can login using a // client secret. var tokenCredential = new ClientSecretCredential( tenantId, clientId, clientSecret, new TokenCredentialOptions { AuthorityHost = KnownAuthorityHosts.AzureCloud }); var dtClient = new DigitalTwinsClient( new Uri(adtEndpoint), tokenCredential); #endregion Snippet:DigitalTwinsSampleCreateServiceClientWithClientSecret return(dtClient); }
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"); }
public void ClientDemo() { var client = new DigitalTwinsClient(); DigitalTwin twin = client.GetTwin(); // creates DigitalTwin instance and stores the JSON payload in it, i.e. very cheap string json = twin.ToString(); // gets the origin JSON payload. Assert.IsTrue(ReferenceEquals(s_demo_payload, json)); // the payload is really the same string as was passed into DigitalTwin ctor Assert.AreEqual("ID0001", twin.Id); // this is where the JSON string is parsed (lazily) Assert.AreEqual(123, twin.CreatedAt); Assert.AreEqual(true, twin.Decomissioned); // Temperature and Unit are not on DigitaTwin (they are user defined properties), so let's use dynamic APIs. dynamic dynamic = twin; Assert.AreEqual(72, dynamic.Temperature); Assert.AreEqual("F", dynamic.Unit); Assert.AreEqual(123, dynamic.CreatedAt); // the service defined properties are also avaliable through dynamic calls. // the client also has strongly typed APIs TemperatureSensor sensor = client.GetTwin <TemperatureSensor>(); Assert.AreEqual("F", sensor.Unit); Assert.AreEqual(72, sensor.Temperature); Assert.AreEqual("ID0001", sensor.Id); Assert.AreEqual(123, sensor.CreatedAt); Assert.AreEqual(true, sensor.Decomissioned); // Interestingly, the base twin type can be converted to user defined type sensor = twin.As <TemperatureSensor>(); Assert.AreEqual("F", sensor.Unit); Assert.AreEqual(72, sensor.Temperature); Assert.AreEqual("ID0001", sensor.Id); Assert.AreEqual(123, sensor.CreatedAt); Assert.AreEqual(true, sensor.Decomissioned); }
public async void Run([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log) { if (adtInstanceUrl == null) { log.LogError("Application setting \"ADT_SERVICE_URL\" not set"); } try { // Authenticate with Digital Twins var cred = new DefaultAzureCredential(); var client = new DigitalTwinsClient(new Uri(adtInstanceUrl), cred); log.LogInformation($"ADT service client connection created."); if (eventGridEvent != null && eventGridEvent.Data != null) { log.LogInformation(eventGridEvent.Data.ToString()); // <Find_device_ID_and_temperature> JObject deviceMessage = (JObject)JsonConvert.DeserializeObject(eventGridEvent.Data.ToString()); string deviceId = (string)deviceMessage["systemProperties"]["iothub-connection-device-id"]; var temperature = deviceMessage["body"]["Temperature"]; // </Find_device_ID_and_temperature> log.LogInformation($"Device:{deviceId} Temperature is:{temperature}"); // <Update_twin_with_device_temperature> var updateTwinData = new JsonPatchDocument(); updateTwinData.AppendReplace("/Temperature", temperature.Value <double>()); await client.UpdateDigitalTwinAsync(deviceId, updateTwinData); // </Update_twin_with_device_temperature> } } catch (Exception ex) { log.LogError($"Error in ingest function: {ex.Message}"); } }
/// <summary> /// Main entry point to the sample. /// </summary> public static async Task Main(string[] args) { // Parse and validate paramters Options options = null; ParserResult <Options> result = Parser.Default.ParseArguments <Options>(args) .WithParsed(parsedOptions => { options = parsedOptions; }) .WithNotParsed(errors => { Environment.Exit(1); }); // Instantiate the client DigitalTwinsClient dtClient = GetDigitalTwinsClient( options.TenantId, options.ClientId, options.ClientSecret, options.AdtEndpoint); // Run the samples var dtLifecycleSamples = new DigitalTwinsLifecycleSamples(dtClient, options.EventHubEndpointName); await dtLifecycleSamples.RunSamplesAsync(); var modelLifecycleSamples = new ModelLifecycleSamples(); await modelLifecycleSamples.RunSamplesAsync(dtClient); var componentSamples = new ComponentSamples(); await componentSamples.RunSamplesAsync(dtClient); var publishTelemetrySamples = new PublishTelemetrySamples(); await publishTelemetrySamples.RunSamplesAsync(dtClient); var relationshipSamples = new RelationshipSamples(); await relationshipSamples.RunSamplesAsync(dtClient); }
public static async Task GetTwin(DigitalTwinsClient client) { Console.Write("twinId: "); string twinId = Console.ReadLine(); try { Response <string> res = await client.GetDigitalTwinAsync(twinId); if (res != null) { Console.WriteLine(Program.PrettifyJson(res.Value.ToString())); } } catch (RequestFailedException e) { Console.WriteLine($"Error {e.Status}: {e.Message}"); } catch (Exception ex) { Console.WriteLine($"Error: {ex}"); } }
public static async void Run([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log) { log.LogInformation(eventGridEvent.Data.ToString()); if (adtInstanceUrl == null) { log.LogError("Application setting \"ADT_SERVICE_URL\" not set"); } try { //Authenticate with Digital Twins. ManagedIdentityCredential cred = new ManagedIdentityCredential("https://digitaltwins.azure.net"); DigitalTwinsClient client = new DigitalTwinsClient(new Uri(adtInstanceUrl), cred, new DigitalTwinsClientOptions { Transport = new HttpClientTransport(httpClient) }); log.LogInformation($"Azure digital twins service client connection created."); if (eventGridEvent != null && eventGridEvent.Data != null) { log.LogInformation(eventGridEvent.Data.ToString()); // Read deviceId and temperature for IoT Hub JSON. JObject deviceMessage = (JObject)JsonConvert.DeserializeObject(eventGridEvent.Data.ToString()); string deviceId = (string)deviceMessage["systemProperties"]["iothub-connection-device-id"]; var chasistemperature = deviceMessage["body"]["ChasisTemperature"]; log.LogInformation($"Device:{deviceId} Temperature is:{chasistemperature}"); //Update twin by using device temperature. var patch = new Azure.JsonPatchDocument(); patch.AppendReplace <double>("/ChasisTemperature", chasistemperature.Value <double>()); await client.UpdateDigitalTwinAsync(deviceId, patch); } } catch (Exception e) { log.LogError(e.Message); } }
private void DeleteAllModels(DigitalTwinsClient client, int iteration) { foreach (DigitalTwinsModelData modelData in client.GetModels()) { try { client.DeleteModel(modelData.Id); Log.Ok($"Deleted model '{modelData.Id}' (Iteration {iteration})"); } catch (RequestFailedException ex) when(ex.Status == (int)HttpStatusCode.Conflict) { // This model is a dependent and will be deleted in the next iteration. } catch (Exception ex) { Log.Error($"Failed to delete model '{modelData.Id}': {ex.Message}"); } } if (client.GetModels().Any()) { DeleteAllModels(client, iteration + 1); } }
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 static async Task GetRelationships(DigitalTwinsClient client) { Console.Write("source twinId: "); string sourceTwinId = Console.ReadLine(); try { AsyncPageable <string> list = client.GetRelationshipsAsync(sourceTwinId); await foreach (string s in list) { BasicRelationship rel = JsonSerializer.Deserialize <BasicRelationship>(s); Console.WriteLine("id={0}, name={1}", rel.Id, rel.Name); } } catch (RequestFailedException e) { Console.WriteLine($"Error {e.Status}: {e.Message}"); } catch (Exception ex) { Console.WriteLine($"Error: {ex}"); } }
public static async Task <string> FindParentByQueryAsync(DigitalTwinsClient client, string childId, ILogger log) { string query = "SELECT Parent " + "FROM digitaltwins Parent " + "JOIN Child RELATED Parent.contains " + $"WHERE Child.$dtId = '{childId}'"; log.LogInformation($"Query: {query}"); try { AsyncPageable <BasicDigitalTwin> twins = client.QueryAsync <BasicDigitalTwin>(query); await foreach (BasicDigitalTwin twin in twins) { return(twin.Id); } log.LogWarning($"*** No parent found"); } catch (RequestFailedException exc) { log.LogError($"*** Error in retrieving parent:{exc.Status}/{exc.Message}"); } return(null); }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req, ILogger log) { log.LogInformation("C# HTTP trigger function processed a request."); DigitalTwinsClient client; AsyncPageable <ModelData> modelList; try { ManagedIdentityCredential cred = new ManagedIdentityCredential(adtAppId); DigitalTwinsClientOptions opts = new DigitalTwinsClientOptions { Transport = new HttpClientTransport(httpClient) }; client = new DigitalTwinsClient(new Uri(adtInstanceUrl), cred, opts); modelList = client.GetModelsAsync(null, true); await foreach (ModelData md in modelList) { log.LogInformation($"Id: {md.Id}"); } log.LogInformation("Done"); } catch (Exception e) { log.LogCritical($"Authentication or client creation error: {e.Message}"); return(new BadRequestObjectResult(e.Message)); } return(new OkObjectResult(modelList)); }
/// <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 ComponentSamples(DigitalTwinsClient dtClient) { DigitalTwinsClient = dtClient; }