コード例 #1
0
        /// <summary>
        /// This sample demonstrates querying for raw events, series and aggregate series data from a Time Series Insights environment.
        /// </summary>
        /// <remarks>
        /// The Query APIs make use Time Series Expressions (TSX) to build filters, value and aggregation expressions. Visit
        /// <see href="https://docs.microsoft.com/rest/api/time-series-insights/reference-time-series-expression-syntax"/> to learn more about TSX.
        /// </remarks>
        public async Task RunSamplesAsync(TimeSeriesInsightsClient client, DeviceClient deviceClient)
        {
            PrintHeader("TIME SERIES INSIGHTS QUERY SAMPLE");

            // Figure out what keys make up the Time Series Id
            TimeSeriesInsightsModelSettings modelSettingsClient = client.GetModelSettingsClient();
            TimeSeriesModelSettings         modelSettings       = await modelSettingsClient.GetAsync();

            TimeSeriesId tsId = TimeSeriesIdHelper.CreateTimeSeriesId(modelSettings);
            TimeSeriesInsightsQueries queriesClient = client.GetQueriesClient();

            // In order to query for data, let's first send events to the IoT Hub
            await SendEventsToIotHubAsync(deviceClient, tsId, modelSettings.TimeSeriesIdProperties.ToArray());

            // Sleeping for a few seconds to allow data to fully propagate in the Time Series Insights service
            Thread.Sleep(TimeSpan.FromSeconds(3));

            await RunQueryEventsSample(queriesClient, tsId);

            await RunQueryAggregateSeriesSample(queriesClient, tsId);

            await RunQuerySeriesSampleWithInlineVariables(queriesClient, tsId);

            await RunQuerySeriesSampleWithPreDefinedVariables(client, tsId);
        }
コード例 #2
0
        private static async Task SendEventsToIotHubAsync(
            DeviceClient deviceClient,
            TimeSeriesId tsId,
            TimeSeriesIdProperty[] timeSeriesIdProperties)
        {
            IDictionary <string, object> messageBase = BuildMessageBase(timeSeriesIdProperties, tsId);
            double minTemperature = 20;
            double minHumidity    = 60;
            var    rand           = new Random();

            Console.WriteLine("\n\nSending temperature and humidity events to the IoT Hub.\n");

            // Build the message base that is used as the base for every event going out
            for (int i = 0; i < 10; i++)
            {
                double currentTemperature = minTemperature + rand.NextDouble() * 15;
                double currentHumidity    = minHumidity + rand.NextDouble() * 20;
                messageBase["Temperature"] = currentTemperature;
                messageBase["Humidity"]    = currentHumidity;
                string messageBody = JsonSerializer.Serialize(messageBase);
                var    message     = new Microsoft.Azure.Devices.Client.Message(Encoding.ASCII.GetBytes(messageBody))
                {
                    ContentType     = "application/json",
                    ContentEncoding = "utf-8",
                };

                await deviceClient.SendEventAsync(message);

                Console.WriteLine($"{DateTime.UtcNow} - Temperature: {currentTemperature}. " +
                                  $"Humidity: {currentHumidity}.");

                await Task.Delay(TimeSpan.FromSeconds(1));
            }
        }
コード例 #3
0
        internal static async Task SendEventsToHubAsync(
            DeviceClient client,
            TimeSeriesId tsiId,
            TimeSeriesIdProperty[] timeSeriesIdProperties,
            int numberOfEventsToSend)
        {
            IDictionary<string, object> messageBase = BuildMessageBase(timeSeriesIdProperties, tsiId);
            double minTemperature = 20;
            double minHumidity = 60;
            var rand = new Random();

            // Build the message base that is used as the base for every event going out
            for (int i = 0; i < numberOfEventsToSend; i++)
            {
                double currentTemperature = minTemperature + rand.NextDouble() * 15;
                double currentHumidity = minHumidity + rand.NextDouble() * 20;
                messageBase[Temperature] = currentTemperature;
                messageBase[Humidity] = currentHumidity;
                string messageBody = JsonSerializer.Serialize(messageBase);
                var message = new Message(Encoding.ASCII.GetBytes(messageBody))
                {
                    ContentType = "application/json",
                    ContentEncoding = "utf-8",
                };

                Func<Task> sendEventAct = async () => await client.SendEventAsync(message).ConfigureAwait(false);
                await sendEventAct.Should().NotThrowAsync();
            }
        }
コード例 #4
0
        protected async Task <TimeSeriesId> GetUniqueTimeSeriesInstanceIdAsync(TimeSeriesInsightsInstances instancesClient, int numOfIdKeys)
        {
            numOfIdKeys.Should().BeInRange(1, 3);

            for (int tryNumber = 0; tryNumber < MaxTries; ++tryNumber)
            {
                var id = new List <string>();
                for (int i = 0; i < numOfIdKeys; i++)
                {
                    id.Add(Recording.GenerateAlphaNumericId(string.Empty));
                }

                TimeSeriesId tsId = numOfIdKeys switch
                {
                    1 => new TimeSeriesId(id[0]),
                    2 => new TimeSeriesId(id[0], id[1]),
                    3 => new TimeSeriesId(id[0], id[1], id[2]),
                    _ => throw new Exception($"Invalid number of Time Series Insights Id properties."),
                };

                Response <InstancesOperationResult[]> getInstancesResult = await instancesClient
                                                                           .GetAsync(new List <TimeSeriesId> {
                    tsId
                })
                                                                           .ConfigureAwait(false);

                if (getInstancesResult.Value?.First()?.Error != null)
                {
                    return(tsId);
                }
            }

            throw new Exception($"Unique Id could not be found");
        }
コード例 #5
0
        public void TimeSeriesId_IdsNotEqual()
        {
            // Arrange
            var tsiId1 = new TimeSeriesId("B17", "F1");
            var tsiId2 = new TimeSeriesId("B17", "F2");

            tsiId1.Equals(tsiId2).Should().BeFalse();
        }
コード例 #6
0
        public void TimeSeriesId_IdsWithNullEqual()
        {
            // Arrange
            var tsiId1 = new TimeSeriesId("B17", null, "R1");
            var tsiId2 = new TimeSeriesId("B17", null, "R1");

            tsiId1.Equals(tsiId2).Should().BeTrue();
        }
コード例 #7
0
        /// <inheritdoc/>
        public void Register(Source source, Tag tag, TimeSeriesId timeSeriesId)
        {
            var timeSeriesMap = new TimeSeriesMap
            {
                Source = source,
            };

            timeSeriesMap.TagToTimeSeriesId[tag] = timeSeriesId.ToProtobuf();
            _timeSeriesMapIdentifierClient.Instance.RegisterAsync(timeSeriesMap);
        }
コード例 #8
0
        /// <summary>
        /// Register a mapping between <see cref="Source"/> and <see cref="Tag"/> to <see cref="TimeSeriesId"/>.
        /// </summary>
        /// <param name="source"><see cref="Source"/> to register for.</param>
        /// <param name="tag"><see cref="Tag"/> to register for.</param>
        /// <param name="timeSeriesId"><see cref="TimeSeriesId"/> to register for.</param>
        public void Register(Source source, Tag tag, TimeSeriesId timeSeriesId)
        {
            if (!_map.ContainsKey(source))
            {
                _map[source] = new ConcurrentDictionary <Tag, TimeSeriesId>();
            }
            var tagToTimeSeries = _map[source];

            tagToTimeSeries[tag] = timeSeriesId;
        }
コード例 #9
0
        public void TimeSeriesId_ToArrayWith1StringKey()
        {
            // Arrange
            var key1  = "B17";
            var tsiId = new TimeSeriesId(key1);

            // Act
            var idAsArray = tsiId.ToStringArray();

            // Assert
            idAsArray.Should().Equal(new string[] { key1 });
        }
コード例 #10
0
        /// <summary>
        /// This sample demonstrates querying for raw events, series and aggregate series data from a Time Series Insights environment.
        /// </summary>
        /// <remarks>
        /// The Query APIs make use Time Series Expressions (TSX) to build filters, value and aggregation expressions. Visit
        /// <see href="https://docs.microsoft.com/rest/api/time-series-insights/reference-time-series-expression-syntax"/> to learn more about TSX.
        /// </remarks>
        public async Task RunSamplesAsync(TimeSeriesInsightsClient client, TimeSeriesId tsId)
        {
            PrintHeader("TIME SERIES INSIGHTS QUERY SAMPLE");

            TimeSeriesInsightsQueries queriesClient = client.GetQueriesClient();

            await RunQueryEventsSample(queriesClient, tsId);

            await RunQueryAggregateSeriesSample(queriesClient, tsId);

            await RunQuerySeriesSampleWithInlineVariables(queriesClient, tsId);

            await RunQuerySeriesSampleWithPreDefinedVariables(client, tsId);
        }
