public static async Task Main(string[] args)
        {
            var adtInstanceUrl = "https://ADT_INSTANCE_HOST_NAME";
            var credential     = new DefaultAzureCredential();
            var client         = new DigitalTwinsClient(new Uri(adtInstanceUrl), credential);

            //retrieve the factory twin - this query will take a moment longer due to the cold start
            var factoryId = "FA44212";
            var factory   = client.GetDigitalTwin <BasicDigitalTwin>(factoryId);

            Console.WriteLine($"Factory {factory.Value.Id} retrieved.");
            foreach (KeyValuePair <string, object> prop in factory.Value.Contents)
            {
                Console.WriteLine($"Factory {factory.Value.Id} has Property: {prop.Key} with value {prop.Value.ToString()}");
            }

            //output factory property metadata, indicating the last time the property was updated
            foreach (var md in factory.Value.Metadata.PropertyMetadata)
            {
                Console.WriteLine($"Factory {factory.Value.Id} Property: {md.Key} was last updated {md.Value.LastUpdatedOn}");
            }

            //retrieve factory relationships
            IAsyncEnumerable <BasicRelationship> relationships = client.GetRelationshipsAsync <BasicRelationship>(factoryId);

            await foreach (BasicRelationship relationship in relationships)
            {
                Console.WriteLine($"Factory {factory.Value.Id} has relationship '{relationship.Name}' with {relationship.TargetId}");
            }

            //retrieve only the Efficiency property value for the factory using a projection
            var projectionQuery1 = $"SELECT Factory.Efficiency FROM DIGITALTWINS Factory WHERE Factory.$dtId='{factoryId}'";
            IAsyncEnumerable <JsonElement> response = client.QueryAsync <JsonElement>(projectionQuery1);

            await foreach (JsonElement ret in response)
            {
                Console.WriteLine($"{factoryId} Efficiency is at {ret.GetProperty("Efficiency")}");
            }

            //retrieve factories with Efficiency equal to or over 90
            var queryByPropertyValue = $"SELECT Factory FROM DIGITALTWINS Factory WHERE Factory.Efficiency >= 90";
            IAsyncEnumerable <BasicDigitalTwin> response2 = client.QueryAsync <IDictionary <string, BasicDigitalTwin> >(queryByPropertyValue).Select(_ => _["Factory"]);

            await foreach (BasicDigitalTwin ret in response2)
            {
                Console.WriteLine($"Factory {ret.Id} has an Efficiency over 90.");
            }
        }
        async public void QueryWithLoopAsync(DigitalTwinsClient client)
        {
            // ------------------ RUN QUERY & LOOP THROUGH PAGEABLE RESULTS WITH TRY/CATCH (Full sample) ---------------------
            // <FullQuerySample>
            AsyncPageable <BasicDigitalTwin> result = client.QueryAsync <BasicDigitalTwin>("Select * From DigitalTwins");

            try
            {
                await foreach (BasicDigitalTwin twin in result)
                {
                    // You can include your own logic to print the result
                    // The logic below prints the twin's ID and contents
                    Console.WriteLine($"Twin ID: {twin.Id} \nTwin data");
                    foreach (KeyValuePair <string, object> kvp in twin.Contents)
                    {
                        Console.WriteLine($"{kvp.Key}  {kvp.Value}");
                    }
                }
            }
            catch (RequestFailedException ex)
            {
                Console.WriteLine($"Error {ex.Status}, {ex.ErrorCode}, {ex.Message}");
                throw;
            }
            // </FullQuerySample>
        }
        public static async Task <IEnumerable <double> > GetAllSensorValuesInRoomAsync(DigitalTwinsClient client, string roomdtid, string sensormodelid, ILogger log)
        {
            var query =
                "SELECT Sensor " +
                "FROM DIGITALTWINS Room " +
                "JOIN Sensor RELATED Room.hasCapability " +
                $"WHERE IS_OF_MODEL(Sensor, '{sensormodelid}') AND Room.$dtId = '{roomdtid}' AND IS_PRIMITIVE(Sensor.Value)";

            try
            {
                List <double> values = new List <double>();
                AsyncPageable <BasicDigitalTwin> twins = client.QueryAsync <BasicDigitalTwin>(query);
                await foreach (BasicDigitalTwin twin in twins)
                {
                    var val = (JObject)JsonConvert.DeserializeObject(twin.Contents["Sensor"].ToString());
                    values.Add(double.Parse(val["Value"].ToString()));
                }
                return(values);
            }
            catch (RequestFailedException exc)
            {
                log.LogError($"*** Error in retrieving parent:{exc.Status}/{exc.Message}");
                throw exc;
            }
        }
        public static async Task <string> FindParentByQuery(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 <string> res = client.QueryAsync(query);

                await foreach (string s in res)
                {
                    JObject parentTwin = (JObject)JsonConvert.DeserializeObject(s);
                    return((string)parentTwin["Parent"]["$dtId"]);
                }
                log.LogInformation($"*** No parent found");
            }
            catch (RequestFailedException exc)
            {
                log.LogInformation($"*** Error in retrieving parent:{exc.Status}/{exc.Message}");
            }
            return(null);
        }
