Exemplo n.º 1
0
        public async Task <IActionResult> GetSettings()
        {
            var user = await userManager.GetUserAsync(User);

            if (user == null)
            {
                return(NotFound("User could not be found"));
            }

            var settings = await dbSettingsRepository.GetSettingsAsync(user.Id);

            return(Ok(settings));
        }
        private async Task <IActionResult> GetMetrics(
            IMetricRepository metricRepository,
            DateTime start,
            DateTime?end        = null,
            TimeGroup timeGroup = TimeGroup.None)
        {
            if (TimeSpanTooLarge(start, end, timeGroup))
            {
                return(BadRequest("Time range is too large for the current resolution"));
            }

            if (end.HasValue && end.Value < start)
            {
                return(BadRequest("Time range is negative (To is smaller than From)"));
            }

            var user = await userManager.GetUserAsync(User);

            var raspberryPiId = await GetRaspberryPiId(user);

            if (!raspberryPiId.HasValue)
            {
                return(NotFound("Either the user does not exist or the user does not have a raspberry pi"));
            }

            var settings = await dbSettingsRepository.GetSettingsAsync(user.Id) ?? new Settings();

            var dbMetrics = (await metricRepository.GetMetrics(raspberryPiId.Value, start, end, settings.TimeZoneId))
                            .ToList();

            if (!dbMetrics.Any())
            {
                return(Ok(new
                {
                    QueryTimestamp = DateTime.UtcNow.AddSeconds(1).ToString("o"),
                    Timestamps = new string[0],
                    Usage = new int[0],
                    Solar = new int[0],
                    Redelivery = new int[0],
                    Intake = new int[0],
                }));
            }

            var format = "";
            List <OutMetricModel> metrics;

            switch (timeGroup)
            {
            case TimeGroup.TenSeconds:
            case TimeGroup.Minutes:
                format = "HH:mm:ss";

                metrics = dbMetrics
                          .Select(d => new OutMetricModel
                {
                    DateTime   = d.Created,
                    Gas        = d.UsageGasNow,
                    Intake     = d.UsageNow,
                    Redelivery = d.RedeliveryNow,
                    Solar      = d.SolarNow,
                    Usage      = d.UsageNow + d.SolarNow - d.RedeliveryNow
                })
                          .ToList();
                break;

            case TimeGroup.Hours:
                format = "MM-dd HH:mm";

                metrics = dbMetrics
                          .Select(d => new OutMetricModel
                {
                    DateTime   = d.Created,
                    Gas        = d.UsageGasNow,
                    Intake     = d.UsageNow,
                    Redelivery = d.RedeliveryNow,
                    Solar      = d.SolarNow,
                    Usage      = d.UsageNow + d.SolarNow - d.RedeliveryNow
                })
                          .ToList();
                break;

            case TimeGroup.Days:
                metrics = dbMetrics
                          .GroupBy(m => m.Created.Date)
                          .Select(m => new
                {
                    First         = m.First(),
                    Last          = m.Last(),
                    SolarTotalMin = m.Any(a => a.SolarTotal > 0) ? m.Where(a => a.SolarTotal > 0).Min(a => a.SolarTotal) : 0,
                    SolarTotalMax = m.Any(a => a.SolarTotal > 0) ? m.Where(a => a.SolarTotal > 0).Max(a => a.SolarTotal) : 0
                })
                          .SelectWithNextOrDefault((c, n) =>
                {
                    var current        = c.First;
                    var next           = n?.First ?? c.Last;
                    current.SolarTotal = c.SolarTotalMin > 0 ? c.SolarTotalMin : n?.SolarTotalMin ?? 0;
                    next.SolarTotal    = n?.SolarTotalMin > 0 ? n.SolarTotalMin : c.SolarTotalMax;

                    return(current.ToOutMetricModel(next, settings));
                })
                          .ToList();

                format = user.Settings.ShowDayName ? "yyyy-MM-dd (dddd)" : "yyyy-MM-dd";
                break;

            // case TimeGroup.Weeks:
            // break;
            case TimeGroup.Months:
                metrics = dbMetrics
                          .GroupBy(m => new
                {
                    m.Created.Date.Year,
                    m.Created.Month
                })
                          .Select(m => new
                {
                    First         = m.First(),
                    Last          = m.Last(),
                    SolarTotalMin = m.Any(a => a.SolarTotal > 0) ? m.Where(a => a.SolarTotal > 0).Min(a => a.SolarTotal) : 0,
                    SolarTotalMax = m.Any(a => a.SolarTotal > 0) ? m.Where(a => a.SolarTotal > 0).Max(a => a.SolarTotal) : 0
                })
                          .SelectWithNextOrDefault((c, n) =>
                {
                    var current        = c.First;
                    var next           = n?.First ?? c.Last;
                    current.SolarTotal = c.SolarTotalMin > 0 ? c.SolarTotalMin : n?.SolarTotalMin ?? 0;
                    next.SolarTotal    = n?.SolarTotalMin > 0 ? n.SolarTotalMin : c.SolarTotalMax;

                    return(current.ToOutMetricModel(next, settings));
                })
                          .ToList();

                format = "yyyy-MM";
                break;

            case TimeGroup.Years:
                metrics = dbMetrics
                          .GroupBy(m => new
                {
                    m.Created.Date.Year
                })
                          .Select(m => new
                {
                    First         = m.First(),
                    Last          = m.Last(),
                    SolarTotalMin = m.Any(a => a.SolarTotal > 0) ? m.Where(a => a.SolarTotal > 0).Min(a => a.SolarTotal) : 0,
                    SolarTotalMax = m.Any(a => a.SolarTotal > 0) ? m.Where(a => a.SolarTotal > 0).Max(a => a.SolarTotal) : 0
                })
                          .SelectWithNextOrDefault((c, n) =>
                {
                    var current        = c.First;
                    var next           = n?.First ?? c.Last;
                    current.SolarTotal = c.SolarTotalMin > 0 ? c.SolarTotalMin : n?.SolarTotalMin ?? 0;
                    next.SolarTotal    = n?.SolarTotalMin > 0 ? n.SolarTotalMin : c.SolarTotalMax;

                    return(current.ToOutMetricModel(next, settings));
                })
                          .ToList();

                format = "yyyy";
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(timeGroup), timeGroup, null);
            }

            var cultureInfo     = new System.Globalization.CultureInfo("nl-NL");
            var timestamps      = metrics.Select(m => m.DateTime.ToString(format, cultureInfo)).ToList();
            var usageList       = metrics.Select(m => m.Usage.DivideByThousand()).ToList();
            var intakeList      = metrics.Select(m => m.Intake.DivideByThousand()).ToList();
            var solarList       = metrics.Select(m => m.Solar.DivideByThousand()).ToList();
            var redeliveryList  = metrics.Select(m => m.Redelivery.DivideByThousand()).ToList();
            var gasList         = metrics.Select(m => m.Gas.DivideByThousand()).ToList();
            var usageCosts      = metrics.Select(m => m.UsageCost).ToList();
            var intakeCosts     = metrics.Select(m => m.IntakeCost).ToList();
            var redeliveryCosts = metrics.Select(m => m.RedeliveryCost).ToList();
            var gasCosts        = metrics.Select(m => m.GasCost).ToList();

            var lastDateTime = metrics
                               .OrderBy(m => m.DateTime)
                               .Select(m => m.DateTime)
                               .LastOrDefault();

            lastDateTime = lastDateTime.ConvertToUtc(settings.TimeZoneId);

            return(Ok(new
            {
                QueryTimestamp = lastDateTime.AddSeconds(1).ToString("o"),
                Timestamps = timestamps,
                Usage = usageList,
                Solar = solarList,
                Redelivery = redeliveryList,
                Intake = intakeList,
                Gas = gasList,
                UsageCosts = usageCosts,
                IntakeCosts = intakeCosts,
                RedeliveryCosts = redeliveryCosts,
                GasCosts = gasCosts
            }));
        }
        public async Task <IActionResult> GetTotalToday()
        {
            var user = await userManager.GetUserAsync(User);

            if (user == null)
            {
                return(BadRequest());
            }

            var settings = await settingsRepository.GetSettingsAsync(user.Id) ?? new Settings();

            var raspberryPiId = await dbContext.Users.Where(u => u.Id.Equals(user.Id))
                                .Select(u => u.RaspberryPi.Id)
                                .FirstOrDefaultAsync();

            var now         = DateTime.UtcNow.Date;
            var midnight    = new DateTime(now.Year, now.Month, now.Day, 0, 0, 0, DateTimeKind.Unspecified);
            var midnightUtc = midnight.ConvertToUtc(settings.TimeZoneId);

            var firstToday = await tenSecondMetricRepository
                             .FirstOrDefaultAsync(q => q
                                                  .Where(t => t.RaspberryPiId == raspberryPiId)
                                                  .Where(t => t.Created > midnightUtc));

            var lastToday = await tenSecondMetricRepository
                            .FirstOrDefaultAsync(q => q
                                                 .Where(t => t.RaspberryPiId == raspberryPiId)
                                                 .Where(t => t.Created > midnightUtc)
                                                 .OrderByDescending(t => t.Created));

            if (firstToday == null || lastToday == null)
            {
                return(Ok(new
                {
                    UsageTotalHigh = (double)0,
                    UsageTotalLow = (double)0,
                    RedeliveryTotalHigh = (double)0,
                    RedeliveryTotalLow = (double)0,
                    TotalSolar = (double)0,
                    TotalGas = (double)0
                }));
            }

            var list = new List <IMetric>
            {
                firstToday,
                lastToday
            };

            var(minSolar, maxSolar) = await tenSecondMetricRepository
                                      .GetMinAndMaxSolarToday(raspberryPiId, settings.TimeZoneId);

            var difference = list
                             .SelectWithPrevious((previous, current) => new
            {
                UsageTotalHigh      = DifferenceInKiloWatt(current.UsageTotalHigh, previous.UsageTotalHigh),
                UsageTotalLow       = DifferenceInKiloWatt(current.UsageTotalLow, previous.UsageTotalLow),
                RedeliveryTotalHigh = DifferenceInKiloWatt(current.RedeliveryTotalHigh, previous.RedeliveryTotalHigh),
                RedeliveryTotalLow  = DifferenceInKiloWatt(current.RedeliveryTotalLow, previous.RedeliveryTotalLow),
                TotalSolar          = DifferenceInKiloWatt(maxSolar, minSolar),
                TotalGas            = DifferenceInKiloWatt(current.UsageGasTotal, previous.UsageGasTotal),
            })
                             .Last();

            return(Ok(difference));
        }