コード例 #11
0
        /// <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 Time Series Insights client
            TimeSeriesInsightsClient tsiClient = GetTimeSeriesInsightsClient(
                options.TenantId,
                options.ClientId,
                options.ClientSecret,
                options.TsiEnvironmentFqdn);

            // Instantiate an IoT Hub device client client in order to send telemetry to the hub
            DeviceClient deviceClient = await GetDeviceClientAsync(options.IoTHubConnectionString).ConfigureAwait(false);

            // Figure out what keys make up the Time Series Id
            TimeSeriesInsightsModelSettings modelSettingsClient = tsiClient.GetModelSettingsClient();
            TimeSeriesModelSettings         modelSettings       = await modelSettingsClient.GetAsync();

            TimeSeriesId tsId = TimeSeriesIdHelper.CreateTimeSeriesId(modelSettings);

            // In order to query for data, let's first send events to the IoT Hub
            await SendEventsToIotHubAsync(deviceClient, tsId, modelSettings.TimeSeriesIdProperties.ToArray());

            // Run the samples

            var tsiInstancesSamples = new InstancesSamples();
            await tsiInstancesSamples.RunSamplesAsync(tsiClient);

            var tsiTypesSamples = new TypesSamples();
            await tsiTypesSamples.RunSamplesAsync(tsiClient);

            var tsiHierarchiesSamples = new HierarchiesSamples();
            await tsiHierarchiesSamples.RunSamplesAsync(tsiClient);

            var tsiModelSettingsSamples = new ModelSettingsSamples();
            await tsiModelSettingsSamples.RunSamplesAsync(tsiClient);

            var querySamples = new QuerySamples();
            await querySamples.RunSamplesAsync(tsiClient, tsId);
        }
コード例 #12
0
        public void TimeSeriesId_GetIdForStringKeys()
        {
            // Arrange
            var key1  = "B17";
            var key2  = "F1";
            var key3  = "R400";
            var tsiId = new TimeSeriesId(key1, key2, key3);

            // Act
            var idAsString = tsiId.ToString();

            // Assert
            idAsString.Should().Be($"[\"{key1}\",\"{key2}\",\"{key3}\"]");
        }
コード例 #13
0
        public void TimeSeriesId_ToArrayWith3StringKeys()
        {
            // Arrange
            var key1  = "B17";
            var key2  = "F1";
            var key3  = "R1";
            var tsiId = new TimeSeriesId(key1, key2, key3);

            // Act
            var idAsArray = tsiId.ToStringArray();

            // Assert
            idAsArray.Should().Equal(new string[] { key1, key2, key3 });
        }