Esempio n. 5
0
        private static async Task <List <BasicDigitalTwin> > Query(string query)
        {
            try
            {
                AsyncPageable <BasicDigitalTwin> queryResult = client.QueryAsync <BasicDigitalTwin>(query);
                var resultlist = new List <BasicDigitalTwin>();

                await foreach (BasicDigitalTwin item in queryResult)
                {
                    resultlist.Add(item);
                }

                return(resultlist);
            }
            catch (RequestFailedException e)
            {
                log.LogInformation($"RequestFailedException error {e.Status}: {e.Message}");
                return(null);
            }
            catch (Exception ex)
            {
                log.LogInformation($"Exception error: {ex}");
                return(null);
            }
        }
        async public void Run(DigitalTwinsClient client)
        {
            AsyncPageable <BasicDigitalTwin> asyncPageableResponseWithCharge = client.QueryAsync <BasicDigitalTwin>("SELECT * FROM digitaltwins");
            int pageNum = 0;

            // The "await" keyword here is required, as a call is made when fetching a new page.

            await foreach (Page <BasicDigitalTwin> page in asyncPageableResponseWithCharge.AsPages())
            {
                Console.WriteLine($"Page {++pageNum} results:");

                // Extract the query-charge header from the page

                if (QueryChargeHelper.TryGetQueryCharge(page, out float queryCharge))
                {
                    Console.WriteLine($"Query charge was: {queryCharge}");
                }

                // Iterate over the twin instances.

                // The "await" keyword is not required here, as the paged response is local.

                foreach (BasicDigitalTwin twin in page.Values)
                {
                    Console.WriteLine($"Found digital twin '{twin.Id}'");
                }
            }
        }
Esempio n. 7
0
        public async Task DeleteAllTwinsAsync()
        {
            Console.WriteLine($"\nDeleting all twins");
            Console.WriteLine($"Step 1: Find all twins", ConsoleColor.DarkYellow);
            List <string> twinlist = new List <string>();

            try
            {
                AsyncPageable <string> qresult = client.QueryAsync("SELECT * FROM DIGITALTWINS");
                await foreach (string item in qresult)
                {
                    JsonDocument document = JsonDocument.Parse(item);
                    if (document.RootElement.TryGetProperty("$dtId", out JsonElement eDtdl))
                    {
                        try
                        {
                            string twinId = eDtdl.GetString();
                            twinlist.Add(twinId);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("No DTDL property in query result");
                        }
                    }
                    else
                    {
                        Console.WriteLine($"Error: Can't find twin id in query result:\n {item}");
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error in query execution: {ex.Message}");
            }


            Console.WriteLine($"Step 2: Find and remove relationships for each twin...", ConsoleColor.DarkYellow);
            foreach (string twinId in twinlist)
            {
                // Remove any relationships for the twin
                await FindAndDeleteOutgoingRelationshipsAsync(twinId).ConfigureAwait(false);
                await FindAndDeleteIncomingRelationshipsAsync(twinId).ConfigureAwait(false);
            }

            Console.WriteLine($"Step 3: Delete all twins", ConsoleColor.DarkYellow);
            foreach (string twinId in twinlist)
            {
                try
                {
                    await client.DeleteDigitalTwinAsync(twinId).ConfigureAwait(false);

                    Console.WriteLine($"Deleted twin {twinId}");
                }
                catch (RequestFailedException ex)
                {
                    Console.WriteLine($"*** Error {ex.Status}/{ex.ErrorCode} deleting twin {twinId} due to {ex.Message}");
                }
            }
        }
 async public void QueryBasicAsync(DigitalTwinsClient client)
 {
     // ------------------ RUN QUERY (Basic) ---------------------
     // <RunQuery>
     // Run a query for all twins
     string query = "SELECT * FROM DIGITALTWINS";
     AsyncPageable <BasicDigitalTwin> result = client.QueryAsync <BasicDigitalTwin>(query);
     // </RunQuery>
 }
Esempio n. 9
0
        public async Task Query_GetTwinAliasing()
        {
            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 CreateAndListModelsAsync(client, new List <string> {
                    roomModel
                }).ConfigureAwait(false);

                // Create a room twin, with property "IsOccupied": true
                string roomTwinId = await GetUniqueTwinIdAsync(client, TestAssetDefaults.RoomTwinIdPrefix).ConfigureAwait(false);

                BasicDigitalTwin roomTwin = TestAssetsHelper.GetRoomTwinPayload(roomModelId);
                await client.CreateOrReplaceDigitalTwinAsync(roomTwinId, roomTwin).ConfigureAwait(false);

                await WaitIfLiveAsync(TimeSpan.FromSeconds(10));

                // Use aliasing in the query to test deserialization when each digital twin in the response will be wrapped by the alias name.
                string queryString = $"SELECT D FROM DIGITALTWINS D";

                // act
                AsyncPageable <AliasedBasicDigitalTwin> asyncPageableResponse = client.QueryAsync <AliasedBasicDigitalTwin>(queryString);
                await foreach (AliasedBasicDigitalTwin twin in asyncPageableResponse)
                {
                    twin.Twin.Id.Should().NotBeNull();
                }
            }
            catch (Exception ex)
            {
                Assert.Fail($"Failure in executing a step in the test case: {ex.Message}.");
            }
            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}");
                }
            }
        }
