예제 #1
0
        public async Task ImportFile(string path)
        {
            using var sr   = new StreamReader(path);
            using var nsql = await NightSql.GetInstance(Configuration);

            DateTimeOffset?dateStart    = null;
            long           msDifference = 0;

            await nsql.StartBatchImport();

            string line = null;

            try
            {
                while (!sr.EndOfStream)
                {
                    line = await sr.ReadLineAsync();

                    if (string.IsNullOrEmpty(line?.Trim()))
                    {
                        continue;
                    }

                    line = line.Replace(' ', '\t');

                    if (line.StartsWith('#'))
                    {
                        var year      = int.Parse(line[1..5]);
예제 #2
0
        public async IAsyncEnumerable <TimeValue> CarbEntries(DateTimeOffset start, DateTimeOffset end)
        {
            using var nsql = await NightSql.GetInstance(Configuration);

            yield return(new TimeValue
            {
                Time = DateTimeOffset.UnixEpoch,
                Value = 0
            });
        }
예제 #3
0
        public async IAsyncEnumerable <TimeValue> BolusEntries(DateTimeOffset start, DateTimeOffset end)
        {
            using var nsql = await NightSql.GetInstance(Configuration);

            var sql        = "SELECT time, amount FROM bolus WHERE time >= @t1 AND time < @t2";
            var parameters = new [] { nsql.GetParameter("t1", start), nsql.GetParameter("t2", end) };

            await foreach (var dr in nsql.ExecuteQuery(sql, parameters))
            {
                yield return(new TimeValue
                {
                    Time = DateTimeOffset.FromUnixTimeMilliseconds(dr.GetInt64(0)),
                    Value = dr.GetDouble(1)
                });
            }
        }
예제 #4
0
        public async Task ImportBg()
        {
            var nsql = await NightSql.GetInstance(Configuration);

            await nsql.StartBatchImport();

            var lastTimestamp = await nsql.GetLastBgDate();

            var entries = MongoDatabase.GetCollection <BsonDocument>("entries");
            var filter  = new FilterDefinitionBuilder <BsonDocument>()
                          .And(
                new FilterDefinitionBuilder <BsonDocument>().Gt <long>("date", lastTimestamp),
                new FilterDefinitionBuilder <BsonDocument>().Eq <string>("type", "sgv")
                );

            using var cursor = await entries.Find(filter).ToCursorAsync();

            while (await cursor.MoveNextAsync())
            {
                foreach (BsonDocument document in cursor.Current)
                {
                    DateTimeOffset?dt = document.SafeDateTimeOffset("date");
                    double?        gv = document.SafePrecisedouble("sgv", 1);

                    if (dt.HasValue && gv.HasValue)
                    {
                        await nsql.Import(new BgValue
                        {
                            Value = gv.Value,
                            Time  = dt.Value
                        });
                    }
                }
            }

            await nsql.FinalizeBatchImport();
        }
예제 #5
0
        public async IAsyncEnumerable <TimeValue> BasalRates(DateTimeOffset start, DateTimeOffset end)
        {
            using var nsql = await NightSql.GetInstance(Configuration);

            var zeroBasalSchedule = (UtcOffset : 0, Rates : new double[48]);

            var basalTimeline     = new IntervalCollection <BasalProfile>();
            var tempBasalTimeline = new IntervalCollection <TempBasal>();

            var bpStart = start;

            var sql = "SELECT * FROM basal WHERE duration = 0 AND time <= @t1 ORDER BY time DESC LIMIT 1";

            await foreach (var bpr in nsql.ExecuteQuery(sql, new [] { nsql.GetParameter("t1", start) }))
            {
                var earlyProfile = await ReadProfile(bpr);

                AddProfileToTimeline(basalTimeline, earlyProfile);
                bpStart = earlyProfile.Time;
            }

            sql = "SELECT * FROM basal WHERE time > @t1 AND time < @t2 ORDER BY time";
            await foreach (var bpr in nsql.ExecuteQuery(sql, new [] { nsql.GetParameter("t1", bpStart), nsql.GetParameter("t2", end) }))
            {
                var profile = await ReadProfile(bpr);

                AddProfileToTimeline(basalTimeline, profile);
            }

            sql = "SELECT * FROM tempbasal WHERE time <= @t1 ORDER BY time DESC LIMIT 1";
            await foreach (var tbr in nsql.ExecuteQuery(sql, new [] { nsql.GetParameter("t1", start) }))
            {
                var earlyTempBasal = await ReadTempBasal(tbr);

                AddTempbasalToTimeline(tempBasalTimeline, earlyTempBasal);
            }

            sql = "SELECT * FROM tempbasal WHERE time > @t1 AND time < @t2 ORDER BY time";
            await foreach (var tbr in nsql.ExecuteQuery(sql, new [] { nsql.GetParameter("t1", start), nsql.GetParameter("t2", end) }))
            {
                AddTempbasalToTimeline(tempBasalTimeline, await ReadTempBasal(tbr));
            }

            var    pointOfInterest  = start;
            double?lastRate         = null;
            var    activeBasalRates = new double[48];
            var    activeUtcOffset  = 0;

            while (pointOfInterest < end)
            {
                var activeBasalInterval     = basalTimeline[pointOfInterest];
                var activeBasal             = activeBasalInterval?.Value;
                var activeTempBasalInterval = tempBasalTimeline[pointOfInterest];
                var activeTempBasal         = activeTempBasalInterval?.Value;

                if (activeBasal.HasValue)
                {
                    for (int i = 0; i < 48; i++)
                    {
                        activeBasalRates[i] = activeBasal.Value.BasalRates[i];
                    }
                    activeUtcOffset = activeBasal.Value.UtcOffsetInMinutes;
                }

                if (activeTempBasal.HasValue)
                {
                    if (activeTempBasal.Value.AbsoluteRate.HasValue)
                    {
                        for (int i = 0; i < 48; i++)
                        {
                            activeBasalRates[i] = activeTempBasal.Value.AbsoluteRate.Value;
                        }
                    }
                    else if (activeTempBasal.Value.Percentage.HasValue)
                    {
                        for (int i = 0; i < 48; i++)
                        {
                            activeBasalRates[i] *= activeTempBasal.Value.Percentage.Value;
                            activeBasalRates[i] /= 100;
                        }
                    }
                }

                var scheduleOffset = pointOfInterest.AddMinutes(activeUtcOffset);
                var scheduleIndex  = scheduleOffset.Hour * 2;
                if (scheduleOffset.Minute > 30)
                {
                    scheduleIndex++;
                }

                var scheduledRate = activeBasalRates[scheduleIndex];

                if (lastRate != scheduledRate)
                {
                    yield return(new TimeValue
                    {
                        Time = pointOfInterest,
                        Value = scheduledRate
                    });

                    lastRate = scheduledRate;
                }

                pointOfInterest = GetNextHalfHourMark(pointOfInterest);

                if (activeBasalInterval?.End < pointOfInterest)
                {
                    pointOfInterest = activeBasalInterval.End;
                }

                if (activeTempBasalInterval?.End < pointOfInterest)
                {
                    pointOfInterest = activeTempBasalInterval.End;
                }
            }
        }