Пример #1
0
        public StateEntity([NotNull] QboxState qboxState)
        {
            Guard.NotNull(qboxState, nameof(qboxState));

            SerialNumber = qboxState.SerialNumber;
            RowKey       = DateTimeRowKeyHelper.Construct(DateTime.UtcNow);

            CorrelationId   = qboxState.CorrelationId;
            LogTimeStamp    = qboxState.LogTime;
            MessageType     = qboxState.MessageType;
            Message         = qboxState.Message;
            State           = qboxState.State;
            FirmwareVersion = qboxState.FirmwareVersion;
            MeterType       = qboxState.MeterType;
            SequenceNumber  = qboxState.SequenceNumber;
            Payloads        = qboxState.Payloads;
            MessageTime     = qboxState.MessageTime;

            // Copy all 'Last...' values
            var propertiesToCopy = typeof(QboxState).GetProperties()
                                   .Where(pi => pi.Name.StartsWith("Last") && (pi.PropertyType == typeof(string) || pi.PropertyType == typeof(DateTime) || pi.PropertyType == typeof(DateTime?))
                                          );

            foreach (var propertyInfo in propertiesToCopy)
            {
                var value = propertyInfo.GetValue(qboxState);
                var targetPropertyInfo = typeof(StateEntity).GetProperty(propertyInfo.Name);

                // Skip null values
                if (targetPropertyInfo != null && value != null)
                {
                    targetPropertyInfo.SetValue(this, value);
                }
            }
        }
Пример #2
0
        /// <inheritdoc cref="IAzureTablesService.StoreBatchAsync(IList{QboxMeasurement})"/>
        public async Task <bool> StoreBatchAsync(IList <QboxMeasurement> qboxMeasurements)
        {
            Guard.NotNull(qboxMeasurements, nameof(qboxMeasurements));

            if (qboxMeasurements.Count == 0)
            {
                return(true);
            }

            var entities = (from entity in qboxMeasurements
                            group entity by new
            {
                entity.SerialNumber,
                entity.MeasureTime,
                entity.MeasureTimeAdjusted
            }
                            into g
                            select new MeasurementEntity
            {
                PartitionKey = PartitionKeyHelper.Construct(g.Key.SerialNumber, g.Key.MeasureTime),
                RowKey = DateTimeRowKeyHelper.Construct(g.Key.MeasureTime),
                SerialNumber = g.Key.SerialNumber,
                MeasureTime = g.Key.MeasureTime,
                MeasureTimeAdjusted = g.Key.MeasureTimeAdjusted,
                CorrelationId = g.First().CorrelationId,
                Counter0181 = g.FirstOrDefault(c => c.CounterId == 181)?.PulseValue,
                Counter0182 = g.FirstOrDefault(c => c.CounterId == 182)?.PulseValue,
                Counter0281 = g.FirstOrDefault(c => c.CounterId == 281)?.PulseValue,
                Counter0282 = g.FirstOrDefault(c => c.CounterId == 282)?.PulseValue,
                Counter2421 = g.FirstOrDefault(c => c.CounterId == 2421)?.PulseValue
            }).ToList();


            string serialNumber = qboxMeasurements.First().SerialNumber;
            string rowKey       = entities.Count == 1 ? entities.First().RowKey : string.Empty;

            _logger.LogInformation("Inserting {Count} measurement(s) for '{SerialNumber}' with RowKey '{RowKey}' into Azure Table '{table}'", entities.Count, serialNumber, rowKey, _measurementTable.Name);

            return(await _measurementTable.Set.AddOrUpdateAsync(entities).TimeoutAfter(_serverTimeout) != null);
        }