Esempio n. 10
0
        public async Task Query_ValidQuery_Success()
        {
            DigitalTwinsClient client = GetClient();

            string floorModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.FloorModelIdPrefix).ConfigureAwait(false);

            string roomModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.RoomModelIdPrefix).ConfigureAwait(false);

            try
            {
                // arrange

                // Create room model
                string roomModel = TestAssetsHelper.GetRoomModelPayload(roomModelId, floorModelId);
                await client.CreateModelsAsync(new List <string> {
                    roomModel
                }).ConfigureAwait(false);

                // Create a room twin, with property "IsOccupied": true
                string roomTwinId = await GetUniqueTwinIdAsync(client, TestAssetDefaults.RoomTwinIdPrefix).ConfigureAwait(false);

                string roomTwin = TestAssetsHelper.GetRoomTwinPayload(roomModelId);
                await client.CreateDigitalTwinAsync(roomTwinId, roomTwin).ConfigureAwait(false);

                string queryString = "SELECT * FROM digitaltwins where IsOccupied = true";

                // act
                AsyncPageable <string> asyncPageableResponse = client.QueryAsync(queryString);

                // assert
                await foreach (string response in asyncPageableResponse)
                {
                    JsonElement jsonElement = JsonSerializer.Deserialize <JsonElement>(response);
                    JsonElement isOccupied  = jsonElement.GetProperty("IsOccupied");
                    isOccupied.GetRawText().Should().Be("true");
                }
            }
            finally
            {
                // clean up
                try
                {
                    if (!string.IsNullOrWhiteSpace(roomModelId))
                    {
                        await client.DeleteModelAsync(roomModelId).ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    Assert.Fail($"Test clean up failed: {ex.Message}");
                }
            }
        }
        public async Task <IEnumerable <Item> > All()
        {
            var result = client.QueryAsync <BasicDigitalTwin>("SELECT * FROM digitaltwins");

            var items = new List <Item>();

            await foreach (BasicDigitalTwin twin in result)
            {
                items.Add(new Item(twin.Id, twin.Metadata.ModelId));
            }
            return(items);
        }
Esempio n. 12
0
        public static async Task <string> GetTwinId(DigitalTwinsClient client, string regId, ILogger log)
        {
            string query = $"SELECT * FROM DigitalTwins T WHERE T.HubRegistrationId = '{regId}'";
            AsyncPageable <string> twins = client.QueryAsync(query);

            await foreach (string twinJson in twins)
            {
                JObject twin = (JObject)JsonConvert.DeserializeObject(twinJson);
                string  dtId = (string)twin["$dtId"];
                log.LogInformation($"Twin '{dtId}' found in DT");
                return(dtId);
            }

            return(null);
        }
        /// <summary>
        /// Queries for all digital twins using <see cref="DigitalTwinsClient.QueryAsync{T}(string, CancellationToken)"/>.
        /// </summary>
        /// <param name="cancellationToken">The token used to signal cancellation request.</param>
        public override async Task RunAsync(CancellationToken cancellationToken)
        {
            AsyncPageable <BasicDigitalTwin> result = _digitalTwinsClient
                                                      .QueryAsync <BasicDigitalTwin>($"SELECT * FROM DIGITALTWINS WHERE TestId = '{_testId}'", cancellationToken);
            long resultCount = 0;

            await foreach (BasicDigitalTwin a in result)
            {
                resultCount++;
            }

#if DEBUG
            resultCount.Should().Be(_size);
#endif
        }
