public async Task InjectMeterValueSucceeds()
        {
            using (var client = new NightScoutClient(BaseUri, TemporaryToken, Log))
            {
                var createdAt = DateTimeOffset.Parse("2019-01-17T00:00:00Z");
                var from      = DateTimeOffset.Parse("2019-01-17T00:00:00Z");
                var to        = DateTimeOffset.Parse("2019-01-17T23:59:59Z");

                Entry latestInjectedMeterValueEntry =
                    await GetLatestInjectedMeterValueAsync(client, from, to);

                if (latestInjectedMeterValueEntry != null)
                {
                    createdAt = createdAt.AddSeconds(1);
                }

                uint expectedMeterValue = (uint)(90 + rnd.Next(20));

                Entry postResponse = await client.InjectMeterBloodGlucoseValueAsync(
                    CancellationToken.None,
                    createdAt,
                    expectedMeterValue);

                latestInjectedMeterValueEntry =
                    await GetLatestInjectedMeterValueAsync(client, from, to);

                Assert.IsNotNull(latestInjectedMeterValueEntry, nameof(latestInjectedMeterValueEntry));
                Assert.IsNotNull(latestInjectedMeterValueEntry.Mbg, nameof(latestInjectedMeterValueEntry.Mbg));
                Assert.AreEqual(postResponse.Date, latestInjectedMeterValueEntry.Date, nameof(latestInjectedMeterValueEntry.Date));
                Assert.AreEqual(postResponse.Mbg, latestInjectedMeterValueEntry.Mbg, nameof(latestInjectedMeterValueEntry.Mbg));
                Assert.AreEqual(expectedMeterValue, latestInjectedMeterValueEntry.Mbg, nameof(latestInjectedMeterValueEntry.Mbg));

                Console.WriteLine("OUTPUT: {0}", latestInjectedMeterValueEntry);
            }
        }
        public async Task SetDailySummaryTreatmentSucceeds()
        {
            using (var client = new NightScoutClient(BaseUri, TemporaryToken, Log))
            {
                var createdAt = DateTimeOffset.Parse("2018-11-11T00:00:00Z");
                var from      = DateTimeOffset.Parse("2018-11-11T00:00:00Z");
                var to        = DateTimeOffset.Parse("2018-11-11T23:59:59Z");

                Treatment currentDailySummaryTreatment =
                    await GetLatestDailySummaryAsync(client, from, to);

                if (currentDailySummaryTreatment != null)
                {
                    createdAt = createdAt.AddSeconds(1);
                }

                string expectedNotes = Guid.NewGuid().ToString("N");

                Treatment postResponse = await client.SetDailySummaryTreatmentsAsync(
                    CancellationToken.None,
                    createdAt,
                    expectedNotes);

                currentDailySummaryTreatment =
                    await GetLatestDailySummaryAsync(client, from, to);

                Assert.IsNotNull(currentDailySummaryTreatment, nameof(currentDailySummaryTreatment));
                Assert.IsNotNull(currentDailySummaryTreatment.Notes, nameof(currentDailySummaryTreatment.Notes));
                Assert.AreEqual(postResponse.CreatedAt, currentDailySummaryTreatment.CreatedAt, nameof(currentDailySummaryTreatment.Notes));
                Assert.AreEqual(postResponse.Notes, currentDailySummaryTreatment.Notes, nameof(currentDailySummaryTreatment.Notes));
                Assert.AreEqual(expectedNotes, currentDailySummaryTreatment.Notes, nameof(currentDailySummaryTreatment.Notes));

                Console.WriteLine("OUTPUT: {0}", currentDailySummaryTreatment);
            }
        }
        public async Task GetDefaultProfileSucceeds()
        {
            using (var client = new NightScoutClient(BaseUri, TemporaryToken, Log))
            {
                Profile profile = await client.GetDefaultProfileAsync(CancellationToken.None);

                Assert.IsNotNull(profile, nameof(profile));
            }
        }
        public async Task GetEntriesSucceeds()
        {
            using (var client = new NightScoutClient(BaseUri, TemporaryToken, Log))
            {
                IList <Entry> entries = await client.GetEntriesAsync(CancellationToken.None);

                Assert.IsNotNull(entries, nameof(entries));
                Assert.AreEqual(300, entries.Count, nameof(entries.Count));

                Console.WriteLine("OUTPUT: {0}", entries);
            }
        }
        public async Task GetEntrySucceeds()
        {
            using (var client = new NightScoutClient(BaseUri, TemporaryToken, Log))
            {
                Entry entry = await client.GetEntryAsync("5be8bd455a6f96e567696f3c", CancellationToken.None);

                Assert.IsNotNull(entry, nameof(entry));
                Assert.AreEqual(68, entry.Sgv, nameof(entry.Sgv));
                Assert.AreEqual("2018-11-11T15:38:05.186-0800", entry.DateString, nameof(entry.DateString));
                Assert.AreEqual(1541979485186, entry.Date, nameof(entry.Date));
                Assert.AreEqual("Flat", entry.Direction, nameof(entry.Direction));

                Console.WriteLine("OUTPUT: {0}", entry);
            }
        }
        private static async Task <Treatment> GetLatestDailySummaryAsync(
            NightScoutClient client,
            DateTimeOffset from,
            DateTimeOffset to)
        {
            IList <Treatment> treatments = await client.GetTreatmentsAsync(
                CancellationToken.None,
                id : null,
                from : DateTimeOffset.Parse("2018-11-11T00:00:00Z"),
                to : DateTimeOffset.Parse("2018-11-11T23:59:59Z"),
                maxCount : null);

            Treatment[] temp = treatments
                               .Where(t => t.EnteredBy == "NightScoutReporter" && t.EventType == "Note")
                               .OrderBy(t => t.CreatedAt).ToArray();

            return(temp.LastOrDefault());
        }
        private static async Task <Entry> GetLatestInjectedMeterValueAsync(
            NightScoutClient client,
            DateTimeOffset from,
            DateTimeOffset to)
        {
            IList <Entry> entries = await client.GetEntriesAsync(
                CancellationToken.None,
                EntryType.All,
                from : from,
                to : to,
                maxCount : null);

            Entry[] temp = entries
                           .Where(e => e.Device == "NightScoutReporter").ToArray();

            temp = entries
                   .Where(e => e.Type == "mbg").ToArray();

            temp = entries
                   .Where(e => e.Device == "NightScoutReporter" && e.Type == "mbg")
                   .OrderBy(e => e.Date).ToArray();

            return(temp.LastOrDefault());
        }
        public async Task GetTreatmentSucceeds()
        {
            using (var client = new NightScoutClient(BaseUri, TemporaryToken, Log))
            {
                Treatment treatment = (await client.GetTreatmentsAsync(CancellationToken.None,
                                                                       id: "5be85efd8a56a01558e2233d",
                                                                       from: DateTimeOffset.Parse("2018-11-11T16:55:41Z"),
                                                                       to: DateTimeOffset.Parse("2018-11-11T16:55:41Z"),
                                                                       maxCount: 1)).SingleOrDefault();

                Assert.IsNotNull(treatment, nameof(treatment));
                Assert.AreEqual("Bolus Wizard", treatment.EventType, nameof(treatment.EventType));
                Assert.IsNotNull(treatment.Insulin, nameof(treatment.Insulin));
                Assert.AreEqual(2.7m, treatment.Insulin, nameof(treatment.Insulin));
                Assert.AreEqual("2018-11-11T16:55:41Z", treatment.CreatedAt, nameof(treatment.CreatedAt));
                Assert.AreEqual(1541955341000, treatment.Date, nameof(treatment.Date));
                Assert.AreEqual(false, treatment.IsSuperMicroBolus, nameof(treatment.IsSuperMicroBolus));
                Assert.AreEqual("1541955341000", treatment.PumpId, nameof(treatment.PumpId));
                Assert.IsNotNull(treatment.Glucose, nameof(treatment.Glucose));
                Assert.AreEqual(81m, treatment.Glucose, nameof(treatment.Glucose));
                Assert.AreEqual("Manual", treatment.GlucoseType, nameof(treatment.GlucoseType));
                Assert.AreEqual("1541955350978", treatment.NightScoutClientId, nameof(treatment.NightScoutClientId));
                Assert.IsNull(treatment.Carbs, nameof(treatment.Carbs));

                Assert.IsNotNull(treatment.BolusCalculation, nameof(treatment.BolusCalculation));
                Assert.AreEqual(
                    "<Active>",
                    treatment.BolusCalculation.Profile,
                    nameof(treatment.BolusCalculation.Profile));
                Assert.AreEqual(
                    DateTimeOffset.Parse("2018-11-11T16:55:07Z"),
                    treatment.BolusCalculation.EventTime,
                    nameof(treatment.BolusCalculation.EventTime));
                Assert.AreEqual(
                    80,
                    treatment.BolusCalculation.TargetBGLow,
                    nameof(treatment.BolusCalculation.TargetBGLow));
                Assert.AreEqual(
                    110,
                    treatment.BolusCalculation.TargetBGHigh,
                    nameof(treatment.BolusCalculation.TargetBGHigh));
                Assert.AreEqual(
                    30,
                    treatment.BolusCalculation.InsulinSensitivityFactor,
                    nameof(treatment.BolusCalculation.InsulinSensitivityFactor));
                Assert.AreEqual(9,
                                treatment.BolusCalculation.InsulinToCarbRatio,
                                nameof(treatment.BolusCalculation.InsulinToCarbRatio));
                Assert.AreEqual(
                    -0.37500000000000006m, //rounded from -0.37500000000000008 - that's fine here
                    treatment.BolusCalculation.InsulinOnBoard,
                    nameof(treatment.BolusCalculation.InsulinOnBoard));
                Assert.AreEqual(
                    true,
                    treatment.BolusCalculation.BasalInsulinOnBoardUsed,
                    nameof(treatment.BolusCalculation.BasalInsulinOnBoardUsed));
                Assert.AreEqual(
                    true,
                    treatment.BolusCalculation.BolusInsulinOnBoardUsed,
                    nameof(treatment.BolusCalculation.BolusInsulinOnBoardUsed));
                Assert.AreEqual(
                    81,
                    treatment.BolusCalculation.BloodGlucose,
                    nameof(treatment.BolusCalculation.BloodGlucose));
                Assert.AreEqual(
                    0,
                    treatment.BolusCalculation.InsulinCorrectionForBloodGlucose,
                    nameof(treatment.BolusCalculation.InsulinCorrectionForBloodGlucose));
                Assert.AreEqual(
                    true,
                    treatment.BolusCalculation.InsulinCorrectionForBloodGlucoseUsed,
                    nameof(treatment.BolusCalculation.InsulinCorrectionForBloodGlucoseUsed));
                Assert.AreEqual(
                    0,
                    treatment.BolusCalculation.BloodGlucoseDiffFromTarget,
                    nameof(treatment.BolusCalculation.BloodGlucoseDiffFromTarget));
                Assert.AreEqual(
                    1.3333333333333333m,
                    treatment.BolusCalculation.InsulinForCarbs,
                    nameof(treatment.BolusCalculation.InsulinForCarbs));
                Assert.AreEqual(
                    12,
                    treatment.BolusCalculation.Carbs,
                    nameof(treatment.BolusCalculation.Carbs));
                Assert.AreEqual(
                    0,
                    treatment.BolusCalculation.CarbsOnBoard,
                    nameof(treatment.BolusCalculation.CarbsOnBoard));
                Assert.AreEqual(
                    0,
                    treatment.BolusCalculation.InsulinCorrectionForCarbsOnBoard,
                    nameof(treatment.BolusCalculation.InsulinCorrectionForCarbsOnBoard));
                Assert.AreEqual(
                    1.4m,
                    treatment.BolusCalculation.OtherCorrection,
                    nameof(treatment.BolusCalculation.OtherCorrection));
                Assert.AreEqual(
                    0,
                    treatment.BolusCalculation.InsulinCorrectionForSuperBolus,
                    nameof(treatment.BolusCalculation.InsulinCorrectionForSuperBolus));
                Assert.AreEqual(
                    -0.356m,
                    treatment.BolusCalculation.InsulinCorrectionForBloodGlucoseTrend,
                    nameof(treatment.BolusCalculation.InsulinCorrectionForBloodGlucoseTrend));
                Assert.AreEqual(
                    2.8000000000000003m, // rounded from 2.8000000000000004 - that's fine here
                    treatment.BolusCalculation.Insulin,
                    nameof(treatment.BolusCalculation.Insulin));

                Console.WriteLine("OUTPUT: {0}", treatment);
            }
        }
