예제 #1
0
        private async Task FetchMeasurementsAsync(DateTime Hour)
        {
            // Discard all old data.
            hourData = new Dictionary <DateTime, List <Measurement> >();

            // Determine where to stop.
            var endHour = Hour.AddHours(PrefetchSize);

            if (endHour > CacheEnd)
            {
                endHour = CacheEnd;
            }

            // Initialize the hour data cache.
            for (DateTime i = Hour; i < endHour; i = i.AddHours(1))
            {
                hourData[i] = new List <Measurement>();
            }

            // Fetch raw data.
            var measurements = await Database.GetRawMeasurementsAsync(SensorId, Hour, endHour);

            // Insert data into cache.
            foreach (var item in measurements)
            {
                var hour = MeasurementAggregation.Quantize(item.Time, TimeSpan.FromHours(1));
                hourData[hour].Add(item);
            }
        }
예제 #2
0
 /// <summary>
 /// Computes the given number of
 /// </summary>
 private void ComputeInCacheHourAverages(
     DateTime Start, int Offset, int Count, Measurement[] Target)
 {
     for (int i = 0; i < Count; i++)
     {
         var hour = Start.AddHours(i + Offset);
         Target[i + Offset] = MeasurementAggregation.Aggregate(hourData[hour], SensorId, hour);
     }
 }
예제 #3
0
        /// <summary>
        /// Gets the hour average for the given hour.
        /// </summary>
        private async Task <Measurement> GetRealHourAverageAsync(DateTime Hour)
        {
            if (hourAverages == null)
            {
                await FetchHourAveragesAsync();
            }

            Measurement result;

            if (hourAverages.TryGetValue(Hour, out result))
            {
                return(result);
            }
            else
            {
                result = MeasurementAggregation.Aggregate(
                    await GetMeasurementsAsync(Hour), SensorId, Hour);
                hourAverages[Hour] = result;
                return(result);
            }
        }
예제 #4
0
        /// <summary>
        /// Gets the day average for the given day.
        /// </summary>
        private async Task <Measurement> GetRealDayAverageAsync(DateTime Day)
        {
            if (dayAverages == null)
            {
                await FetchDayAveragesAsync();
            }

            Measurement result;

            if (dayAverages.TryGetValue(Day, out result))
            {
                return(result);
            }
            else
            {
                result = MeasurementAggregation.Aggregate(
                    await GetRealHourAveragesAsync(Day, 24),
                    SensorId, Day, Enumerable.Average);
                dayAverages[Day] = result;
                return(result);
            }
        }
예제 #5
0
        /// <summary>
        /// Gets the month-average for the given month.
        /// </summary>
        public async Task <Measurement> GetMonthAverageAsync(DateTime Month)
        {
            if (monthAverages == null)
            {
                await FetchMonthAveragesAsync();
            }

            Measurement result;

            if (monthAverages.TryGetValue(Month, out result))
            {
                return(result);
            }
            else
            {
                var timeSpan = Month.AddMonths(1) - Month;
                result = MeasurementAggregation.Aggregate(
                    await GetRealDayAveragesAsync(Month, (int)timeSpan.TotalDays),
                    SensorId, Month, Enumerable.Average);
                monthAverages[Month] = result;
                return(result);
            }
        }
예제 #6
0
        private async Task <IEnumerable <Measurement> > GetMeasurementsAsync(FrozenPeriod Period)
        {
            const int MinutesPerHour = 60;

            switch (Period.Compaction)
            {
            case CompactionLevel.DayAverages:
            case CompactionLevel.HourAverages:
            case CompactionLevel.Measurements:
                // We'll re-create measurement data by replicating
                // hour-average data.
                var results = await GetHourAveragesAsync(
                    MeasurementAggregation.Quantize(Period.StartTime, TimeSpan.FromHours(1)),
                    (int)Math.Ceiling(Period.Duration.TotalHours));

                return(ReplicateEach(results, Period.StartTime, Period.EndTime, TimeSpan.FromMinutes(1), MinutesPerHour).ToArray());

            case CompactionLevel.None:
            default:
                // We can just fetch real measurements from the database.
                return(await Database.GetRawMeasurementsAsync(SensorId, Period.StartTime, Period.EndTime));
            }
        }
예제 #7
0
        private async Task <IEnumerable <Measurement> > GetHourAveragesAsync(FrozenPeriod Period)
        {
            const int HoursPerDay = 24;

            switch (Period.Compaction)
            {
            case CompactionLevel.DayAverages:
            case CompactionLevel.HourAverages:
                // We'll re-create hour-average data by replicating
                // day-average data.
                var results = await GetDayAveragesAsync(
                    MeasurementAggregation.Quantize(Period.StartTime, TimeSpan.FromDays(1)),
                    (int)Math.Ceiling(Period.Duration.TotalDays));

                return(ReplicateEach(results, Period.StartTime, Period.EndTime, TimeSpan.FromHours(1), HoursPerDay).ToArray());

            case CompactionLevel.Measurements:
            case CompactionLevel.None:
            default:
                // We can just fetch or create "real" hour-average data.
                return(await GetRealHourAveragesAsync(Period.StartTime, (int)Period.Duration.TotalHours));
            }
        }
예제 #8
0
        private async Task <IEnumerable <Measurement> > GetDayAveragesAsync(FrozenPeriod Period)
        {
            switch (Period.Compaction)
            {
            case CompactionLevel.DayAverages:
                // We'll re-create day-average data by replicating
                // month-average data.
                var results = new List <Measurement>();
                for (var day = Period.StartTime; day < Period.EndTime; day = day.AddDays(1))
                {
                    var monthMeasurement = await GetMonthAverageAsync(MeasurementAggregation.QuantizeMonth(day));

                    results.Add(new Measurement(SensorId, day, monthMeasurement.MeasuredData, monthMeasurement.Notes));
                }
                return(results);

            case CompactionLevel.HourAverages:
            case CompactionLevel.Measurements:
            case CompactionLevel.None:
            default:
                // We can just fetch or create "real" day-average data.
                return(await GetRealDayAveragesAsync(Period.StartTime, (int)Period.Duration.TotalDays));
            }
        }