Esempio n. 14
0
        public static async Task <string> FindOrCreateTwinAsync(string dtmi, string regId, ILogger log)
        {
            // Create Digital Twins client
            var cred   = new ManagedIdentityCredential(adtAppId);
            var client = new DigitalTwinsClient(
                new Uri(adtInstanceUrl),
                cred,
                new DigitalTwinsClientOptions
            {
                Transport = new HttpClientTransport(singletonHttpClientInstance)
            });

            // Find existing twin with registration ID
            string query = $"SELECT * FROM DigitalTwins T WHERE $dtId = '{regId}' AND IS_OF_MODEL('{dtmi}')";
            AsyncPageable <BasicDigitalTwin> twins = client.QueryAsync(query);
            string dtId;

            await foreach (BasicDigitalTwin digitalTwin in twins)
            {
                dtId = digitalTwin.Id;
                log.LogInformation($"Twin '{dtId}' with Registration ID '{regId}' found in DT");
                break;
            }

            if (String.IsNullOrWhiteSpace(dtId))
            {
                // Not found, so create new twin
                log.LogInformation($"Twin ID not found - setting DT ID to regID");
                dtId = regId; // use the Registration ID as the DT ID

                // Initialize the twin properties
                var digitalTwin = new BasicDigitalTwin
                {
                    Metadata = { ModelId = dtmi },
                    Contents =
                    {
                        { "Temperature", 0.0 },
                    },
                };

                await client.CreateOrReplaceDigitalTwinAsync <BasicDigitalTwin>(dtId, digitalTwin);

                log.LogInformation($"Twin '{dtId}' created in DT");
            }

            return(dtId);
        }
        public static async Task <string> FindOrCreateTwin(string dtmi, string regId, ILogger log)
        {
            // Create Digital Twins client
            var cred   = new ManagedIdentityCredential(adtAppId);
            var client = new DigitalTwinsClient(new Uri(adtInstanceUrl), cred, new DigitalTwinsClientOptions {
                Transport = new HttpClientTransport(httpClient)
            });

            // Find existing twin with registration ID
            string dtId;
            string query = $"SELECT * FROM DigitalTwins T WHERE $dtId = '{regId}' AND IS_OF_MODEL('{dtmi}')";
            AsyncPageable <string> twins = client.QueryAsync(query);

            await foreach (string twinJson in twins)
            {
                // Get DT ID from the Twin
                JObject twin = (JObject)JsonConvert.DeserializeObject(twinJson);
                dtId = (string)twin["$dtId"];
                log.LogInformation($"Twin '{dtId}' with Registration ID '{regId}' found in DT");
                return(dtId);
            }

            // Not found, so create new twin
            log.LogInformation($"Twin ID not found, setting DT ID to regID");
            dtId = regId; // use the Registration ID as the DT ID

            // Define the model type for the twin to be created
            Dictionary <string, object> meta = new Dictionary <string, object>()
            {
                { "$model", dtmi }
            };
            // Initialize the twin properties
            Dictionary <string, object> twinProps = new Dictionary <string, object>()
            {
                { "$metadata", meta }
            };

            twinProps.Add("Temperature", 0.0);

            await client.CreateOrReplaceDigitalTwinAsync <BasicDigitalTwin>(dtId, twinProps);

            log.LogInformation($"Twin '{dtId}' created in DT");

            return(dtId);
        }
Esempio n. 16
0
        public static async Task <string> FindOrCreateTwin(string dtmi, string regId, ILogger log)
        {
            // Create Digital Twin client
            var cred   = new ManagedIdentityCredential("https://digitaltwins.azure.net");
            var client = new DigitalTwinsClient(new Uri(adtInstanceUrl), cred, new DigitalTwinsClientOptions {
                Transport = new HttpClientTransport(httpClient)
            });

            // Find existing twin with registration ID
            string dtId;
            string query = $"SELECT * FROM DigitalTwins T WHERE T.HubRegistrationId = '{regId}' AND IS_OF_MODEL('{dtmi}')";
            AsyncPageable <string> twins = client.QueryAsync(query);

            await foreach (string twinJson in twins)
            {
                // Get DT ID from the Twin
                JObject twin = (JObject)JsonConvert.DeserializeObject(twinJson);
                dtId = (string)twin["$dtId"];
                log.LogInformation($"Twin '{dtId}' with Registration ID '{regId}' found in DT");
                return(dtId);
            }

            // Not found, so create new twin
            dtId = regId; // use the Registration ID as the DT ID

            // Define the model type for the twin to be created
            Dictionary <string, object> meta = new Dictionary <string, object>()
            {
                { "$model", dtmi }
            };
            // Initialize the twin properties
            Dictionary <string, object> twinProps = new Dictionary <string, object>()
            {
                { "$metadata", meta },
                { "HubRegistrationId", regId }
            };
            await client.CreateDigitalTwinAsync(dtId, System.Text.Json.JsonSerializer.Serialize <Dictionary <string, object> >(twinProps));

            log.LogInformation($"Twin '{dtId}' created in DT");

            return(dtId);
        }
        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);
            }
        }
        private static async Task <DtIds> fetchDtIds(string query)
        {
            DtIds dtIds = new DtIds();

            try {
                Azure.AsyncPageable <string>            result     = client.QueryAsync(query);
                IAsyncEnumerator <Azure.Page <string> > enumerator = result.AsPages().GetAsyncEnumerator();
                while (await enumerator.MoveNextAsync())
                {
                    IReadOnlyList <string> values = enumerator.Current.Values;
                    if (values.Count > 0)
                    {
                        JObject nodeData = JObject.Parse(values[0]);
                        dtIds.sensor          = (string)nodeData["$dtId"];
                        dtIds.turbineObserved = (string)nodeData["observes"];
                    }
                    else
                    {
                        throw new Exception("Node not found!");
                    }
                }
            } catch {}
            return(dtIds);
        }
Esempio n. 19
0
        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);
        }
Esempio n. 20
0
 private async Task <List <string> > Query(string query)
 {
     try
     {
         AsyncPageable <string> qresult = client.QueryAsync(query);
         List <string>          reslist = new List <string>();
         await foreach (string item in qresult)
         {
             reslist.Add(item);
         }
         Print(reslist);
         return(reslist);
     }
     catch (RequestFailedException e)
     {
         Log.Error($"Error {e.Status}: {e.Message}");
         return(null);
     }
     catch (Exception ex)
     {
         Log.Error($"Error: {ex}");
         return(null);
     }
 }