Пример #3
0
        /// <inheritdoc cref="IAzureTablesService.QueryDataAsync(string, DateTime, DateTime, QboxQueryResolution, bool)"/>
        public async Task <QboxPagedDataQueryResult <QboxCounterData> > QueryDataAsync(string serialNumber, DateTime from, DateTime to, QboxQueryResolution resolution, bool adjustHours)
        {
            Guard.NotNullOrEmpty(serialNumber, nameof(serialNumber));

            int      adjustedHours      = 0;
            DateTime fromQueryParameter = from;

            if (adjustHours)
            {
                fromQueryParameter = from.AddDays(-1);
                adjustedHours      = TimeZoneUtils.GetHoursDifferenceFromUTC(from);
            }

            string fromPartitionKey = PartitionKeyHelper.Construct(serialNumber, fromQueryParameter);
            string toPartitionKey   = PartitionKeyHelper.Construct(serialNumber, to);

            string fromRowKey = DateTimeRowKeyHelper.Construct(fromQueryParameter);
            string toRowKey   = DateTimeRowKeyHelper.Construct(to);

            _logger.LogInformation("Querying Table {table} with PartitionKey {fromPartitionKey} to {toPartitionKey} and RowKey {fromRowKey} to {toRowKey} and AdjustHours = {adjustHours}", _measurementTable.Name, fromPartitionKey, toPartitionKey, fromRowKey, toRowKey, adjustHours);

            var queue = new ConcurrentQueue <List <MeasurementEntity> >();
            var tasks = EachDay(fromQueryParameter, to).Select(async date =>
            {
                var result = await _measurementTable.Set.Where(m =>
                                                               m.PartitionKey == PartitionKeyHelper.Construct(serialNumber, date) &&
                                                               string.CompareOrdinal(m.RowKey, fromRowKey) <= 0 && string.CompareOrdinal(m.RowKey, toRowKey) > 0
                                                               ).ToListAsync();

                queue.Enqueue(result);
            });

            await Task.WhenAll(tasks);

            var entities = queue.SelectMany(x => x)
                           .Where(e => e.MeasureTimeAdjusted != true)                                 // Exclude adjusted measurements here. Not possible in real query above !
                           .Where(e => !adjustHours || e.MeasureTime > from.AddHours(-adjustedHours)) // Filter
                           .OrderBy(e => e.MeasureTime).ToList();

            // Adjust MeasureTime if needed
            if (adjustHours)
            {
                foreach (var entity in entities)
                {
                    entity.MeasureTime = entity.MeasureTime.AddHours(adjustedHours);
                }
            }

            var deltas = entities.Zip(entities.Skip(1), (current, next) => new QboxCounterData
            {
                MeasureTime = next.MeasureTime,
                Delta0181   = next.Counter0181 - current.Counter0181 ?? 0,
                Delta0182   = next.Counter0182 - current.Counter0182 ?? 0,
                Delta0281   = next.Counter0281 - current.Counter0281 ?? 0,
                Delta0282   = next.Counter0282 - current.Counter0282 ?? 0,
                Delta2421   = next.Counter2421 - current.Counter2421 ?? 0,
            }).ToList();

            if (deltas.Count > 0)
            {
                deltas.Insert(0, new QboxCounterData
                {
                    MeasureTime = entities[0].MeasureTime,
                    Delta0181   = 0,
                    Delta0182   = 0,
                    Delta0281   = 0,
                    Delta0282   = 0,
                    Delta2421   = 0
                });
            }

            var groupedByTimeFrame = from delta in deltas
                                     group delta by new
            {
                MeasureTimeRounded = resolution.TruncateTime(delta.MeasureTime)
            }
            into g
                select new QboxCounterData
            {
                LabelText   = resolution.GetLabelText(g.Key.MeasureTimeRounded),
                LabelValue  = resolution.GetLabelValue(g.Key.MeasureTimeRounded),
                MeasureTime = g.Key.MeasureTimeRounded,
                Delta0181   = g.Sum(x => x.Delta0181),
                Delta0182   = g.Sum(x => x.Delta0182),
                Delta0281   = g.Sum(x => x.Delta0281) * -1,
                Delta0282   = g.Sum(x => x.Delta0282) * -1,
                Delta2421   = g.Sum(x => x.Delta2421)
            };

            var itemsFound = groupedByTimeFrame.ToList();

            var items = FillGaps(from, to, resolution, itemsFound);

            var overview = new QboxCounterData
            {
                LabelText   = "overview",
                MeasureTime = DateTime.UtcNow,
                Delta0181   = entities.Max(e => e.Counter0181) - entities.Min(e => e.Counter0181) ?? 0,
                Delta0182   = entities.Max(e => e.Counter0182) - entities.Min(e => e.Counter0182) ?? 0,
                Delta0281   = (entities.Max(e => e.Counter0281) - entities.Min(e => e.Counter0281) ?? 0) * -1,
                Delta0282   = (entities.Max(e => e.Counter0282) - entities.Min(e => e.Counter0282) ?? 0) * -1,
                Delta2421   = entities.Max(e => e.Counter2421) - entities.Min(e => e.Counter2421) ?? 0
            };

            // Define DrillDownQuery
            if (resolution > QboxQueryResolution.FiveMinutes)
            {
                foreach (var item in items)
                {
                    item.DrillDownQuery = GetDrillDownQboxDataQuery(item.MeasureTime, resolution, adjustHours);
                }
            }

            return(new QboxPagedDataQueryResult <QboxCounterData>
            {
                Overview = overview,
                Items = items,
                Count = items.Count
            });
        }