예제 #1
0
        private async Task RunQueryEventsSample(TimeSeriesInsightsQueries queriesClient, TimeSeriesId tsId)
        {
            #region Snippet:TimeSeriesInsightsSampleQueryEvents
            Console.WriteLine("\n\nQuery for raw temperature events over the past 10 minutes.\n");

            // Get events from last 10 minute
            DateTimeOffset endTime   = DateTime.UtcNow;
            DateTimeOffset startTime = endTime.AddMinutes(-10);

            QueryAnalyzer temperatureEventsQuery = queriesClient.CreateEventsQuery(tsId, startTime, endTime);
            await foreach (TimeSeriesPoint point in temperatureEventsQuery.GetResultsAsync())
            {
                TimeSeriesValue temperatureValue = point.GetValue("Temperature");

                // Figure out what is the underlying type for the time series value. Since you know your Time Series Insights
                // environment best, you probably do not need this logic and you can skip to directly casting to the proper
                // type. This logic demonstrates how you can figure out what type to cast to in the case where you are not
                // too familiar with the property type.
                if (temperatureValue.Type == typeof(double?))
                {
                    Console.WriteLine($"{point.Timestamp} - Temperature: {point.GetNullableDouble("Temperature")}");
                }
                else if (temperatureValue.Type == typeof(int?))
                {
                    Console.WriteLine($"{point.Timestamp} - Temperature: {point.GetNullableInt("Temperature")}");
                }
                else
                {
                    Console.WriteLine("The type of the Time Series value for Temperature is not numeric.");
                }
            }
            #endregion Snippet:TimeSeriesInsightsSampleQueryEvents

            // Query for raw events using a time interval
            #region Snippet:TimeSeriesInsightsSampleQueryEventsUsingTimeSpan
            Console.WriteLine("\n\nQuery for raw humidity events over the past 30 seconds.\n");

            QueryAnalyzer humidityEventsQuery = queriesClient.CreateEventsQuery(tsId, TimeSpan.FromSeconds(30));
            await foreach (TimeSeriesPoint point in humidityEventsQuery.GetResultsAsync())
            {
                TimeSeriesValue humidityValue = point.GetValue("Humidity");

                // Figure out what is the underlying type for the time series value. Since you know your Time Series Insights
                // environment best, you probably do not need this logic and you can skip to directly casting to the proper
                // type. This logic demonstrates how you can figure out what type to cast to in the case where you are not
                // too familiar with the property type.
                if (humidityValue.Type == typeof(double?))
                {
                    Console.WriteLine($"{point.Timestamp} - Humidity: {point.GetNullableDouble("Humidity")}");
                }
                else if (humidityValue.Type == typeof(int?))
                {
                    Console.WriteLine($"{point.Timestamp} - Humidity: {point.GetNullableInt("Humidity")}");
                }
                else
                {
                    Console.WriteLine("The type of the Time Series value for Humidity is not numeric.");
                }
            }
            #endregion Snippet:TimeSeriesInsightsSampleQueryEventsUsingTimeSpan
        }
        public async Task TimeSeriesInsightsQuery_GetEventsLifecycle()
        {
            // Arrange
            TimeSeriesInsightsClient        tsiClient = GetClient();
            TimeSeriesInsightsModelSettings timeSeriesModelSettings = tsiClient.GetModelSettingsClient();
            TimeSeriesInsightsInstances     instancesClient         = tsiClient.GetInstancesClient();
            TimeSeriesInsightsQueries       queriesClient           = tsiClient.GetQueriesClient();
            DeviceClient deviceClient = await GetDeviceClient().ConfigureAwait(false);

            // Figure out what the Time Series Id is composed of
            TimeSeriesModelSettings modelSettings = await timeSeriesModelSettings.GetAsync().ConfigureAwait(false);

            // Create a Time Series Id where the number of keys that make up the Time Series Id is fetched from Model Settings
            TimeSeriesId tsiId = await GetUniqueTimeSeriesInstanceIdAsync(instancesClient, modelSettings.TimeSeriesIdProperties.Count)
                                 .ConfigureAwait(false);

            try
            {
                var initialEventsCount = 50;

                // Send some events to the IoT hub
                await QueryTestsHelper.SendEventsToHubAsync(
                    deviceClient,
                    tsiId,
                    modelSettings.TimeSeriesIdProperties.ToArray(),
                    initialEventsCount)
                .ConfigureAwait(false);

                // Act

                // Get events from last 10 minute
                DateTimeOffset now       = Recording.UtcNow;
                DateTimeOffset endTime   = now.AddMinutes(10);
                DateTimeOffset startTime = now.AddMinutes(-10);

                // This retry logic was added as the TSI instance are not immediately available after creation
                await TestRetryHelper.RetryAsync <AsyncPageable <TimeSeriesPoint> >(async() =>
                {
                    TimeSeriesQueryAnalyzer queryEventsPages = queriesClient.CreateEventsQuery(tsiId, startTime, endTime);
                    var count = 0;
                    await foreach (TimeSeriesPoint timeSeriesPoint in queryEventsPages.GetResultsAsync())
                    {
                        count++;
                        timeSeriesPoint.Timestamp.Should().BeAfter(startTime).And.BeBefore(endTime);

                        var temperatureValue = timeSeriesPoint.GetNullableDouble(QueryTestsHelper.Temperature);
                        temperatureValue.Should().NotBeNull();

                        var humidityValue = (double?)timeSeriesPoint.GetValue(QueryTestsHelper.Humidity);
                        humidityValue.Should().NotBeNull();
                    }

                    count.Should().Be(initialEventsCount);

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

                // Send 2 events with a special condition that can be used later to query on
                IDictionary <string, object> messageBase = QueryTestsHelper.BuildMessageBase(
                    modelSettings.TimeSeriesIdProperties.ToArray(),
                    tsiId);
                messageBase[QueryTestsHelper.Temperature] = 1.2;
                messageBase[QueryTestsHelper.Humidity]    = 3.4;
                string messageBody = JsonSerializer.Serialize(messageBase);
                var    message     = new Message(Encoding.ASCII.GetBytes(messageBody))
                {
                    ContentType     = "application/json",
                    ContentEncoding = "utf-8",
                };

                Func <Task> sendEventAct = async() => await deviceClient.SendEventAsync(message).ConfigureAwait(false);

                await sendEventAct.Should().NotThrowAsync();

                // Send it again
                sendEventAct.Should().NotThrow();

                // Query for the two events with a filter

                // Only project Temperature and one of the Id properties
                var queryRequestOptions = new QueryEventsRequestOptions
                {
                    Filter = new TimeSeriesExpression("$event.Temperature.Double = 1.2"),
                    Store  = StoreType.WarmStore,
                };
                queryRequestOptions.ProjectedProperties.Add(
                    new TimeSeriesInsightsEventProperty
                {
                    Name = QueryTestsHelper.Temperature,
                    PropertyValueType = "Double",
                });
                queryRequestOptions.ProjectedProperties.Add(
                    new TimeSeriesInsightsEventProperty
                {
                    Name = modelSettings.TimeSeriesIdProperties.First().Name,
                    PropertyValueType = modelSettings.TimeSeriesIdProperties.First().PropertyType.ToString(),
                });

                await TestRetryHelper.RetryAsync <AsyncPageable <TimeSeriesPoint> >(async() =>
                {
                    TimeSeriesQueryAnalyzer queryEventsPages = queriesClient.CreateEventsQuery(tsiId, startTime, endTime, queryRequestOptions);
                    await foreach (Page <TimeSeriesPoint> page in queryEventsPages.GetResultsAsync().AsPages())
                    {
                        page.Values.Should().HaveCount(2);
                        foreach (TimeSeriesPoint point in page.Values)
                        {
                            var value = (double?)point.GetValue(QueryTestsHelper.Temperature);
                            value.Should().Be(1.2);
                        }
                    }

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

                // Query for the two events with a filter, but only take 1
                queryRequestOptions.MaxNumberOfEvents = 1;
                TimeSeriesQueryAnalyzer queryEventsPagesWithFilter = queriesClient.CreateEventsQuery(tsiId, startTime, endTime, queryRequestOptions);
                await foreach (Page <TimeSeriesPoint> page in queryEventsPagesWithFilter.GetResultsAsync().AsPages())
                {
                    page.Values.Should().HaveCount(1);
                }

                await TestRetryHelper.RetryAsync <AsyncPageable <TimeSeriesPoint> >(async() =>
                {
                    // Query for all the events using a timespan
                    TimeSeriesQueryAnalyzer queryEventsPagesWithTimespan = queriesClient
                                                                           .CreateEventsQuery(tsiId, TimeSpan.FromMinutes(20), endTime);
                    await foreach (Page <TimeSeriesPoint> page in queryEventsPagesWithTimespan.GetResultsAsync().AsPages())
                    {
                        page.Values.Should().HaveCount(52);
                        foreach (TimeSeriesPoint point in page.Values)
                        {
                            point.Timestamp.Should().BeAfter(startTime).And.BeBefore(endTime);
                            var temperatureValue = (double?)point.GetValue(QueryTestsHelper.Temperature);
                            temperatureValue.Should().NotBeNull();
                            var humidityValue = (double?)point.GetValue(QueryTestsHelper.Humidity);
                            humidityValue.Should().NotBeNull();
                        }
                    }

                    return(null);
                }, MaxNumberOfRetries, s_retryDelay);
            }
            finally
            {
                deviceClient?.Dispose();
            }
        }