Esempio n. 21
0
        public async Task QueryTwinsAsync()
        {
            PrintHeader("QUERY DIGITAL TWINS");

            try
            {
                Console.WriteLine("Making a twin query and iterating over the results.");

                #region Snippet:DigitalTwinsSampleQueryTwins

                // This code snippet demonstrates the simplest way to iterate over the digital twin results, where paging
                // happens under the covers.
                AsyncPageable <string> asyncPageableResponse = client.QueryAsync("SELECT * FROM digitaltwins");

                // Iterate over the twin instances in the pageable response.
                // The "await" keyword here is required because new pages will be fetched when necessary,
                // which involves a request to the service.
                await foreach (string response in asyncPageableResponse)
                {
                    BasicDigitalTwin twin = JsonSerializer.Deserialize <BasicDigitalTwin>(response);
                    Console.WriteLine($"Found digital twin: {twin.Id}");
                }

                #endregion Snippet:DigitalTwinsSampleQueryTwins

                Console.WriteLine("Making a twin query, with query-charge header extraction.");

                #region Snippet:DigitalTwinsSampleQueryTwinsWithQueryCharge

                // This code snippet demonstrates how you could extract the query charges incurred when calling
                // the query API. It iterates over the response pages first to access to the query-charge header,
                // and then the digital twin results within each page.

                AsyncPageable <string> asyncPageableResponseWithCharge = client.QueryAsync("SELECT * FROM digitaltwins");
                int pageNum = 0;

                // The "await" keyword here is required as a call is made when fetching a new page.
                await foreach (Page <string> page in asyncPageableResponseWithCharge.AsPages())
                {
                    Console.WriteLine($"Page {++pageNum} results:");

                    // Extract the query-charge header from the page
                    if (QueryChargeHelper.TryGetQueryCharge(page, out float queryCharge))
                    {
                        Console.WriteLine($"Query charge was: {queryCharge}");
                    }

                    // Iterate over the twin instances.
                    // The "await" keyword is not required here as the paged response is local.
                    foreach (string response in page.Values)
                    {
                        BasicDigitalTwin twin = JsonSerializer.Deserialize <BasicDigitalTwin>(response);
                        Console.WriteLine($"Found digital twin: {twin.Id}");
                    }
                }

                #endregion Snippet:DigitalTwinsSampleQueryTwinsWithQueryCharge
            }
            catch (Exception ex)
            {
                FatalError($"Could not query digital twins due to {ex}");
            }
        }
Esempio n. 22
0
        public async Task Query_PaginationWorks()
        {
            DigitalTwinsClient client = GetClient();
            int    pageSize           = 5;
            string floorModelId       = await GetUniqueModelIdAsync(client, TestAssetDefaults.FloorModelIdPrefix).ConfigureAwait(false);

            string roomModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.RoomModelIdPrefix).ConfigureAwait(false);

            try
            {
                // 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 roomTwin = TestAssetsHelper.GetRoomTwinPayload(roomModelId);

                for (int i = 0; i < pageSize + 1; i++)
                {
                    string roomTwinId = await GetUniqueTwinIdAsync(client, TestAssetDefaults.RoomTwinIdPrefix).ConfigureAwait(false);

                    await client.CreateDigitalTwinAsync(roomTwinId, roomTwin).ConfigureAwait(false);
                }

                string queryString = "SELECT * FROM digitaltwins";

                // act
                var options = new QueryOptions();
                options.MaxItemsPerPage = pageSize;
                AsyncPageable <string> asyncPageableResponse = client.QueryAsync(queryString, options);

                // assert
                // Test that page size hint works, and that all returned pages either have the page size hint amount of
                // elements, or have no continuation token (signaling that it is the last page)
                int pageCount = 0;
                await foreach (Page <string> page in asyncPageableResponse.AsPages())
                {
                    pageCount++;
                    if (page.ContinuationToken != null)
                    {
                        page.Values.Count.Should().Be(pageSize, "Unexpected page size for a non-terminal page");
                    }
                }

                pageCount.Should().BeGreaterThan(1, "Expected more than one page of query results");
            }
            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}");
                }
            }
        }
