Kaynağa Gözat

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 yıl önce
ebeveyn
işleme
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 carbs = storage.retrieve(OpenAPS.Monitor.carbHistory, as: [CarbsEntry].self)
         let tdds = storage.retrieve(OpenAPS.Monitor.tdd, as: [TDD].self)
         let tdds = storage.retrieve(OpenAPS.Monitor.tdd, as: [TDD].self)
         let currentTDD = tdds?[0].TDD
         let currentTDD = tdds?[0].TDD
-
         let carbs_length = carbs?.count ?? 0
         let carbs_length = carbs?.count ?? 0
         var carbTotal: Decimal = 0
         var carbTotal: Decimal = 0
 
 
@@ -769,83 +768,72 @@ final class BaseAPSManager: APSManager, Injectable {
             iPa = 50
             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)
         // 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 *
         let IFCCa1CStatisticValue = 10.929 *
             (NGSPa1CStatisticValue - 2.152) // IFCC (mmol/mol)  A1C(mmol/mol) = 10.929 * (A1C(%) - 2.15)
             (NGSPa1CStatisticValue - 2.152) // IFCC (mmol/mol)  A1C(mmol/mol) = 10.929 * (A1C(%) - 2.15)
         // 7 days
         // 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)
         let IFCCa1CStatisticValue_7 = 10.929 * (NGSPa1CStatisticValue_7 - 2.152)
         // 14 days
         // 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)
         let IFCCa1CStatisticValue_30 = 10.929 * (NGSPa1CStatisticValue_30 - 2.152)
         // All days
         // 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)
         let IFCCa1CStatisticValue_total = 10.929 * (NGSPa1CStatisticValue_total - 2.152)
 
 
