Просмотр исходного кода

Revert, Redo everything.
Use glucose.json for every calculation.
Extend storage in glucose.json to 120 days (For HbA1c and averages in stats).
Use just one array with all (growing) data in DailyStats instead.

Jon Mårtensson 3 лет назад
Родитель
Сommit
12cdc3cac9

+ 80 - 100
FreeAPS/Sources/APS/APSManager.swift

@@ -724,7 +724,6 @@ final class BaseAPSManager: APSManager, Injectable {
         let carbs = storage.retrieve(OpenAPS.Monitor.carbHistory, as: [CarbsEntry].self)
         let tdds = storage.retrieve(OpenAPS.Monitor.tdd, as: [TDD].self)
         let currentTDD = tdds?[0].TDD
-
         let carbs_length = carbs?.count ?? 0
         var carbTotal: Decimal = 0
 
@@ -769,83 +768,72 @@ final class BaseAPSManager: APSManager, Injectable {
             iPa = 50
         }
 
-        // Averages:
-        // If more than l day of stats:
-        let stats = storage.retrieve(OpenAPS.Monitor.dailyStats, as: [DailyStats].self)
-
-        var avgS: Decimal = 0
-        var nrAvgs: Decimal = 0
-        var sevenDaysAvg: Decimal = 0
-        var thirtyDaysAverage: Decimal = 0
-        var totalDataAvg: Decimal = 0
-        let arraysInjson = stats?.count ?? 0
-        // let end = arraysInjson - 1
-        print("arraysInjson: \(arraysInjson)")
-        var i = 0
-
-        if arraysInjson > 1 {
-            while i < arraysInjson {
-                avgS += stats?[i].BG_daily_Average_mg_dl as! Decimal
-                nrAvgs += 1
-                if nrAvgs >= 1 {
-                    totalDataAvg = avgS / nrAvgs
-                }
-                if nrAvgs == 7 {
-                    sevenDaysAvg = avgS / nrAvgs
-                }
-                if nrAvgs == 30 {
-                    thirtyDaysAverage = avgS / nrAvgs
-                }
-                i += 1
-            }
-        }
-
         // HbA1c estimation (%, mmol/mol)
-        let NGSPa1CStatisticValue = (46.7 + tir().averageGlucose) / 28.7 // NGSP (%)
+        let NGSPa1CStatisticValue = (46.7 + tir().averageGlucose_1) / 28.7 // NGSP (%)
         let IFCCa1CStatisticValue = 10.929 *
             (NGSPa1CStatisticValue - 2.152) // IFCC (mmol/mol)  A1C(mmol/mol) = 10.929 * (A1C(%) - 2.15)
         // 7 days
-        let NGSPa1CStatisticValue_7 = (46.7 + sevenDaysAvg) / 28.7
+        let NGSPa1CStatisticValue_7 = (46.7 + tir().averageGlucose_7) / 28.7
         let IFCCa1CStatisticValue_7 = 10.929 * (NGSPa1CStatisticValue_7 - 2.152)
         // 14 days
-        let NGSPa1CStatisticValue_30 = (46.7 + thirtyDaysAverage) / 28.7
+        let NGSPa1CStatisticValue_30 = (46.7 + tir().averageGlucose_30) / 28.7
         let IFCCa1CStatisticValue_30 = 10.929 * (NGSPa1CStatisticValue_30 - 2.152)
         // All days
-        let NGSPa1CStatisticValue_total = (46.7 + totalDataAvg) / 28.7
+        let NGSPa1CStatisticValue_total = (46.7 + tir().averageGlucose) / 28.7
         let IFCCa1CStatisticValue_total = 10.929 * (NGSPa1CStatisticValue_total - 2.152)
 
-        // HbA1c string:
+        // HbA1c string and BG string:
+
+        var HbA1c_string_1 = ""
         var string7Days = ""
         var string30Days = ""
         var stringTotal = ""
 
-        switch arraysInjson {
-        case 7...:
+        var bgString1day = ""
+        var bgString7Days = ""
+        var bgString30Days = ""
+        var bgAverageTotalString = ""
+
+        let daysBG = tir().daysWithBG
+        print("Days with BG: \(daysBG)")
+
+        let avg1 = tir().averageGlucose_1
+        let avg7 = tir().averageGlucose_7
+        let avg30 = tir().averageGlucose_30
+        let avgTot = tir().averageGlucose
+
+        if avg1 != 0 {
+            bgString1day = " Average BG (mmol/l, 1 day): \(roundDecimal(avg1 * 0.0555, 1)). Average BG (mmg/dl, 1 day): \(avg1)."
+            HbA1c_string_1 =
+                "Estimated HbA1c (%, 1 day): \(roundDecimal(NGSPa1CStatisticValue, 1)). Estimated HbA1c (mmol/mol, 1 day): \(roundDecimal(IFCCa1CStatisticValue, 1))."
+        }
+        if avg7 != 0 {
             string7Days =
-                " HbA1c 7 days: \(roundDecimal(IFCCa1CStatisticValue_7, 1)) mmol/mol / \(roundDecimal(NGSPa1CStatisticValue_7, 1)) %."
-            fallthrough
-        case 30...:
+                " HbA1c 7 days (mmol/mol): \(roundDecimal(IFCCa1CStatisticValue_7, 1)). HbA1c 7 days (%): \(roundDecimal(NGSPa1CStatisticValue_7, 1))."
+            bgString7Days = " Average BG (mmol/l) 7 days: \(roundDecimal(avg7 * 0.0555, 1)). Average BG (mg/dl) 7 days: \(avg7)."
+        }
+        if avg30 != 0 {
             string30Days =
-                " HbA1c 30 days: \(roundDecimal(IFCCa1CStatisticValue_30, 1)) mmol/mol / \(roundDecimal(NGSPa1CStatisticValue_30, 1)) %."
-            fallthrough
-        case 2...:
+                " HbA1c 30 days (mmol/mol): \(roundDecimal(IFCCa1CStatisticValue_30, 1)).  HbA1c 30 days (%): \(roundDecimal(NGSPa1CStatisticValue_30, 1))."
+            bgString30Days =
+                " Average BG 30 days (mmol/l): \(roundDecimal(avg30 * 0.0555, 1)). Average BG 30 days (mg/dl): \(avg30). "
+        }
+        if avgTot != 0, daysBG >= 2 {
             stringTotal =
-                " HbA1c \(arraysInjson) days: \(roundDecimal(IFCCa1CStatisticValue_total, 1)) mmol/mol / \(roundDecimal(NGSPa1CStatisticValue_total, 1)) %."
-        default:
-            stringTotal = ""
+                " HbA1c Total (\(daysBG)) Days (mmol/mol): \(roundDecimal(IFCCa1CStatisticValue_total, 1)). HbA1c Total (\(daysBG)) Days (mg/dl): \(roundDecimal(NGSPa1CStatisticValue_total, 1)) %."
+            bgAverageTotalString =
+                "BG Average Total (\(daysBG)) Days (mmol/l): \(roundDecimal(avgTot * 0.0555, 1)). BG Average Total (\(daysBG)) Days (mmg/dl): \(avgTot)."
         }
 
-        let HbA1c_string =
-            "Estimated HbA1c (%): \(roundDecimal(NGSPa1CStatisticValue, 1)). Estimated HbA1c (mmol/mol): \(roundDecimal(IFCCa1CStatisticValue, 1))." +
-            string7Days + string30Days + stringTotal
+        let HbA1c_string = HbA1c_string_1 + string7Days + string30Days + stringTotal
 
         let tirString =
             "\(tir().TIR) %. Time with Hypoglucemia: \(tir().hypos) % (< 4 mmol/l or 72 mg/dl). Time with Hyperglucemia: \(tir().hypers) % (> 10 mmol/l or 180 mg/dl)."
 
-        let averageBG = tir().averageGlucose
+        let bgAverageString = bgString1day + bgString7Days + bgString30Days + bgAverageTotalString
 
         let dailystat = DailyStats(
-            date: Date(),
+            createdAt: Date(),
             FAX_Build_Version: version,
             FAX_Build_Number: build ?? "1",
             FAX_Branch: branch ?? "N/A",
@@ -859,62 +847,27 @@ final class BaseAPSManager: APSManager, Injectable {
             TDD: currentTDD ?? 0,
             Carbs_24h: carbTotal,
             TIR: tirString,
-            BG_daily_Average_mg_dl: averageBG,
-            BG_daily_Average_mmol_l: roundDecimal(averageBG * 0.0555, 2),
+            BG_Average: bgAverageString,
             HbA1c: HbA1c_string,
             id: UUID().uuidString
         )
 
-        var newEntries: [DailyStats] = []
-
-        // If file is empty
-        let file_3 = loadFileFromStorage(name: OpenAPS.Monitor.dailyStats)
-        var isJSONempty = false
-        if file_3.rawJSON.isEmpty {
-            isJSONempty = true
-        }
-
-        let now = Date()
-        let calender = Calendar.current
-
         file = OpenAPS.Monitor.dailyStats
 
-        let stats_ = storage.retrieve(OpenAPS.Monitor.dailyStats, as: [DailyStats].self)
-
-        let arraysInjson_ = stats_?.count ?? 0
-        var time_ = Date()
-        var timePlus = Date()
-
-        if arraysInjson_ > 0 {
-            time_ = stats_?[0].date ?? Date()
-            timePlus = time_.addingTimeInterval(20.hours.timeInterval)
-        }
-
-        // If current local time is 23:41 or later
-        if calender.component(.hour, from: now) == 0,
-           calender.component(.minute, from: now) > 0
-        {
-            if isJSONempty || arraysInjson == 0 {
-                storage.save(dailystat, as: file)
-            } else if now > timePlus {
-                storage.transaction { storage in
-                    storage.append(dailystat, to: file, uniqBy: \.id)
-                    newEntries = storage.retrieve(file, as: [DailyStats].self)?
-                        .filter { $0.date.addingTimeInterval(120.days.timeInterval) > Date() }
-                        .sorted { $0.date > $1.date } ?? []
-                    storage.save(newEntries, as: OpenAPS.Monitor.dailyStats)
-                }
-            }
-        }
+        storage.save(dailystat, as: file)
     }
 
     // Time In Range (%) and Average Glucose (24 hours)
     func tir()
         -> (
             averageGlucose: Decimal,
+            averageGlucose_1: Decimal,
+            averageGlucose_7: Decimal,
+            averageGlucose_30: Decimal,
             hypos: Decimal,
             hypers: Decimal,
-            TIR: Decimal
+            TIR: Decimal,
+            daysWithBG: Decimal
         )
     {
         let glucose = storage.retrieve(OpenAPS.Monitor.glucose, as: [BloodGlucose].self)
@@ -923,22 +876,45 @@ final class BaseAPSManager: APSManager, Injectable {
         let endIndex = length_ - 1
 
         guard length_ != 0 else {
-            return (0, 0, 0, 0)
+            return (0, 0, 0, 0, 0, 0, 0, 0)
         }
 
         var bg: Decimal = 0
         var nr_bgs: Decimal = 0
+        let startDate = glucose![0].date
+        var end1 = false
+        var end7 = false
+        var end30 = false
+        var bg_1: Decimal = 0
+        var bg_7: Decimal = 0
+        var bg_30: Decimal = 0
 
         for entry in glucose! {
             if entry.glucose! > 0 {
                 bg += Decimal(entry.glucose!)
                 nr_bgs += 1
+
+                if startDate - entry.date > 8.64E7, !end1 {
+                    end1 = true
+                    bg_1 = bg / nr_bgs
+                }
+
+                if startDate - entry.date > 6.045E8, !end7 {
+                    end7 = true
+                    bg_7 = bg / nr_bgs
+                }
+                if startDate - entry.date > 2.59E9, !end30 {
+                    end30 = true
+                    bg_30 = bg / nr_bgs
+                }
             }
         }
 
-        let averageGlucose_ = bg / nr_bgs
-
+        let bg_120 = bg / nr_bgs
         let fullTime = glucose![0].date - glucose![endIndex].date
+
+        let daysBG = fullTime / 8.64E7
+
         var timeInHypo: Decimal = 0
         var timeInHyper: Decimal = 0
         var hypos: Decimal = 0
@@ -979,10 +955,14 @@ final class BaseAPSManager: APSManager, Injectable {
         let TIR = 100 - (hypos + hypers)
 
         return (
-            roundDecimal(averageGlucose_, 0),
+            roundDecimal(bg_120, 0),
+            roundDecimal(bg_1, 0),
+            roundDecimal(bg_7, 0),
+            roundDecimal(bg_30, 0),
             roundDecimal(hypos, 1),
             roundDecimal(hypers, 1),
-            roundDecimal(TIR, 1)
+            roundDecimal(TIR, 1),
+            roundDecimal(daysBG, 1)
         )
     }
 

+ 1 - 1
FreeAPS/Sources/APS/Storage/GlucoseStorage.swift

@@ -38,7 +38,7 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
             self.storage.transaction { storage in
                 storage.append(glucose, to: file, uniqBy: \.dateString)
                 let uniqEvents = storage.retrieve(file, as: [BloodGlucose].self)?
-                    .filter { $0.dateString.addingTimeInterval(1.days.timeInterval) > Date() }
+                    .filter { $0.dateString.addingTimeInterval(120.days.timeInterval) > Date() }
                     .sorted { $0.dateString > $1.dateString } ?? []
                 let glucose = Array(uniqEvents)
                 storage.save(glucose, as: file)

+ 16 - 12
FreeAPS/Sources/Models/DailyStats.swift

@@ -1,7 +1,7 @@
 import Foundation
 
 struct DailyStats: JSON, Equatable {
-    var date: Date
+    var createdAt: Date
     var FAX_Build_Version: String
     var FAX_Build_Number: String
     var FAX_Branch: String
@@ -15,13 +15,12 @@ struct DailyStats: JSON, Equatable {
     var TDD: Decimal
     var Carbs_24h: Decimal
     var TIR: String
-    var BG_daily_Average_mg_dl: Decimal
-    var BG_daily_Average_mmol_l: Decimal
+    var BG_Average: String
     var HbA1c: String
     var id: String
 
     init(
-        date: Date,
+        createdAt: Date,
         FAX_Build_Version: String,
         FAX_Build_Number: String,
         FAX_Branch: String,
@@ -35,12 +34,11 @@ struct DailyStats: JSON, Equatable {
         TDD: Decimal,
         Carbs_24h: Decimal,
         TIR: String,
-        BG_daily_Average_mg_dl: Decimal,
-        BG_daily_Average_mmol_l: Decimal,
+        BG_Average: String,
         HbA1c: String,
         id: String
     ) {
-        self.date = date
+        self.createdAt = createdAt
         self.FAX_Build_Version = FAX_Build_Version
         self.FAX_Build_Number = FAX_Build_Number
         self.FAX_Branch = FAX_Branch
@@ -54,16 +52,23 @@ struct DailyStats: JSON, Equatable {
         self.TDD = TDD
         self.Carbs_24h = Carbs_24h
         self.TIR = TIR
-        self.BG_daily_Average_mg_dl = BG_daily_Average_mg_dl
-        self.BG_daily_Average_mmol_l = BG_daily_Average_mmol_l
+        self.BG_Average = BG_Average
         self.HbA1c = HbA1c
         self.id = id
     }
+
+    static func == (lhs: DailyStats, rhs: DailyStats) -> Bool {
+        lhs.createdAt == rhs.createdAt
+    }
+
+    func hash(into hasher: inout Hasher) {
+        hasher.combine(createdAt)
+    }
 }
 
 extension DailyStats {
     private enum CodingKeys: String, CodingKey {
-        case date
+        case createdAt
         case FAX_Build_Version
         case FAX_Build_Number
         case FAX_Branch
@@ -77,8 +82,7 @@ extension DailyStats {
         case TDD
         case Carbs_24h
         case TIR
-        case BG_daily_Average_mg_dl
-        case BG_daily_Average_mmol_l
+        case BG_Average
         case HbA1c
         case id
     }