Esempio n. 23
0
        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 CreateAndListModelsAsync(client, new List <string> {
                    roomModel
                }).ConfigureAwait(false);

                // Create a room twin, with property "IsOccupied": true
                string roomTwinId = await GetUniqueTwinIdAsync(client, TestAssetDefaults.RoomTwinIdPrefix).ConfigureAwait(false);

                BasicDigitalTwin roomTwin = TestAssetsHelper.GetRoomTwinPayload(roomModelId);
                await client.CreateOrReplaceDigitalTwinAsync(roomTwinId, roomTwin).ConfigureAwait(false);

                // Construct a query string to find the twins with the EXACT model id and provided version. If EXACT is not specified, the query
                // call will get all twins with the same model id but that implement any version higher than the provided version
                string queryString = $"SELECT * FROM digitaltwins WHERE IS_OF_MODEL('{roomModelId}', EXACT) AND IsOccupied = true";

                // act
                AsyncPageable <BasicDigitalTwin> asyncPageableResponse = client.QueryAsync <BasicDigitalTwin>(queryString);

                // assert

                // It takes a few seconds for the service to be able to fetch digital twins through queries after being created. Hence, adding the retry logic
                var digitalTwinFound = false;
                await TestRetryHelper.RetryAsync <AsyncPageable <BasicDigitalTwin> >(async() =>
                {
                    await foreach (BasicDigitalTwin response in asyncPageableResponse)
                    {
                        digitalTwinFound = true;
                        bool isOccupied  = ((JsonElement)response.Contents["IsOccupied"]).GetBoolean();
                        isOccupied.Should().BeTrue();
                        break;
                    }

                    if (!digitalTwinFound)
                    {
                        throw new Exception($"Digital twin based on model Id {roomModelId} not found");
                    }

                    return(null);
                }, s_retryCount, s_retryDelay);

                digitalTwinFound.Should().BeTrue();
            }
            catch (Exception ex)
            {
                Assert.Fail($"Failure in executing a step in the test case: {ex.Message}.");
            }
            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}");
                }
            }
        }
Esempio n. 24
0
        public async Task Query_PaginationWorks()
        {
            DigitalTwinsClient client = GetClient();
            int    pageSize           = 5;
            string floorModelId       = await GetUniqueModelIdAsync(client, TestAssetDefaults.FloorModelIdPrefix).ConfigureAwait(false);

            string roomModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.RoomModelIdPrefix).ConfigureAwait(false);

            TimeSpan QueryWaitTimeout = TimeSpan.FromMinutes(1); // Wait at most one minute for the created twins to become queryable

            try
            {
                // Create room model
                string roomModel = TestAssetsHelper.GetRoomModelPayload(roomModelId, floorModelId);
                await CreateAndListModelsAsync(client, new List <string> {
                    roomModel
                }).ConfigureAwait(false);

                // Create a room twin, with property "IsOccupied": true
                BasicDigitalTwin roomTwin = TestAssetsHelper.GetRoomTwinPayload(roomModelId);

                for (int i = 0; i < pageSize * 2; i++)
                {
                    string roomTwinId = await GetUniqueTwinIdAsync(client, TestAssetDefaults.RoomTwinIdPrefix).ConfigureAwait(false);

                    await client.CreateOrReplaceDigitalTwinAsync <BasicDigitalTwin>(roomTwinId, roomTwin).ConfigureAwait(false);
                }

                string queryString = "SELECT * FROM digitaltwins";

                // act
                CancellationTokenSource queryTimeoutCancellationToken = new CancellationTokenSource(QueryWaitTimeout);
                bool queryHasExpectedCount = false;
                while (!queryHasExpectedCount)
                {
                    if (queryTimeoutCancellationToken.IsCancellationRequested)
                    {
                        throw new AssertionException($"Timed out waiting for at least {pageSize + 1} twins to be queryable");
                    }

                    AsyncPageable <BasicDigitalTwin> asyncPageableResponse = client.QueryAsync <BasicDigitalTwin>(queryString, queryTimeoutCancellationToken.Token);
                    int count = 0;
                    await foreach (Page <BasicDigitalTwin> queriedTwinPage in asyncPageableResponse.AsPages(pageSizeHint: pageSize))
                    {
                        count += queriedTwinPage.Values.Count;
                    }

                    // Once at least (page + 1) twins are query-able, then page size control can be tested.
                    queryHasExpectedCount = count >= pageSize + 1;
                }

                // assert
                // Test that page size hint works, and that all returned pages either have the page size hint amount of
                // elements, or have no continuation token (signaling that it is the last page)
                int pageCount = 0;
                await foreach (Page <BasicDigitalTwin> page in client.QueryAsync <BasicDigitalTwin>(queryString).AsPages(pageSizeHint: pageSize))
                {
                    pageCount++;
                    if (page.ContinuationToken != null)
                    {
                        page.Values.Count.Should().Be(pageSize, "Unexpected page size for a non-terminal page");
                    }
                }

                pageCount.Should().BeGreaterThan(1, "Expected more than one page of query results");
            }
            catch (Exception ex)
            {
                Assert.Fail($"Failure in executing a step in the test case: {ex.Message}.");
            }
            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}");
                }
            }
        }