-        // HbA1c string:
+        // HbA1c string and BG string:
+
+        var HbA1c_string_1 = ""
         var string7Days = ""
         var string7Days = ""
         var string30Days = ""
         var string30Days = ""
         var stringTotal = ""
         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 =
             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 =
             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 =
             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 =
         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)."
             "\(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(
         let dailystat = DailyStats(
-            date: Date(),
+            createdAt: Date(),
             FAX_Build_Version: version,
             FAX_Build_Version: version,
             FAX_Build_Number: build ?? "1",
             FAX_Build_Number: build ?? "1",
             FAX_Branch: branch ?? "N/A",
             FAX_Branch: branch ?? "N/A",
@@ -859,62 +847,27 @@ final class BaseAPSManager: APSManager, Injectable {
             TDD: currentTDD ?? 0,
             TDD: currentTDD ?? 0,
             Carbs_24h: carbTotal,
             Carbs_24h: carbTotal,
             TIR: tirString,
             TIR: tirString,
-            BG_daily_Average_mg_dl: averageBG,
-            BG_daily_Average_mmol_l: roundDecimal(averageBG * 0.0555, 2),
+            BG_Average: bgAverageString,
             HbA1c: HbA1c_string,
             HbA1c: HbA1c_string,
             id: UUID().uuidString
             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
         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)
     // Time In Range (%) and Average Glucose (24 hours)
     func tir()
     func tir()
         -> (
         -> (
             averageGlucose: Decimal,
             averageGlucose: Decimal,
+            averageGlucose_1: Decimal,
+            averageGlucose_7: Decimal,
+            averageGlucose_30: Decimal,
             hypos: Decimal,
             hypos: Decimal,
             hypers: Decimal,
             hypers: Decimal,
-            TIR: Decimal
+            TIR: Decimal,
+            daysWithBG: Decimal
         )
         )
     {
     {
         let glucose = storage.retrieve(OpenAPS.Monitor.glucose, as: [BloodGlucose].self)
         let glucose = storage.retrieve(OpenAPS.Monitor.glucose, as: [BloodGlucose].self)
@@ -923,22 +876,45 @@ final class BaseAPSManager: APSManager, Injectable {
         let endIndex = length_ - 1
         let endIndex = length_ - 1
 
 
         guard length_ != 0 else {
         guard length_ != 0 else {
-            return (0, 0, 0, 0)
+            return (0, 0, 0, 0, 0, 0, 0, 0)
         }
         }
 
 
         var bg: Decimal = 0
         var bg: Decimal = 0
         var nr_bgs: 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! {
         for entry in glucose! {
             if entry.glucose! > 0 {
             if entry.glucose! > 0 {
                 bg += Decimal(entry.glucose!)
                 bg += Decimal(entry.glucose!)
                 nr_bgs += 1
                 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 fullTime = glucose![0].date - glucose![endIndex].date
+
+        let daysBG = fullTime / 8.64E7
+
         var timeInHypo: Decimal = 0
         var timeInHypo: Decimal = 0
         var timeInHyper: Decimal = 0
         var timeInHyper: Decimal = 0
         var hypos: Decimal = 0
         var hypos: Decimal = 0
@@ -979,10 +955,14 @@ final class BaseAPSManager: APSManager, Injectable {
         let TIR = 100 - (hypos + hypers)
         let TIR = 100 - (hypos + hypers)
 
 
         return (
         return (
-            roundDecimal(averageGlucose_, 0),
+            roundDecimal(bg_120, 0),
+            roundDecimal(bg_1, 0),
+            roundDecimal(bg_7, 0),
+            roundDecimal(bg_30, 0),
             roundDecimal(hypos, 1),
             roundDecimal(hypos, 1),
             roundDecimal(hypers, 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
             self.storage.transaction { storage in
                 storage.append(glucose, to: file, uniqBy: \.dateString)
                 storage.append(glucose, to: file, uniqBy: \.dateString)
                 let uniqEvents = storage.retrieve(file, as: [BloodGlucose].self)?
                 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 } ?? []
                     .sorted { $0.dateString > $1.dateString } ?? []
                 let glucose = Array(uniqEvents)
                 let glucose = Array(uniqEvents)
                 storage.save(glucose, as: file)
                 storage.save(glucose, as: file)

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

@@ -1,7 +1,7 @@
 import Foundation
 import Foundation
 
 
 struct DailyStats: JSON, Equatable {
 struct DailyStats: JSON, Equatable {
-    var date: Date
+    var createdAt: Date
     var FAX_Build_Version: String
     var FAX_Build_Version: String
     var FAX_Build_Number: String
     var FAX_Build_Number: String
     var FAX_Branch: String
     var FAX_Branch: String
@@ -15,13 +15,12 @@ struct DailyStats: JSON, Equatable {
     var TDD: Decimal
     var TDD: Decimal
     var Carbs_24h: Decimal
     var Carbs_24h: Decimal
     var TIR: String
     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 HbA1c: String
     var id: String
     var id: String
 
 
     init(
     init(
-        date: Date,
+        createdAt: Date,
         FAX_Build_Version: String,
         FAX_Build_Version: String,
         FAX_Build_Number: String,
         FAX_Build_Number: String,
         FAX_Branch: String,
         FAX_Branch: String,
@@ -35,12 +34,11 @@ struct DailyStats: JSON, Equatable {
         TDD: Decimal,
         TDD: Decimal,
         Carbs_24h: Decimal,
         Carbs_24h: Decimal,
         TIR: String,
         TIR: String,
-        BG_daily_Average_mg_dl: Decimal,
-        BG_daily_Average_mmol_l: Decimal,
+        BG_Average: String,
         HbA1c: String,
         HbA1c: String,
         id: String
         id: String
     ) {
     ) {
-        self.date = date
+        self.createdAt = createdAt
         self.FAX_Build_Version = FAX_Build_Version
         self.FAX_Build_Version = FAX_Build_Version
         self.FAX_Build_Number = FAX_Build_Number
         self.FAX_Build_Number = FAX_Build_Number
         self.FAX_Branch = FAX_Branch
         self.FAX_Branch = FAX_Branch
@@ -54,16 +52,23 @@ struct DailyStats: JSON, Equatable {
         self.TDD = TDD
         self.TDD = TDD
         self.Carbs_24h = Carbs_24h
         self.Carbs_24h = Carbs_24h
         self.TIR = TIR
         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.HbA1c = HbA1c
         self.id = id
         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 {
 extension DailyStats {
     private enum CodingKeys: String, CodingKey {
     private enum CodingKeys: String, CodingKey {
-        case date
+        case createdAt
         case FAX_Build_Version
         case FAX_Build_Version
         case FAX_Build_Number
         case FAX_Build_Number
         case FAX_Branch
         case FAX_Branch
@@ -77,8 +82,7 @@ extension DailyStats {
         case TDD
         case TDD
         case Carbs_24h
         case Carbs_24h
         case TIR
         case TIR
-        case BG_daily_Average_mg_dl
-        case BG_daily_Average_mmol_l
+        case BG_Average
         case HbA1c
         case HbA1c
         case id
         case id
     }
     }