Example #9
0
        public async Task OnGetAsync()
        {
            try
            {
                if (!this.Request.Query.TryGetValue("Hostname", out StringValues hostnameValues) ||
                    hostnameValues.Count != 1 ||
                    !Uri.TryCreate(
                        "https://" + hostnameValues[0],
                        UriKind.Absolute,
                        out Uri baseUri))
                {
                    throw new ArgumentException(
                              "Query parameter 'Hostname' is missing or invalid.",
                              "Hostname");
                }
                ;

                if (!this.Request.Query.TryGetValue("Day", out StringValues dayValues) ||
                    dayValues.Count != 1 ||
                    dayValues[0].Length != 10 ||
                    !DateTimeOffset.TryParseExact(
                        dayValues[0],
                        format: "yyyy-MM-dd",
                        formatProvider: CultureInfo.InvariantCulture,
                        styles: DateTimeStyles.AssumeUniversal,
                        result: out DateTimeOffset parsedDay))
                {
                    throw new ArgumentException(
                              "Query parameter 'Day' is missing or invalid. It must have the format 'yyyy-MM-dd'",
                              "Day");
                }
                ;

                if (!this.Request.Query.TryGetValue("Token", out StringValues tokenValues) ||
                    tokenValues.Count != 1 ||
                    String.IsNullOrWhiteSpace(tokenValues[0]))
                {
                    throw new ArgumentException(
                              "Query parameter 'Token' is missing.",
                              "Token");
                }
                ;

                this.DayQueryParameter = parsedDay.ToString("yyyy-MM-dd");

                for (int i = 0; i < 12 * 24; i++)
                {
                    this.timeLineLabels5M[i] = String.Concat("'", parsedDay.AddMinutes(5 * i).ToString("HH:mm"), "'");
                    this.sgvs[i]             = "NaN";
                    this.mbgvs[i]            = "NaN";
                }

                using (var client = new NightScoutClient(baseUri, tokenValues[0], this.logger))
                {
                    Profile profile = await client.GetDefaultProfileAsync(CancellationToken.None);

                    //TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(profile.)


                    Task <IList <Entry> > entriesTask = client.GetEntriesAsync(
                        CancellationToken.None,
                        from: parsedDay,
                        to: parsedDay.AddDays(1).AddMilliseconds(-1),
                        maxCount: 300);

                    Task <IList <Treatment> > treatmentsTask = client.GetTreatmentsAsync(
                        CancellationToken.None,
                        id: null,
                        from: parsedDay,
                        to: parsedDay.AddDays(1).AddMilliseconds(-1),
                        maxCount: 300);

                    await Task.WhenAll(entriesTask, treatmentsTask);

                    IList <Entry>     entries    = entriesTask.Result;
                    IList <Treatment> treatments = treatmentsTask.Result;

                    decimal suggestedMaxGlucoseValue = 180;

                    SetBloodGlucoseLevels(
                        parsedDay,
                        entries,
                        entryType: "sgv",
                        getGlucoseValue: new Func <Entry, decimal?>(e => e.Sgv),
                        values:  this.sgvs,
                        suggestedMaxGlucoseValue: ref suggestedMaxGlucoseValue);

                    SetBloodGlucoseLevels(
                        parsedDay,
                        entries,
                        entryType: "mbg",
                        getGlucoseValue: new Func <Entry, decimal?>(e => e.Mbg),
                        values: this.mbgvs,
                        suggestedMaxGlucoseValue: ref suggestedMaxGlucoseValue);

                    suggestedMaxGlucoseValue = ((int)((suggestedMaxGlucoseValue * 1.1m) / 10)) * 10 + 10;

                    this.WarningHigh              = Math.Min(240, suggestedMaxGlucoseValue).ToString("###.##");
                    this.CriticalHigh             = suggestedMaxGlucoseValue.ToString("###.##");
                    this.SuggestedMaxGlucoseValue = suggestedMaxGlucoseValue;

                    this.SerumGlucoseValues      = String.Join(',', this.sgvs);
                    this.MeterBloodGlucoseValues = String.Join(',', this.mbgvs);
                    this.TimeLineLabels5M        = new HtmlString(String.Join(',', this.timeLineLabels5M));

                    for (int i = 0; i < 60 * 24; i++)
                    {
                        this.timeLineLabels1M[i] = String.Concat("'", parsedDay.AddMinutes(i).ToString("HH:mm"), "'");
                    }

                    var orderedBasalRates = new List <ProfileDefinition>(profile.BasalRate.OrderBy(br => br.TimeAsSeconds));
                    for (int i = 0; i < orderedBasalRates.Count; i++)
                    {
                        int left = (int)orderedBasalRates[i].TimeAsSeconds / 60;
                        int right;
                        if (i < orderedBasalRates.Count - 1)
                        {
                            right = (int)orderedBasalRates[i + 1].TimeAsSeconds / 60;
                        }
                        else
                        {
                            right = 60 * 24;
                        }

                        for (int n = left; n < right; n++)
                        {
                            this.targetBasalRateValues[n] = orderedBasalRates[i].Value.ToString("##0.##", CultureInfo.InvariantCulture);
                        }
                    }

                    var temporaryBasalRateTreatments = new List <Treatment>(
                        treatments.Where(t => t.EventType == "Temp Basal").OrderBy(t => t.CreatedAt));

                    var tempBasalRates = new List <TempBasal>();

                    for (int i = 0; i < temporaryBasalRateTreatments.Count; i++)
                    {
                        Treatment current = temporaryBasalRateTreatments[i];
                        if (current.Percent == null)
                        {
                            continue;
                        }

                        int start = (int)(DateTimeOffset.Parse(current.CreatedAt, CultureInfo.InvariantCulture) - parsedDay).TotalMinutes;
                        var tbr   = new TempBasal
                        {
                            Start  = start,
                            End    = start + current.Duration.Value,
                            Factor = temporaryBasalRateTreatments[i].Percent.Value / 100,
                        };

                        if (i < temporaryBasalRateTreatments.Count - 1)
                        {
                            Treatment next      = temporaryBasalRateTreatments[i + 1];
                            int       nextStart = (int)(DateTimeOffset.Parse(next.CreatedAt, CultureInfo.InvariantCulture) - parsedDay).TotalMinutes;

                            tbr.End = Math.Min(tbr.End, nextStart);
                        }

                        tempBasalRates.Add(tbr);
                    }

                    for (int i = 0; i < this.targetBasalRateValues.Length; i++)
                    {
                        this.actualBasalRateValues[i] = this.targetBasalRateValues[i];
                    }

                    for (int i = 0; i < tempBasalRates.Count; i++)
                    {
                        for (int n = tempBasalRates[i].Start; n < tempBasalRates[i].End; n++)
                        {
                            decimal targetRate   = Decimal.Parse(this.actualBasalRateValues[n], CultureInfo.InvariantCulture);
                            decimal adjustedRate = targetRate * (1 + tempBasalRates[i].Factor);
                            this.actualBasalRateValues[n] = adjustedRate.ToString("##0.##", CultureInfo.InvariantCulture);
                        }
                    }

                    this.TimeLineLabels1M = new HtmlString(String.Join(',', this.timeLineLabels1M));
                    this.TargetBasalRates = new HtmlString(String.Join(',', this.targetBasalRateValues));
                    this.ActualBasalRates = new HtmlString(String.Join(',', this.actualBasalRateValues));

                    var eventTypes = new HashSet <string>(
                        treatments.Select(t => t.EventType));

                    Treatment dailySummaryTreatment = treatments
                                                      .Where(t => t.EventType == "NightScoutReporterDailySummary")
                                                      .OrderBy(t => t.CreatedAt)
                                                      .LastOrDefault();

                    if (dailySummaryTreatment != null &&
                        !String.IsNullOrWhiteSpace(dailySummaryTreatment.Notes))
                    {
                        this.DailySummary = new HtmlString(String.Join(',', eventTypes));
                    }
                    else
                    {
                        this.DailySummary = new HtmlString("Keine");
                    }

                    List <MealBolusTreatment> mealBoulsTreatments = ToMealBolusTreatments(treatments);
                    var sb = new StringBuilder();

                    if (mealBoulsTreatments.Count > 0)
                    {
                        sb.Append("<table>")
                        .Append("<tr>")
                        .Append("<th width='15%' align='left'>Uhrzeit</th>")
                        .Append("<th width='15%' align='right'>BG (in mg/dl)</th>")
                        .Append("<th width='15%' align='right'>KH (in g)</th>")
                        .Append("<th width='25%' align='right'>IE (+/- Korrektur)</th>")
                        .Append("<th width='15%' align='right'>COB (in g)</th>")
                        .Append("<th width='15%' align='right'>IOB (in IE)</th>")
                        .Append("</tr>");

                        foreach (MealBolusTreatment t in mealBoulsTreatments)
                        {
                            string insulinText = String.Empty;

                            if (t.Insulin != null)
                            {
                                if (t.InsulinCorrection != null)
                                {
                                    insulinText = String.Format(
                                        CultureInfo.InvariantCulture,
                                        "{0} [{1}]",
                                        t.Insulin.Value.ToString("###0.00"),
                                        t.InsulinCorrection.Value.ToString("###0.00"));
                                }
                                else
                                {
                                    insulinText = t.Insulin.Value.ToString("###0.00");
                                }
                            }

                            sb
                            .Append("<tr>")
                            .Append("<td align='left' style='font-weight:bold'>").Append(t.CreatedAt.Substring(11, 8)).Append("</td>")
                            .Append("<td align='right'>")
                            .Append(t.BG != null ? t.BG.Value.ToString("###0") : String.Empty).Append("</td>")
                            .Append("<td align='right'>")
                            .Append(t.Carbs != null ?
                                    t.Carbs.Value.ToString("###0") :
                                    String.Empty).Append("</td>")
                            .Append("<td align='right'>").Append(insulinText).Append("</td>")
                            .Append("<td align='right'>")
                            .Append(t.CarbsOnBoard != null ?
                                    t.CarbsOnBoard.Value.ToString("###0") :
                                    String.Empty).Append("</td>")
                            .Append("<td align='right'>")
                            .Append(t.InsulinOnBoard != null ?
                                    t.InsulinOnBoard.Value.ToString("###0.00") :
                                    String.Empty).Append("</td>")
                            .Append("</tr>");
                        }

                        sb.Append("</table>");
                    }

                    this.Meals = new HtmlString(sb.ToString());
                }
            }
            catch (Exception error)
            {
                this.logger.LogError(error, "Error in OnGet: {0}", error.ToString());
                throw;
            }
        }