コード例 #14
0
        internal static TimeSeriesId CreateTimeSeriesId(TimeSeriesModelSettings modelSettings)
        {
            int numOfIdKeys = modelSettings.TimeSeriesIdProperties.Count;

            // Create a Time Series Id where the number of keys that make up the Time Series Id is fetched from Model Settings
            var id = new List <string>();

            for (int i = 0; i < numOfIdKeys; i++)
            {
                id.Add(Guid.NewGuid().ToString());
            }

            TimeSeriesId tsId = numOfIdKeys switch
            {
                1 => new TimeSeriesId(id[0]),
                2 => new TimeSeriesId(id[0], id[1]),
                3 => new TimeSeriesId(id[0], id[1], id[2]),
                _ => throw new Exception($"Invalid number of Time Series Insights Id properties."),
            };

            return(tsId);
        }
        public async Task TimeSeriesInsightsQuery_AggregateSeriesWithNumericVariable()
        {
            // Arrange
            TimeSeriesInsightsClient tsiClient    = GetClient();
            DeviceClient             deviceClient = await GetDeviceClient().ConfigureAwait(false);

            // Figure out what the Time Series Id is composed of
            TimeSeriesModelSettings modelSettings = await tsiClient.ModelSettings.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(tsiClient, modelSettings.TimeSeriesIdProperties.Count)
                                 .ConfigureAwait(false);

            try
            {
                // Send some events to the IoT hub with with a second between each event
                await QueryTestsHelper.SendEventsToHubAsync(
                    deviceClient,
                    tsiId,
                    modelSettings.TimeSeriesIdProperties.ToArray(),
                    30)
                .ConfigureAwait(false);

                DateTimeOffset now       = Recording.UtcNow;
                DateTimeOffset endTime   = now.AddMinutes(10);
                DateTimeOffset startTime = now.AddMinutes(-10);

                var temperatureNumericVariable = new NumericVariable(
                    new TimeSeriesExpression($"$event.{QueryTestsHelper.Temperature}"),
                    new TimeSeriesExpression("avg($value)"));

                var queryAggregateSeriesRequestOptions = new QueryAggregateSeriesRequestOptions();
                queryAggregateSeriesRequestOptions.InlineVariables[QueryTestsHelper.Temperature] = temperatureNumericVariable;
                queryAggregateSeriesRequestOptions.ProjectedVariables.Add(QueryTestsHelper.Temperature);

                // This retry logic was added as the TSI instance are not immediately available after creation
                await TestRetryHelper.RetryAsync <AsyncPageable <QueryResultPage> >(async() =>
                {
                    QueryAnalyzer queryAggregateSeriesPages = tsiClient.Queries.CreateAggregateSeriesQueryAnalyzer(
                        tsiId,
                        startTime,
                        endTime,
                        TimeSpan.FromSeconds(5),
                        queryAggregateSeriesRequestOptions);

                    var nonNullFound = false;
                    await foreach (Page <TimeSeriesPoint> aggregateSeriesPage in queryAggregateSeriesPages.GetResultsAsync().AsPages())
                    {
                        foreach (TimeSeriesPoint point in aggregateSeriesPage.Values)
                        {
                            point.GetUniquePropertyNames().Should().HaveCount(1).And.Contain((property) => property == QueryTestsHelper.Temperature);
                            var value = (double?)point.GetValue(QueryTestsHelper.Temperature);
                            if (value != null)
                            {
                                nonNullFound = true;
                            }
                        }

                        nonNullFound.Should().BeTrue();
                    }

                    queryAggregateSeriesPages.Progress.Should().Be(100);

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

                // Add an interpolated variable
                var linearInterpolationNumericVariable = new NumericVariable(
                    new TimeSeriesExpression($"$event.{QueryTestsHelper.Temperature}"),
                    new TimeSeriesExpression("left($value)"));

                linearInterpolationNumericVariable.Interpolation = new InterpolationOperation
                {
                    Kind     = InterpolationKind.Linear,
                    Boundary = new InterpolationBoundary()
                    {
                        Span = TimeSpan.FromSeconds(1),
                    },
                };

                const string linearInterpolation = "linearInterpolation";
                queryAggregateSeriesRequestOptions.InlineVariables[linearInterpolation] = linearInterpolationNumericVariable;
                queryAggregateSeriesRequestOptions.ProjectedVariables.Add(linearInterpolation);

                await TestRetryHelper.RetryAsync <AsyncPageable <QueryResultPage> >(async() =>
                {
                    QueryAnalyzer queryAggregateSeriesPages = tsiClient.Queries.CreateAggregateSeriesQueryAnalyzer(
                        tsiId,
                        startTime,
                        endTime,
                        TimeSpan.FromSeconds(5),
                        queryAggregateSeriesRequestOptions);

                    await foreach (Page <TimeSeriesPoint> aggregateSeriesPage in queryAggregateSeriesPages.GetResultsAsync().AsPages())
                    {
                        aggregateSeriesPage.Values.Should().HaveCountGreaterThan(0);
                        foreach (var point in aggregateSeriesPage.Values)
                        {
                            point.GetUniquePropertyNames().Should().HaveCount(2)
                            .And
                            .Contain((property) => property == QueryTestsHelper.Temperature)
                            .And
                            .Contain((property) => property == linearInterpolation);
                        }
                    }

                    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);

                sendEventAct.Should().NotThrow();

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

                // Query for the two events with a filter
                queryAggregateSeriesRequestOptions.Filter = "$event.Temperature.Double = 1.2";
                await TestRetryHelper.RetryAsync <AsyncPageable <QueryResultPage> >(async() =>
                {
                    QueryAnalyzer queryAggregateSeriesPages = tsiClient.Queries.CreateAggregateSeriesQueryAnalyzer(
                        tsiId,
                        startTime,
                        endTime,
                        TimeSpan.FromSeconds(5),
                        queryAggregateSeriesRequestOptions);

                    var valueFound = false;
                    await foreach (TimeSeriesPoint point in queryAggregateSeriesPages.GetResultsAsync())
                    {
                        point.GetUniquePropertyNames().Should().HaveCount(2)
                        .And
                        .Contain((property) => property == QueryTestsHelper.Temperature)
                        .And
                        .Contain((property) => property == linearInterpolation);

                        var value = (double?)point.GetValue(QueryTestsHelper.Temperature);
                        if (value == 1.2)
                        {
                            valueFound = true;
                        }
                    }

                    valueFound.Should().BeTrue();

                    return(null);
                }, MaxNumberOfRetries, s_retryDelay);
            }
            finally
            {
                deviceClient?.Dispose();
            }
        }
        public async Task TimeSeriesInsightsQuery_AggregateSeriesWithCategoricalVariable()
        {
            // Arrange
            TimeSeriesInsightsClient tsiClient    = GetClient();
            DeviceClient             deviceClient = await GetDeviceClient().ConfigureAwait(false);

            // Figure out what the Time Series Id is composed of
            TimeSeriesModelSettings modelSettings = await tsiClient.ModelSettings.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(tsiClient, modelSettings.TimeSeriesIdProperties.Count)
                                 .ConfigureAwait(false);

            try
            {
                // Send some events to the IoT hub with with a second between each event
                await QueryTestsHelper.SendEventsToHubAsync(
                    deviceClient,
                    tsiId,
                    modelSettings.TimeSeriesIdProperties.ToArray(),
                    30)
                .ConfigureAwait(false);

                DateTimeOffset now       = Recording.UtcNow;
                DateTimeOffset endTime   = now.AddMinutes(10);
                DateTimeOffset startTime = now.AddMinutes(-10);

                var queryAggregateSeriesRequestOptions = new QueryAggregateSeriesRequestOptions();

                var categoricalVariable = new CategoricalVariable(
                    new TimeSeriesExpression($"tolong($event.{QueryTestsHelper.Temperature}.Double)"),
                    new TimeSeriesDefaultCategory("N/A"));
                categoricalVariable.Categories.Add(new TimeSeriesAggregateCategory("good", new List <object> {
                    1
                }));

                queryAggregateSeriesRequestOptions.InlineVariables["categorical"] = categoricalVariable;

                await TestRetryHelper.RetryAsync <AsyncPageable <QueryResultPage> >(async() =>
                {
                    QueryAnalyzer queryAggregateSeriesPages = tsiClient.Queries.CreateAggregateSeriesQueryAnalyzer(
                        tsiId,
                        startTime,
                        endTime,
                        TimeSpan.FromSeconds(5),
                        queryAggregateSeriesRequestOptions);

                    await foreach (TimeSeriesPoint point in queryAggregateSeriesPages.GetResultsAsync())
                    {
                        point.GetUniquePropertyNames().Should().HaveCount(3)
                        .And
                        .Contain((property) => property == "categorical[good]")
                        .And
                        .Contain((property) => property == "categorical[N/A]");
                    }

                    return(null);
                }, MaxNumberOfRetries, s_retryDelay);
            }
            finally
            {
                deviceClient?.Dispose();
            }
        }
        public async Task TimeSeriesInsightsQuery_AggregateSeriesWithAggregateVariable()
        {
            // Arrange
            TimeSeriesInsightsClient tsiClient    = GetClient();
            DeviceClient             deviceClient = await GetDeviceClient().ConfigureAwait(false);

            // Figure out what the Time Series Id is composed of
            TimeSeriesModelSettings modelSettings = await tsiClient.ModelSettings.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(tsiClient, modelSettings.TimeSeriesIdProperties.Count)
                                 .ConfigureAwait(false);

            try
            {
                // Send some events to the IoT hub with with a second between each event
                await QueryTestsHelper.SendEventsToHubAsync(
                    deviceClient,
                    tsiId,
                    modelSettings.TimeSeriesIdProperties.ToArray(),
                    30)
                .ConfigureAwait(false);

                // Query for temperature events with two calculateions. First with the temperature value as is, and the second
                // with the temperature value multiplied by 2.
                DateTimeOffset now       = Recording.UtcNow;
                DateTimeOffset endTime   = now.AddMinutes(10);
                DateTimeOffset startTime = now.AddMinutes(-10);

                var aggregateVariable = new AggregateVariable(
                    new TimeSeriesExpression("count()"));

                var queryAggregateSeriesRequestOptions = new QueryAggregateSeriesRequestOptions();
                queryAggregateSeriesRequestOptions.InlineVariables["Count"] = aggregateVariable;
                queryAggregateSeriesRequestOptions.ProjectedVariables.Add("Count");

                // This retry logic was added as the TSI instance are not immediately available after creation
                await TestRetryHelper.RetryAsync <AsyncPageable <QueryResultPage> >(async() =>
                {
                    QueryAnalyzer queryAggregateSeriesPages = tsiClient.Queries.CreateAggregateSeriesQueryAnalyzer(
                        tsiId,
                        startTime,
                        endTime,
                        TimeSpan.FromSeconds(5),
                        queryAggregateSeriesRequestOptions);

                    long?totalCount = 0;
                    await foreach (TimeSeriesPoint point in queryAggregateSeriesPages.GetResultsAsync())
                    {
                        var currentCount = (long?)point.GetValue("Count");
                        totalCount      += currentCount;
                    }

                    totalCount.Should().Be(30);

                    return(null);
                }, MaxNumberOfRetries, s_retryDelay);
            }
            finally
            {
                deviceClient?.Dispose();
            }
        }
コード例 #18
0
        public async Task TimeSeriesId_CreateInstanceWith3Keys()
        {
            // Arrange
            TimeSeriesInsightsClient    client          = GetClient();
            TimeSeriesInsightsInstances instancesClient = client.GetInstancesClient();

            // Create a Time Series Id with 3 keys. Middle key is a null
            var idWithNull = new TimeSeriesId(
                Recording.GenerateAlphaNumericId(string.Empty, 5),
                null,
                Recording.GenerateAlphaNumericId(string.Empty, 5));

            var timeSeriesInstances = new List <TimeSeriesInstance>
            {
                new TimeSeriesInstance(idWithNull, DefaultType),
            };

            // Act and assert
            try
            {
                // Create TSI instances
                Response <TimeSeriesOperationError[]> createInstancesResult = await instancesClient
                                                                              .CreateOrReplaceAsync(timeSeriesInstances)
                                                                              .ConfigureAwait(false);

                // Assert that the result error array does not contain any object that is set
                createInstancesResult.Value.Should().OnlyContain((errorResult) => errorResult == null);

                // This retry logic was added as the TSI instance are not immediately available after creation
                await TestRetryHelper.RetryAsync <Response <InstancesOperationResult[]> >(async() =>
                {
                    // Get the instance with a null item in its Id
                    Response <InstancesOperationResult[]> getInstanceWithNullInId = await instancesClient
                                                                                    .GetByIdAsync(new List <TimeSeriesId> {
                        idWithNull
                    })
                                                                                    .ConfigureAwait(false);

                    getInstanceWithNullInId.Value.Length.Should().Be(1);

                    InstancesOperationResult resultItem = getInstanceWithNullInId.Value.First();
                    resultItem.Instance.Should().NotBeNull();
                    resultItem.Instance.TimeSeriesId.ToStringArray().Length.Should().Be(3);
                    resultItem.Instance.TimeSeriesId.ToStringArray()[1].Should().BeNull();

                    return(null);
                }, MaxNumberOfRetries, s_retryDelay);
            }
            finally
            {
                // clean up
                try
                {
                    Response <TimeSeriesOperationError[]> deleteInstancesResponse = await instancesClient
                                                                                    .DeleteByIdAsync(timeSeriesInstances.Select((instance) => instance.TimeSeriesId))
                                                                                    .ConfigureAwait(false);

                    // Assert that the response array does not have any error object set
                    deleteInstancesResponse.Value.Should().OnlyContain((errorResult) => errorResult == null);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Test clean up failed: {ex.Message}");
                    throw;
                }
            }
        }
コード例 #19
0
        private async Task RunQuerySeriesSampleWithInlineVariables(TimeSeriesInsightsQueries queriesClient, TimeSeriesId tsId)
        {
            // Query for two series, one with the temperature values in Celsius and another in Fahrenheit
            #region Snippet:TimeSeriesInsightsSampleQuerySeriesWithInlineVariables
            Console.WriteLine("\n\nQuery for temperature series in Celsius and Fahrenheit over the past 10 minutes.\n");

            var celsiusVariable = new NumericVariable(
                new TimeSeriesExpression("$event.Temperature"),
                new TimeSeriesExpression("avg($value)"));
            var fahrenheitVariable = new NumericVariable(
                new TimeSeriesExpression("$event.Temperature * 1.8 + 32"),
                new TimeSeriesExpression("avg($value)"));

            var querySeriesRequestOptions = new QuerySeriesRequestOptions();
            querySeriesRequestOptions.InlineVariables["TemperatureInCelsius"]    = celsiusVariable;
            querySeriesRequestOptions.InlineVariables["TemperatureInFahrenheit"] = fahrenheitVariable;

            QueryAnalyzer seriesQuery = queriesClient.CreateSeriesQuery(
                tsId,
                TimeSpan.FromMinutes(10),
                null,
                querySeriesRequestOptions);

            await foreach (TimeSeriesPoint point in seriesQuery.GetResultsAsync())
            {
                double?tempInCelsius    = (double?)point.GetValue("TemperatureInCelsius");
                double?tempInFahrenheit = (double?)point.GetValue("TemperatureInFahrenheit");

                Console.WriteLine($"{point.Timestamp} - Average temperature in Celsius: {tempInCelsius}. Average temperature in Fahrenheit: {tempInFahrenheit}.");
            }
            #endregion Snippet:TimeSeriesInsightsSampleQuerySeriesWithInlineVariables
        }
コード例 #20
0
        private static IDictionary <string, object> BuildMessageBase(TimeSeriesIdProperty[] timeSeriesIdProperties, TimeSeriesId tsiId)
        {
            var messageBase = new Dictionary <string, object>();

            string[] tsiIdArray = tsiId.ToStringArray();
            for (int i = 0; i < timeSeriesIdProperties.Count(); i++)
            {
                TimeSeriesIdProperty idProperty = timeSeriesIdProperties[i];
                string tsiIdValue = tsiIdArray[i];
                messageBase[idProperty.Name] = tsiIdValue;
            }

            return(messageBase);
        }
コード例 #21
0
        public async Task TimeSeriesInsightsQuery_GetSeriesLifecycle()
        {
            // Arrange
            TimeSeriesInsightsClient tsiClient    = GetClient();
            DeviceClient             deviceClient = await GetDeviceClient().ConfigureAwait(false);

            // Figure out what the Time Series Id is composed of
            TimeSeriesModelSettings modelSettings = await tsiClient.ModelSettings.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(tsiClient, modelSettings.TimeSeriesIdProperties.Count)
                                 .ConfigureAwait(false);

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

                // Act

                // Query for temperature events with two calculateions. First with the temperature value as is, and the second
                // with the temperature value multiplied by 2.
                DateTimeOffset now       = Recording.UtcNow;
                DateTimeOffset endTime   = now.AddMinutes(10);
                DateTimeOffset startTime = now.AddMinutes(-10);

                var temperatureNumericVariable = new NumericVariable(
                    new TimeSeriesExpression($"$event.{QueryTestsHelper.Temperature}"),
                    new TimeSeriesExpression("avg($value)"));
                var temperatureNumericVariableTimesTwo = new NumericVariable(
                    new TimeSeriesExpression($"$event.{QueryTestsHelper.Temperature} * 2"),
                    new TimeSeriesExpression("avg($value)"));
                var temperatureTimesTwoVariableName = $"{QueryTestsHelper.Temperature}TimesTwo";

                var querySeriesRequestOptions = new QuerySeriesRequestOptions();
                querySeriesRequestOptions.InlineVariables[QueryTestsHelper.Temperature]    = temperatureNumericVariable;
                querySeriesRequestOptions.InlineVariables[temperatureTimesTwoVariableName] = temperatureNumericVariableTimesTwo;

                // This retry logic was added as the TSI instance are not immediately available after creation
                await TestRetryHelper.RetryAsync <AsyncPageable <QueryResultPage> >(async() =>
                {
                    AsyncPageable <QueryResultPage> querySeriesEventsPages = tsiClient.Query.GetSeriesAsync(
                        tsiId,
                        startTime,
                        endTime,
                        querySeriesRequestOptions);

                    await foreach (QueryResultPage seriesEventsPage in querySeriesEventsPages)
                    {
                        seriesEventsPage.Timestamps.Should().HaveCount(10);
                        seriesEventsPage.Timestamps.Should().OnlyContain(timeStamp => timeStamp >= startTime)
                        .And
                        .OnlyContain(timeStamp => timeStamp <= endTime);
                        seriesEventsPage.Properties.Count.Should().Be(3); // EventCount, Temperature and TemperatureTimesTwo
                        seriesEventsPage.Properties.Should().Contain((property) => property.Name == QueryTestsHelper.Temperature)
                        .And
                        .Contain((property) => property.Name == temperatureTimesTwoVariableName);

                        // Assert that the values for the Temperature property is equal to the values for the other property, multiplied by 2
                        var temperatureValues = seriesEventsPage
                                                .Properties
                                                .First((property) => property.Name == QueryTestsHelper.Temperature)
                                                .Values.Cast <double>().ToList();

                        var temperatureTimesTwoValues = seriesEventsPage
                                                        .Properties
                                                        .First((property) => property.Name == temperatureTimesTwoVariableName)
                                                        .Values.Cast <double>().ToList();
                        temperatureTimesTwoValues.Should().Equal(temperatureValues.Select((property) => property * 2).ToList());
                    }

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

                // Query for all the series events using a timespan
                AsyncPageable <QueryResultPage> querySeriesEventsPagesWithTimespan = tsiClient.Query.GetSeriesAsync(tsiId, TimeSpan.FromMinutes(10), null, querySeriesRequestOptions);
                await foreach (QueryResultPage seriesEventsPage in querySeriesEventsPagesWithTimespan)
                {
                    seriesEventsPage.Timestamps.Should().HaveCount(10);
                    seriesEventsPage.Properties.Count.Should().Be(3); // EventCount, Temperature and TemperatureTimesTwo
                }

                // Query for temperature and humidity
                var humidityNumericVariable = new NumericVariable(
                    new TimeSeriesExpression("$event.Humidity"),
                    new TimeSeriesExpression("avg($value)"));
                querySeriesRequestOptions.InlineVariables[QueryTestsHelper.Humidity] = humidityNumericVariable;
                querySeriesRequestOptions.ProjectedVariables.Add(QueryTestsHelper.Temperature);
                querySeriesRequestOptions.ProjectedVariables.Add(QueryTestsHelper.Humidity);
                await TestRetryHelper.RetryAsync <AsyncPageable <QueryResultPage> >(async() =>
                {
                    AsyncPageable <QueryResultPage> querySeriesEventsPages = tsiClient.Query.GetSeriesAsync(tsiId, startTime, endTime, querySeriesRequestOptions);

                    await foreach (QueryResultPage seriesEventsPage in querySeriesEventsPages)
                    {
                        seriesEventsPage.Timestamps.Should().HaveCount(10);
                        seriesEventsPage.Timestamps.Should().OnlyContain(timeStamp => timeStamp >= startTime)
                        .And
                        .OnlyContain(timeStamp => timeStamp <= endTime);
                        seriesEventsPage.Properties.Count.Should().Be(2); // Temperature and Humidity
                        seriesEventsPage.Properties.Should().Contain((property) => property.Name == QueryTestsHelper.Temperature)
                        .And
                        .Contain((property) => property.Name == QueryTestsHelper.Humidity);
                    }

                    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);

                sendEventAct.Should().NotThrow();

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

                // Query for the two events with a filter
                querySeriesRequestOptions.Filter = "$event.Temperature.Double = 1.2";
                await TestRetryHelper.RetryAsync <AsyncPageable <QueryResultPage> >(async() =>
                {
                    AsyncPageable <QueryResultPage> querySeriesEventsPages = tsiClient.Query.GetSeriesAsync(tsiId, startTime, endTime, querySeriesRequestOptions);
                    await foreach (QueryResultPage seriesEventsPage in querySeriesEventsPages)
                    {
                        seriesEventsPage.Timestamps.Should().HaveCount(2);
                        seriesEventsPage.Properties.Should().HaveCount(2)
                        .And
                        .Contain((property) => property.Name == QueryTestsHelper.Temperature)
                        .And
                        .Contain((property) => property.Name == QueryTestsHelper.Humidity);

                        var temperatureValues = seriesEventsPage
                                                .Properties
                                                .First((property) => property.Name == QueryTestsHelper.Temperature)
                                                .Values.Cast <double>().ToList();
                        temperatureValues.Should().AllBeEquivalentTo(1.2);
                    }

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

                // Query for the two events with a filter, but only take 1
                querySeriesRequestOptions.MaximumNumberOfEvents = 1;
                AsyncPageable <QueryResultPage> querySeriesEventsPagesWithFilter = tsiClient.Query.GetSeriesAsync(tsiId, startTime, endTime, querySeriesRequestOptions);
                await foreach (QueryResultPage seriesEventsPage in querySeriesEventsPagesWithFilter)
                {
                    seriesEventsPage.Timestamps.Should().HaveCount(1);
                    seriesEventsPage.Properties.Should().HaveCount(2)
                    .And
                    .Contain((property) => property.Name == QueryTestsHelper.Temperature)
                    .And
                    .Contain((property) => property.Name == QueryTestsHelper.Humidity);

                    var temperatureValues = seriesEventsPage
                                            .Properties
                                            .First((property) => property.Name == QueryTestsHelper.Temperature)
                                            .Values.Cast <double>().ToList();
                    temperatureValues.Should().AllBeEquivalentTo(1.2);
                }
            }
            finally
            {
                deviceClient?.Dispose();
            }
        }
コード例 #22
0
        public async Task TimeSeriesInsightsInstances_Lifecycle()
        {
            // Arrange
            TimeSeriesInsightsClient        client = GetClient();
            TimeSeriesInsightsModelSettings modelSettingsClient = client.GetModelSettingsClient();
            TimeSeriesInsightsInstances     instancesClient     = client.GetInstancesClient();

            int numOfInstancesToSetup = 2;
            var timeSeriesInstances   = new List <TimeSeriesInstance>();
            Response <TimeSeriesModelSettings> currentSettings = await modelSettingsClient.GetAsync().ConfigureAwait(false);

            string defaultTypeId     = currentSettings.Value.DefaultTypeId;
            int    numOfIdProperties = currentSettings.Value.TimeSeriesIdProperties.Count;

            for (int i = 0; i < numOfInstancesToSetup; i++)
            {
                TimeSeriesId id = await GetUniqueTimeSeriesInstanceIdAsync(instancesClient, numOfIdProperties)
                                  .ConfigureAwait(false);

                var instance = new TimeSeriesInstance(id, defaultTypeId)
                {
                    Name = Recording.GenerateAlphaNumericId("instance"),
                };
                timeSeriesInstances.Add(instance);
            }

            IEnumerable <TimeSeriesId> timeSeriesInstancesIds = timeSeriesInstances.Select((instance) => instance.TimeSeriesId);

            // Act and assert
            try
            {
                await TestRetryHelper.RetryAsync <Response <InstancesOperationResult[]> >((Func <Task <Response <InstancesOperationResult[]> > >)(async() =>
                {
                    // Create TSI instances
                    Response <TimeSeriesOperationError[]> createInstancesResult = await instancesClient
                                                                                  .CreateOrReplaceAsync(timeSeriesInstances)
                                                                                  .ConfigureAwait(false);

                    // Assert that the result error array does not contain any object that is set
                    createInstancesResult.Value.Should().OnlyContain((errorResult) => errorResult == null);

                    // Get the created instances by Ids
                    Response <InstancesOperationResult[]> getInstancesByIdsResult = await instancesClient
                                                                                    .GetByIdAsync(timeSeriesInstancesIds)
                                                                                    .ConfigureAwait(false);

                    getInstancesByIdsResult.Value.Length.Should().Be(timeSeriesInstances.Count);
                    foreach (InstancesOperationResult instanceResult in getInstancesByIdsResult.Value)
                    {
                        instanceResult.Instance.Should().NotBeNull();
                        instanceResult.Error.Should().BeNull();
                        instanceResult.Instance.TimeSeriesId.ToStringArray().Length.Should().Be(numOfIdProperties);
                        AssertionExtensions.Should(instanceResult.Instance.TimeSeriesTypeId).Be(defaultTypeId);
                        instanceResult.Instance.HierarchyIds.Count.Should().Be(0);
                        instanceResult.Instance.InstanceFields.Count.Should().Be(0);
                    }

                    // Update the instances by adding descriptions to them
                    timeSeriesInstances.ForEach((timeSeriesInstance) =>
                                                timeSeriesInstance.Description = "Description");

                    Response <InstancesOperationResult[]> replaceInstancesResult = await instancesClient
                                                                                   .ReplaceAsync(timeSeriesInstances)
                                                                                   .ConfigureAwait(false);

                    replaceInstancesResult.Value.Length.Should().Be(timeSeriesInstances.Count);
                    replaceInstancesResult.Value.Should().OnlyContain((errorResult) => errorResult.Error == null);

                    // Get instances by name
                    Response <InstancesOperationResult[]> getInstancesByNameResult = await instancesClient
                                                                                     .GetByNameAsync(timeSeriesInstances.Select((instance) => instance.Name))
                                                                                     .ConfigureAwait(false);

                    getInstancesByNameResult.Value.Length.Should().Be(timeSeriesInstances.Count);
                    foreach (InstancesOperationResult instanceResult in getInstancesByNameResult.Value)
                    {
                        instanceResult.Instance.Should().NotBeNull();
                        instanceResult.Error.Should().BeNull();
                        instanceResult.Instance.TimeSeriesId.ToStringArray().Length.Should().Be(numOfIdProperties);
                        AssertionExtensions.Should(instanceResult.Instance.TimeSeriesTypeId).Be(defaultTypeId);
                        instanceResult.Instance.HierarchyIds.Count.Should().Be(0);
                        instanceResult.Instance.InstanceFields.Count.Should().Be(0);
                    }

                    // Get all Time Series instances in the environment
                    AsyncPageable <TimeSeriesInstance> getAllInstancesResponse = instancesClient.GetAsync();

                    int numOfInstances = 0;
                    await foreach (TimeSeriesInstance tsiInstance in getAllInstancesResponse)
                    {
                        numOfInstances++;
                        tsiInstance.Should().NotBeNull();
                    }
                    numOfInstances.Should().BeGreaterOrEqualTo(numOfInstancesToSetup);
                    return(null);
                }), MaxNumberOfRetries, s_retryDelay);
            }
            finally
            {
                // clean up
                try
                {
                    Response <TimeSeriesOperationError[]> deleteInstancesResponse = await instancesClient
                                                                                    .DeleteByIdAsync(timeSeriesInstancesIds)
                                                                                    .ConfigureAwait(false);

                    // Assert that the response array does not have any error object set
                    deleteInstancesResponse.Value.Should().OnlyContain((errorResult) => errorResult == null);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Test clean up failed: {ex.Message}");
                    throw;
                }
            }
        }
        public async Task TimeSeriesInsightsInstances_Lifecycle()
        {
            // Arrange
            TimeSeriesInsightsClient client = GetClient();
            int    numOfIdProperties        = 3;
            int    numOfInstancesToSetup    = 2;
            var    timeSeriesInstances      = new List <TimeSeriesInstance>();
            string defaultTypeId            = await getDefaultTypeIdAsync(client).ConfigureAwait(false);

            for (int i = 0; i < numOfInstancesToSetup; i++)
            {
                TimeSeriesId id = await GetUniqueTimeSeriesInstanceIdAsync(client, numOfIdProperties)
                                  .ConfigureAwait(false);

                var instance = new TimeSeriesInstance(id, defaultTypeId)
                {
                    Name = Recording.GenerateAlphaNumericId("instance"),
                };
                timeSeriesInstances.Add(instance);
            }

            IEnumerable <TimeSeriesId> timeSeriesInstancesIds = timeSeriesInstances.Select((instance) => instance.TimeSeriesId);

            // Act and assert
            try
            {
                await TestRetryHelper.RetryAsync <Response <InstancesOperationResult[]> >(async() =>
                {
                    // Create TSI instances
                    Response <TimeSeriesOperationError[]> createInstancesResult = await client
                                                                                  .Instances
                                                                                  .CreateOrReplaceAsync(timeSeriesInstances)
                                                                                  .ConfigureAwait(false);

                    // Assert that the result error array does not contain any object that is set
                    createInstancesResult.Value.Should().OnlyContain((errorResult) => errorResult == null);

                    // Get the created instances by Ids
                    Response <InstancesOperationResult[]> getInstancesByIdsResult = await client
                                                                                    .Instances
                                                                                    .GetAsync(timeSeriesInstancesIds)
                                                                                    .ConfigureAwait(false);

                    getInstancesByIdsResult.Value.Length.Should().Be(timeSeriesInstances.Count);
                    foreach (InstancesOperationResult instanceResult in getInstancesByIdsResult.Value)
                    {
                        instanceResult.Instance.Should().NotBeNull();
                        instanceResult.Error.Should().BeNull();
                        instanceResult.Instance.TimeSeriesId.ToArray().Length.Should().Be(numOfIdProperties);
                        instanceResult.Instance.TypeId.Should().Be(defaultTypeId);
                        instanceResult.Instance.HierarchyIds.Count.Should().Be(0);
                        instanceResult.Instance.InstanceFields.Count.Should().Be(0);
                    }

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

                // Update the instances by adding descriptions to them
                timeSeriesInstances.ForEach((timeSeriesInstance) =>
                                            timeSeriesInstance.Description = "Description");

                Response <InstancesOperationResult[]> replaceInstancesResult = await client
                                                                               .Instances
                                                                               .ReplaceAsync(timeSeriesInstances)
                                                                               .ConfigureAwait(false);

                replaceInstancesResult.Value.Length.Should().Be(timeSeriesInstances.Count);
                replaceInstancesResult.Value.Should().OnlyContain((errorResult) => errorResult.Error == null);

                // This retry logic was added as the TSI instance are not immediately available after creation
                await TestRetryHelper.RetryAsync <Response <InstancesOperationResult[]> >(async() =>
                {
                    // Get instances by name
                    Response <InstancesOperationResult[]> getInstancesByNameResult = await client
                                                                                     .Instances
                                                                                     .GetAsync(timeSeriesInstances.Select((instance) => instance.Name))
                                                                                     .ConfigureAwait(false);

                    getInstancesByNameResult.Value.Length.Should().Be(timeSeriesInstances.Count);
                    foreach (InstancesOperationResult instanceResult in getInstancesByNameResult.Value)
                    {
                        instanceResult.Instance.Should().NotBeNull();
                        instanceResult.Error.Should().BeNull();
                        instanceResult.Instance.TimeSeriesId.ToArray().Length.Should().Be(numOfIdProperties);
                        instanceResult.Instance.TypeId.Should().Be(defaultTypeId);
                        instanceResult.Instance.HierarchyIds.Count.Should().Be(0);
                        instanceResult.Instance.InstanceFields.Count.Should().Be(0);
                    }

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

                // Get all Time Series instances in the environment
                AsyncPageable <TimeSeriesInstance> getAllInstancesResponse = client.Instances.GetAsync();

                int numOfInstances = 0;
                await foreach (TimeSeriesInstance tsiInstance in getAllInstancesResponse)
                {
                    numOfInstances++;
                    tsiInstance.Should().NotBeNull();
                }
                numOfInstances.Should().BeGreaterOrEqualTo(numOfInstancesToSetup);

                // Get search suggestions for the first instance
                TimeSeriesId timeSeriesIdToSuggest = timeSeriesInstances.First().TimeSeriesId;
                string       suggestionString      = timeSeriesIdToSuggest.ToArray().First();
                Response <SearchSuggestion[]> searchSuggestionResponse = await TestRetryHelper.RetryAsync(async() =>
                {
                    Response <SearchSuggestion[]> searchSuggestions = await client
                                                                      .Instances
                                                                      .GetSearchSuggestionsAsync(suggestionString)
                                                                      .ConfigureAwait(false);

                    if (searchSuggestions.Value.Length == 0)
                    {
                        throw new Exception($"Unable to find a search suggestion for string {suggestionString}.");
                    }

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

                searchSuggestionResponse.Value.Length.Should().Be(1);
            }
            finally
            {
                // clean up
                try
                {
                    Response <TimeSeriesOperationError[]> deleteInstancesResponse = await client
                                                                                    .Instances
                                                                                    .DeleteAsync(timeSeriesInstancesIds)
                                                                                    .ConfigureAwait(false);

                    // Assert that the response array does not have any error object set
                    deleteInstancesResponse.Value.Should().OnlyContain((errorResult) => errorResult == null);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Test clean up failed: {ex.Message}");
                    throw;
                }
            }
        }
コード例 #24
0
        private async Task RunQueryAggregateSeriesSample(TimeSeriesInsightsQueries queriesClient, TimeSeriesId tsId)
        {
            #region Snippet:TimeSeriesInsightsSampleQueryAggregateSeriesWithNumericVariable
            Console.WriteLine("\n\nQuery for the average temperature over the past 30 seconds, in 2-second time slots.\n");

            var numericVariable = new NumericVariable(
                new TimeSeriesExpression("$event.Temperature"),
                new TimeSeriesExpression("avg($value)"));

            var requestOptions = new QueryAggregateSeriesRequestOptions();
            requestOptions.InlineVariables["Temperature"] = numericVariable;
            requestOptions.ProjectedVariableNames.Add("Temperature");

            QueryAnalyzer aggregateSeriesQuery = queriesClient.CreateAggregateSeriesQuery(
                tsId,
                TimeSpan.FromSeconds(2),
                TimeSpan.FromSeconds(30),
                null,
                requestOptions);

            await foreach (TimeSeriesPoint point in aggregateSeriesQuery.GetResultsAsync())
            {
                double?averageTemperature = point.GetNullableDouble("Temperature");
                if (averageTemperature != null)
                {
                    Console.WriteLine($"{point.Timestamp} - Average temperature: {averageTemperature}.");
                }
            }
            #endregion Snippet:TimeSeriesInsightsSampleQueryAggregateSeriesWithNumericVariable

            #region Snippet:TimeSeriesInsightsSampleQueryAggregateSeriesWithAggregateVariable
            Console.WriteLine("\n\nCount the number of temperature events over the past 3 minutes, in 1-minute time slots.\n");

            // Get the count of events in 60-second time slots over the past 3 minutes
            DateTimeOffset endTime   = DateTime.UtcNow;
            DateTimeOffset startTime = endTime.AddMinutes(-3);

            var aggregateVariable = new AggregateVariable(
                new TimeSeriesExpression("count()"));

            var countVariableName = "Count";

            var aggregateSeriesRequestOptions = new QueryAggregateSeriesRequestOptions();
            aggregateSeriesRequestOptions.InlineVariables[countVariableName] = aggregateVariable;
            aggregateSeriesRequestOptions.ProjectedVariableNames.Add(countVariableName);

            QueryAnalyzer query = queriesClient.CreateAggregateSeriesQuery(
                tsId,
                startTime,
                endTime,
                TimeSpan.FromSeconds(60),
                aggregateSeriesRequestOptions);

            await foreach (TimeSeriesPoint point in query.GetResultsAsync())
            {
                long?temperatureCount = (long?)point.GetValue(countVariableName);
                Console.WriteLine($"{point.Timestamp} - Temperature count: {temperatureCount}");
            }
            #endregion Snippet:TimeSeriesInsightsSampleQueryAggregateSeriesWithAggregateVariable
        }
コード例 #25
0
        public async Task TimeSeriesInsightsQuery_GetEventsLifecycle()
        {
            // Arrange
            TimeSeriesInsightsClient tsiClient    = GetClient();
            DeviceClient             deviceClient = await GetDeviceClient().ConfigureAwait(false);

            // Figure out what the Time Series Id is composed of
            TimeSeriesModelSettings modelSettings = await tsiClient.GetModelSettingsAsync().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(tsiClient, modelSettings.TimeSeriesIdProperties.Count)
                                 .ConfigureAwait(false);

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

                // Act

                // Get events from last 1 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 <QueryResultPage> >(async() =>
                {
                    AsyncPageable <QueryResultPage> queryEventsPages = tsiClient.QueryEventsAsync(tsiId, startTime, endTime);

                    await foreach (QueryResultPage eventPage in queryEventsPages)
                    {
                        eventPage.Timestamps.Should().HaveCount(2);
                        eventPage.Timestamps.Should().OnlyContain(timeStamp => timeStamp >= startTime).And.OnlyContain(timeStamp => timeStamp <= endTime);
                        eventPage.Properties.Should().NotBeEmpty();
                        eventPage.Properties.First().Should().NotBeNull();
                    }

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

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

                // This retry logic was added as the TSI instance are not immediately available after creation
                await TestRetryHelper.RetryAsync <AsyncPageable <QueryResultPage> >(async() =>
                {
                    AsyncPageable <QueryResultPage> queryEventsPages = tsiClient.QueryEventsAsync(tsiId, startTime, endTime);

                    await foreach (QueryResultPage eventPage in queryEventsPages)
                    {
                        eventPage.Timestamps.Should().HaveCount(4);
                        eventPage.Timestamps.Should()
                        .OnlyContain(timeStamp => timeStamp >= startTime)
                        .And
                        .OnlyContain(timeStamp => timeStamp <= endTime);
                        eventPage.Properties.Should().NotBeEmpty();
                        eventPage.Properties.First().Should().NotBeNull();
                    }

                    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    = "$event.Temperature.Double = 1.2",
                    StoreType = StoreType.WarmStore,
                };
                queryRequestOptions.ProjectedProperties.Add(
                    new EventProperty
                {
                    Name = QueryTestsHelper.Temperature,
                    Type = "Double",
                });
                queryRequestOptions.ProjectedProperties.Add(
                    new EventProperty
                {
                    Name = modelSettings.TimeSeriesIdProperties.First().Name,
                    Type = modelSettings.TimeSeriesIdProperties.First().Type.ToString(),
                });

                await TestRetryHelper.RetryAsync <AsyncPageable <QueryResultPage> >(async() =>
                {
                    AsyncPageable <QueryResultPage> queryEventsPages = tsiClient.QueryEventsAsync(tsiId, startTime, endTime, queryRequestOptions);
                    await foreach (QueryResultPage eventPage in queryEventsPages)
                    {
                        eventPage.Timestamps.Should().HaveCount(2);
                        eventPage.Properties.Should().HaveCount(2);
                        eventPage.Properties.First().Should().NotBeNull();
                        eventPage.Properties.First().Name.Should().Be(QueryTestsHelper.Temperature);
                        eventPage.Properties[1].Name.Should().Be(modelSettings.TimeSeriesIdProperties.First().Name);
                    }

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

                // Query for the two events with a filter, but only take 1
                queryRequestOptions.MaximumNumberOfEvents = 1;
                AsyncPageable <QueryResultPage> queryEventsPagesWithFilter = tsiClient.QueryEventsAsync(tsiId, startTime, endTime, queryRequestOptions);
                await foreach (QueryResultPage eventPage in queryEventsPagesWithFilter)
                {
                    eventPage.Timestamps.Should().HaveCount(1);
                    eventPage.Properties.Should().HaveCount(2);
                    eventPage.Properties.First().Should().NotBeNull();
                    eventPage.Properties.First().Name.Should().Be(QueryTestsHelper.Temperature);
                    eventPage.Properties[1].Name.Should().Be(modelSettings.TimeSeriesIdProperties.First().Name);
                }

                await TestRetryHelper.RetryAsync <AsyncPageable <QueryResultPage> >(async() =>
                {
                    // Query for all the events using a timespan
                    AsyncPageable <QueryResultPage> queryEventsPagesWithTimespan = tsiClient.QueryEventsAsync(tsiId, TimeSpan.FromMinutes(20), endTime);
                    await foreach (QueryResultPage eventPage in queryEventsPagesWithTimespan)
                    {
                        eventPage.Timestamps.Should().HaveCount(6);
                        eventPage.Timestamps.Should()
                        .OnlyContain(timeStamp => timeStamp >= startTime)
                        .And
                        .OnlyContain(timeStamp => timeStamp <= endTime);
                        eventPage.Properties.Should().NotBeEmpty();
                        eventPage.Properties.First().Should().NotBeNull();
                    }

                    return(null);
                }, MaxNumberOfRetries, s_retryDelay);
            }
            finally
            {
                deviceClient?.Dispose();
            }
        }
コード例 #26
0
        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();
            }
        }
コード例 #27
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TimeSeriesMetadata"/> class.
 /// </summary>
 /// <param name="timeSeries">The <see cref="TimeSeries"/> the metadata is for.</param>
 public TimeSeriesMetadata(TimeSeriesId timeSeries)
 {
     TimeSeries = timeSeries;
 }
コード例 #28
0
        /// <summary>
        /// Creates a Time Series Insights instance
        /// Gets all instances for the environment
        /// Gets a specific instance by Id
        /// Replaces an instance
        /// Deletes an instance.
        /// </summary>
        public async Task RunSamplesAsync(TimeSeriesInsightsClient client)
        {
            PrintHeader("TIME SERIES INSIGHTS INSTANCES SAMPLE");

            // Figure out what keys make up the Time Series Id
            TimeSeriesModelSettings modelSettings = await client.ModelSettings.GetAsync();

            TimeSeriesId tsId          = TimeSeriesIdHelper.CreateTimeSeriesId(modelSettings);
            string       defaultTypeId = modelSettings.DefaultTypeId;

            #region Snippet:TimeSeriesInsightsSampleCreateInstance

            // Create a Time Series Instance object with the default Time Series Insights type Id.
            // The default type Id can be obtained programmatically by using the ModelSettings client.
            // tsId is created above using `TimeSeriesIdHelper.CreateTimeSeriesId`.
            var instance = new TimeSeriesInstance(tsId, defaultTypeId)
            {
                Name = "instance1",
            };

            var tsiInstancesToCreate = new List <TimeSeriesInstance>
            {
                instance,
            };

            Response <TimeSeriesOperationError[]> createInstanceErrors = await client
                                                                         .Instances
                                                                         .CreateOrReplaceAsync(tsiInstancesToCreate);

            // The response of calling the API contains a list of error objects corresponding by position to the input parameter
            // array in the request. If the error object is set to null, this means the operation was a success.
            for (int i = 0; i < createInstanceErrors.Value.Length; i++)
            {
                TimeSeriesId tsiId = tsiInstancesToCreate[i].TimeSeriesId;

                if (createInstanceErrors.Value[i] == null)
                {
                    Console.WriteLine($"Created Time Series Insights instance with Id '{tsiId}'.");
                }
                else
                {
                    Console.WriteLine($"Failed to create a Time Series Insights instance with Id '{tsiId}', " +
                                      $"Error Message: '{createInstanceErrors.Value[i].Message}, " +
                                      $"Error code: '{createInstanceErrors.Value[i].Code}'.");
                }
            }

            #endregion Snippet:TimeSeriesInsightsSampleCreateInstance

            #region Snippet:TimeSeriesInsightsGetAllInstances

            // Get all instances for the Time Series Insights environment
            AsyncPageable <TimeSeriesInstance> tsiInstances = client.Instances.GetAsync();
            await foreach (TimeSeriesInstance tsiInstance in tsiInstances)
            {
                Console.WriteLine($"Retrieved Time Series Insights instance with Id '{tsiInstance.TimeSeriesId}' and name '{tsiInstance.Name}'.");
            }

            #endregion Snippet:TimeSeriesInsightsGetAllInstances

            #region Snippet:TimeSeriesInsightsReplaceInstance

            // Get Time Series Insights instances by Id
            // tsId is created above using `TimeSeriesIdHelper.CreateTimeSeriesId`.
            var instanceIdsToGet = new List <TimeSeriesId>
            {
                tsId,
            };

            Response <InstancesOperationResult[]> getInstancesByIdResult = await client.Instances.GetAsync(instanceIdsToGet);

            TimeSeriesInstance instanceResult = getInstancesByIdResult.Value[0].Instance;
            Console.WriteLine($"Retrieved Time Series Insights instance with Id '{instanceResult.TimeSeriesId}' and name '{instanceResult.Name}'.");

            // Now let's replace the instance with an updated name
            instanceResult.Name = "newInstanceName";

            var instancesToReplace = new List <TimeSeriesInstance>
            {
                instanceResult,
            };

            Response <InstancesOperationResult[]> replaceInstancesResult = await client.Instances.ReplaceAsync(instancesToReplace);

            // The response of calling the API contains a list of error objects corresponding by position to the input parameter.
            // array in the request. If the error object is set to null, this means the operation was a success.
            for (int i = 0; i < replaceInstancesResult.Value.Length; i++)
            {
                TimeSeriesId tsiId = instancesToReplace[i].TimeSeriesId;

                TimeSeriesOperationError currentError = replaceInstancesResult.Value[i].Error;

                if (currentError != null)
                {
                    Console.WriteLine($"Failed to replace Time Series Insights instance with Id '{tsiId}'," +
                                      $" Error Message: '{currentError.Message}', Error code: '{currentError.Code}'.");
                }
                else
                {
                    Console.WriteLine($"Replaced Time Series Insights instance with Id '{tsiId}'.");
                }
            }

            #endregion Snippet:TimeSeriesInsightsReplaceInstance

            #region Snippet:TimeSeriesInsightsGetnstancesById

            // Get Time Series Insights instances by Id
            // tsId is created above using `TimeSeriesIdHelper.CreateTimeSeriesId`.
            var timeSeriesIds = new List <TimeSeriesId>
            {
                tsId,
            };

            Response <InstancesOperationResult[]> getByIdsResult = await client.Instances.GetAsync(timeSeriesIds);

            // The response of calling the API contains a list of instance or error objects corresponding by position to the array in the request.
            // Instance object is set when operation is successful and error object is set when operation is unsuccessful.
            for (int i = 0; i < getByIdsResult.Value.Length; i++)
            {
                InstancesOperationResult currentOperationResult = getByIdsResult.Value[i];

                if (currentOperationResult.Instance != null)
                {
                    Console.WriteLine($"Retrieved Time Series Insights instance with Id '{currentOperationResult.Instance.TimeSeriesId}' and name '{currentOperationResult.Instance.Name}'.");
                }
                else if (currentOperationResult.Error != null)
                {
                    Console.WriteLine($"Failed to retrieve a Time Series Insights instance with Id '{timeSeriesIds[i]}'. Error message: '{currentOperationResult.Error.Message}'.");
                }
            }

            #endregion Snippet:TimeSeriesInsightsGetnstancesById

            // Clean up
            try
            {
                #region Snippet:TimeSeriesInsightsSampleDeleteInstanceById

                // tsId is created above using `TimeSeriesIdHelper.CreateTimeSeriesId`.
                var instancesToDelete = new List <TimeSeriesId>
                {
                    tsId,
                };

                Response <TimeSeriesOperationError[]> deleteInstanceErrors = await client
                                                                             .Instances
                                                                             .DeleteAsync(instancesToDelete);

                // The response of calling the API contains a list of error objects corresponding by position to the input parameter
                // array in the request. If the error object is set to null, this means the operation was a success.
                for (int i = 0; i < deleteInstanceErrors.Value.Length; i++)
                {
                    TimeSeriesId tsiId = instancesToDelete[i];

                    if (deleteInstanceErrors.Value[i] == null)
                    {
                        Console.WriteLine($"Deleted Time Series Insights instance with Id '{tsiId}'.");
                    }
                    else
                    {
                        Console.WriteLine($"Failed to delete a Time Series Insights instance with Id '{tsiId}'. Error Message: '{deleteInstanceErrors.Value[i].Message}'");
                    }
                }

                #endregion Snippet:TimeSeriesInsightsSampleDeleteInstanceById
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Failed to delete Time Series Insights instance: {ex.Message}");
            }
        }
コード例 #29
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
        }
コード例 #30
0
        private async Task RunQuerySeriesSampleWithPreDefinedVariables(TimeSeriesInsightsClient client, TimeSeriesId tsId)
        {
            // Setup
            TimeSeriesInsightsInstances instancesClient = client.GetInstancesClient();
            TimeSeriesInsightsTypes     typesClient     = client.GetTypesClient();
            TimeSeriesInsightsQueries   queriesClient   = client.GetQueriesClient();

            // First create the Time Series type along with the numeric variables
            var timeSeriesTypes = new List <TimeSeriesType>();

            var celsiusVariable = new NumericVariable(
                new TimeSeriesExpression("$event.Temperature"),
                new TimeSeriesExpression("avg($value)"));
            var fahrenheitVariable = new NumericVariable(
                new TimeSeriesExpression("$event.Temperature * 1.8 + 32"),
                new TimeSeriesExpression("avg($value)"));

            var celsiusVariableName    = "TemperatureInCelsius";
            var fahrenheitVariableName = "TemperatureInFahrenheit";
            var variables = new Dictionary <string, TimeSeriesVariable>
            {
                { celsiusVariableName, celsiusVariable },
                { fahrenheitVariableName, fahrenheitVariable }
            };

            timeSeriesTypes.Add(new TimeSeriesType("TemperatureSensor", variables)
            {
                Id = "TemperatureSensorTypeId"
            });

            Response <TimeSeriesTypeOperationResult[]> createTypesResult = await typesClient
                                                                           .CreateOrReplaceAsync(timeSeriesTypes)
                                                                           .ConfigureAwait(false);

            if (createTypesResult.Value.First().Error != null)
            {
                Console.WriteLine($"\n\nFailed to create a Time Series Insights type. " +
                                  $"Error Message: '{createTypesResult.Value.First().Error.Message}.' " +
                                  $"Code: '{createTypesResult.Value.First().Error.Code}'.");
            }

            // Get the Time Series instance and replace its type with the one we just created
            Response <InstancesOperationResult[]> getInstanceResult = await instancesClient
                                                                      .GetAsync(new List <TimeSeriesId> {
                tsId
            });

            if (getInstanceResult.Value.First().Error != null)
            {
                Console.WriteLine($"\n\nFailed to retrieve Time Series instance with Id '{tsId}'. " +
                                  $"Error Message: '{getInstanceResult.Value.First().Error.Message}.' " +
                                  $"Code: '{getInstanceResult.Value.First().Error.Code}'.");
            }

            TimeSeriesInstance instanceToReplace = getInstanceResult.Value.First().Instance;

            instanceToReplace.TypeId = createTypesResult.Value.First().TimeSeriesType.Id;
            Response <InstancesOperationResult[]> replaceInstanceResult = await instancesClient
                                                                          .ReplaceAsync(new List <TimeSeriesInstance> {
                instanceToReplace
            });

            if (replaceInstanceResult.Value.First().Error != null)
            {
                Console.WriteLine($"\n\nFailed to retrieve Time Series instance with Id '{tsId}'. " +
                                  $"Error Message: '{replaceInstanceResult.Value.First().Error.Message}.' " +
                                  $"Code: '{replaceInstanceResult.Value.First().Error.Code}'.");
            }

            // Now that we set up the instance with the property type, query for the data
            #region Snippet:TimeSeriesInsightsSampleQuerySeries
            Console.WriteLine($"\n\nQuery for temperature series in Celsius and Fahrenheit over the past 10 minutes. " +
                              $"The Time Series instance belongs to a type that has predefined numeric variable that represents the temperature " +
                              $"in Celsuis, and a predefined numeric variable that represents the temperature in Fahrenheit.\n");

            DateTimeOffset endTime     = DateTime.UtcNow;
            DateTimeOffset startTime   = endTime.AddMinutes(-10);
            QueryAnalyzer  seriesQuery = queriesClient.CreateSeriesQuery(
                tsId,
                startTime,
                endTime);

            await foreach (TimeSeriesPoint point in seriesQuery.GetResultsAsync())
            {
                double?tempInCelsius    = point.GetNullableDouble(celsiusVariableName);
                double?tempInFahrenheit = point.GetNullableDouble(fahrenheitVariableName);

                Console.WriteLine($"{point.Timestamp} - Average temperature in Celsius: {tempInCelsius}. " +
                                  $"Average temperature in Fahrenheit: {tempInFahrenheit}.");
            }
            #endregion Snippet:TimeSeriesInsightsSampleQuerySeries
        }