Esempio n. 25
0
        static async Task Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            string             clientId       = "<clientId>";
            string             tenantId       = "<tenatId>";
            string             adtInstanceUrl = "https://yourinstance";
            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("Models/SampleModel.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}");
            }
            // 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}");
            }

            // Initialize twin data
            BasicDigitalTwin twinData = new BasicDigitalTwin();

            twinData.Metadata.ModelId = "dtmi:com:contoso:SampleModel;1";
            twinData.CustomProperties.Add("data", $"Hello World!");

            string prefix = "sampleTwin-";

            for (int i = 0; i < 3; i++)
            {
                try {
                    twinData.Id = $"{prefix}{i}";
                    await client.CreateDigitalTwinAsync($"{prefix}{i}", JsonSerializer.Serialize(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
            AsyncPageable <string> result = client.QueryAsync("Select * From DigitalTwins");

            await foreach (string twin in result)
            {
                object jsonObj    = JsonSerializer.Deserialize <object>(twin);
                string prettyTwin = JsonSerializer.Serialize(jsonObj, new JsonSerializerOptions {
                    WriteIndented = true
                });
                Console.WriteLine(prettyTwin);
                Console.WriteLine("---------------");
            }
        }
        // <Async_signature>
        static async Task Main(string[] args)
        {
            // </Async_signature>
            Console.WriteLine("Hello World!");
            // <Authentication_code>
            string adtInstanceUrl = "https://<your-Azure-Digital-Twins-instance-hostName>";

            var credential = new DefaultAzureCredential();
            var client     = new DigitalTwinsClient(new Uri(adtInstanceUrl), credential);

            Console.WriteLine($"Service client created – ready to go");
            // </Authentication_code>

            // <Model_code>
            Console.WriteLine();
            Console.WriteLine("Upload a model");
            string dtdl   = File.ReadAllText("SampleModel.json");
            var    models = new List <string> {
                dtdl
            };

            // Upload the model to the service
            // <Model_try_catch>
            try
            {
                await client.CreateModelsAsync(models);

                Console.WriteLine("Models uploaded to the instance:");
            }
            catch (RequestFailedException e)
            {
                Console.WriteLine($"Upload model error: {e.Status}: {e.Message}");
            }
            // </Model_try_catch>

            // <Print_model>
            // Read a list of models back from the service
            AsyncPageable <DigitalTwinsModelData> modelDataList = client.GetModelsAsync();

            await foreach (DigitalTwinsModelData md in modelDataList)
            {
                Console.WriteLine($"Model: {md.Id}");
            }
            // </Print_model>
            // </Model_code>

            // <Initialize_twins>
            var twinData = new BasicDigitalTwin();

            twinData.Metadata.ModelId = "dtmi:example:SampleModel;1";
            twinData.Contents.Add("data", $"Hello World!");

            string prefix = "sampleTwin-";

            for (int i = 0; i < 3; i++)
            {
                try
                {
                    twinData.Id = $"{prefix}{i}";
                    await client.CreateOrReplaceDigitalTwinAsync <BasicDigitalTwin>(twinData.Id, twinData);

                    Console.WriteLine($"Created twin: {twinData.Id}");
                }
                catch (RequestFailedException e)
                {
                    Console.WriteLine($"Create twin error: {e.Status}: {e.Message}");
                }
            }
            // </Initialize_twins>

            // <Use_create_relationship>
            // Connect the twins with relationships
            await CreateRelationshipAsync(client, "sampleTwin-0", "sampleTwin-1");
            await CreateRelationshipAsync(client, "sampleTwin-0", "sampleTwin-2");

            // </Use_create_relationship>

            // <Use_list_relationships>
            //List the relationships
            await ListRelationshipsAsync(client, "sampleTwin-0");

            // </Use_list_relationships>

            // <Query_twins>
            // Run a query for all twins
            string query = "SELECT * FROM digitaltwins";
            AsyncPageable <BasicDigitalTwin> queryResult = client.QueryAsync <BasicDigitalTwin>(query);

            await foreach (BasicDigitalTwin twin in queryResult)
            {
                Console.WriteLine(JsonSerializer.Serialize(twin));
                Console.WriteLine("---------------");
            }
            // </Query_twins>
        }
        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("---------------");
            }
        }
        public async Task TestNewtonsoftObjectSerializerWithDigitalTwins()
        {
            DigitalTwinsClient defaultClient = GetClient();

            string roomTwinId = await GetUniqueTwinIdAsync(defaultClient, TestAssetDefaults.RoomTwinIdPrefix).ConfigureAwait(false);

            string floorModelId = await GetUniqueModelIdAsync(defaultClient, TestAssetDefaults.FloorModelIdPrefix).ConfigureAwait(false);

            string roomModelId = await GetUniqueModelIdAsync(defaultClient, TestAssetDefaults.RoomModelIdPrefix).ConfigureAwait(false);

            try
            {
                // arrange

                // create room model
                string roomModel = TestAssetsHelper.GetRoomModelPayload(roomModelId, floorModelId);
                await CreateAndListModelsAsync(defaultClient, new List <string> {
                    roomModel
                }).ConfigureAwait(false);

                // act

                // create room twin
                BasicDigitalTwin roomTwin = TestAssetsHelper.GetRoomTwinPayload(roomModelId);
                await defaultClient.CreateOrReplaceDigitalTwinAsync <BasicDigitalTwin>(roomTwinId, roomTwin).ConfigureAwait(false);

                // Create a client with NewtonsoftJsonObjectSerializer configured as the serializer.
                DigitalTwinsClient testClient = GetClient(
                    new DigitalTwinsClientOptions
                {
                    Serializer = new NewtonsoftJsonObjectSerializer()
                });

                // Get digital twin using the simple DigitalTwin model annotated with Newtonsoft attributes
                SimpleNewtonsoftDtModel getResponse = await testClient.GetDigitalTwinAsync <SimpleNewtonsoftDtModel>(roomTwinId).ConfigureAwait(false);

                getResponse.Id.Should().NotBeNullOrEmpty("Digital twin ID should not be null or empty");

                // Query DigitalTwins using the simple DigitalTwin model annotated with Newtonsoft attributes
                AsyncPageable <SimpleNewtonsoftDtModel> queryResponse = testClient.QueryAsync <SimpleNewtonsoftDtModel>("SELECT * FROM DIGITALTWINS");

                await foreach (SimpleNewtonsoftDtModel twin in queryResponse)
                {
                    twin.Id.Should().NotBeNullOrEmpty("Digital twin Id should not be null or empty");
                }
            }
            finally
            {
                // cleanup
                try
                {
                    // delete twin
                    if (!string.IsNullOrWhiteSpace(roomTwinId))
                    {
                        await defaultClient.DeleteDigitalTwinAsync(roomTwinId).ConfigureAwait(false);
                    }

                    // delete models
                    if (!string.IsNullOrWhiteSpace(roomModelId))
                    {
                        await defaultClient.DeleteModelAsync(roomModelId).ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    Assert.Fail($"Test clean up failed: {ex.Message}");
                }
            }
        }
Esempio n. 29
0
        public static async Task Run(
            [EventHubTrigger("twins-event-hub", Connection = "EventHubAppSetting-Twins")] EventData myEventHubMessage,
            [EventHub("tsi-event-hub", Connection = "EventHubAppSetting-TSI")] IAsyncCollector <string> outputEvents,
            ILogger log)
        {
            if (adtServiceUrl == null)
            {
                log.LogError("Application setting \"ADT_SERVICE_URL\" not set");
                return;
            }

            DefaultAzureCredential credentials = new DefaultAzureCredential();

            dtClient = new DigitalTwinsClient(new Uri(adtServiceUrl), credentials, new DigitalTwinsClientOptions {
                Transport = new HttpClientTransport(httpClient)
            });

            string  capabilityTwinId = myEventHubMessage.Properties["cloudEvents:subject"].ToString();
            JObject message          = (JObject)JsonConvert.DeserializeObject(Encoding.UTF8.GetString(myEventHubMessage.Body));

            log.LogInformation($"Reading event: '{message}' from twin '{capabilityTwinId}'.");

            // Get the twin from ADT that was updated to cause the incoming message
            // Query verifies that the twin is an instance of REC capability subclass
            List <BasicDigitalTwin> capabilityTwins = new List <BasicDigitalTwin>();
            string capabilityTwinQuery = $"SELECT * FROM DIGITALTWINS DT WHERE IS_OF_MODEL(DT, 'dtmi:digitaltwins:rec_3_3:core:Capability;1') AND DT.$dtId = '{capabilityTwinId}'";

            await foreach (BasicDigitalTwin returnedTwin in dtClient.QueryAsync <BasicDigitalTwin>(capabilityTwinQuery))
            {
                capabilityTwins.Add(returnedTwin);
                break;
            }
            // If we get anything but a single result back from the above, something has gone wrong; the twin does not exist or is the wrong type
            if (capabilityTwins.Count != 1)
            {
                log.LogInformation($"The modified twin {capabilityTwinId} is not defined as a REC Capability in ADT.");
                return;
            }
            BasicDigitalTwin capabilityTwin = capabilityTwins.First();

            // Extract name of capability twin. Only proceed if such a name exists.
            string capabilityName = "";

            if (capabilityTwin.Contents.ContainsKey("name") && capabilityTwin.Contents["name"] is JsonElement)
            {
                capabilityName = ((JsonElement)capabilityTwin.Contents["name"]).ToString().Trim();
            }
            if (capabilityName == "")
            {
                log.LogError($"Capability twin {capabilityTwinId} does not have a name assigned.");
                log.LogError(capabilityTwin.ToString());
                return;
            }

            // Extract value from incoming message JSON patch. Only proceed if the patch assigns a value to /lastValue
            JToken capabilityValue = message["patch"].Children <JObject>()
                                     .Where(
                patch =>
                patch.ContainsKey("path") && patch["path"].ToString() == "/lastValue" &&
                patch.ContainsKey("op") && (patch["op"].ToString() == "replace" || patch["op"].ToString() == "add") &&
                patch.ContainsKey("value"))
                                     .Select(patch => patch["value"]).FirstOrDefault();

            if (capabilityValue == null)
            {
                log.LogInformation($"Incoming event does not contain a JSON patch for /lastValue.");
                return;
            }

            // At this stage, we have enough information to propagate the state to TSI
            await PropagateStateToTSI(capabilityTwinId, capabilityName, capabilityValue, outputEvents, log);

            // And also to Azure Maps
            await PropagateStateToAzureMapsAsync(capabilityTwinId, capabilityName, capabilityValue, log);
        }