|
@@ -215,9 +215,11 @@ final class BaseAPSManager: APSManager, Injectable {
|
|
|
isLooping.send(false)
|
|
isLooping.send(false)
|
|
|
|
|
|
|
|
if let error = error {
|
|
if let error = error {
|
|
|
|
|
+ loopStats(error: error)
|
|
|
warning(.apsManager, "Loop failed with error: \(error.localizedDescription)")
|
|
warning(.apsManager, "Loop failed with error: \(error.localizedDescription)")
|
|
|
processError(error)
|
|
processError(error)
|
|
|
} else {
|
|
} else {
|
|
|
|
|
+ loopStats()
|
|
|
debug(.apsManager, "Loop succeeded")
|
|
debug(.apsManager, "Loop succeeded")
|
|
|
lastLoopDate = Date()
|
|
lastLoopDate = Date()
|
|
|
lastError.send(nil)
|
|
lastError.send(nil)
|
|
@@ -735,7 +737,7 @@ final class BaseAPSManager: APSManager, Injectable {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- var algo_ = "oref0" //Default
|
|
|
|
|
|
|
+ var algo_ = "oref0" // Default
|
|
|
if preferences.enableChris, preferences.useNewFormula {
|
|
if preferences.enableChris, preferences.useNewFormula {
|
|
|
algo_ = "Dynamic ISF, Logarithmic Formula"
|
|
algo_ = "Dynamic ISF, Logarithmic Formula"
|
|
|
} else if !preferences.useNewFormula, preferences.enableChris {
|
|
} else if !preferences.useNewFormula, preferences.enableChris {
|
|
@@ -743,22 +745,13 @@ final class BaseAPSManager: APSManager, Injectable {
|
|
|
}
|
|
}
|
|
|
let af = preferences.adjustmentFactor
|
|
let af = preferences.adjustmentFactor
|
|
|
let insulin_type = preferences.curve
|
|
let insulin_type = preferences.curve
|
|
|
- var buildDate: Date {
|
|
|
|
|
- if let infoPath = Bundle.main.path(forResource: "Info", ofType: "plist"),
|
|
|
|
|
- let infoAttr = try? FileManager.default.attributesOfItem(atPath: infoPath),
|
|
|
|
|
- let infoDate = infoAttr[.modificationDate] as? Date
|
|
|
|
|
- {
|
|
|
|
|
- return infoDate
|
|
|
|
|
- }
|
|
|
|
|
- return Date()
|
|
|
|
|
- }
|
|
|
|
|
- let nsObject: AnyObject? = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as AnyObject
|
|
|
|
|
- let version = nsObject as! String
|
|
|
|
|
- let build = Bundle.main.infoDictionary?["CFBundleVersion"] as? String
|
|
|
|
|
|
|
+ let buildDate = Bundle.main.buildDate
|
|
|
|
|
+ let version = Bundle.main.releaseVersionNumber
|
|
|
|
|
+ let build = Bundle.main.buildVersionNumber
|
|
|
let branch = Bundle.main.infoDictionary?["NSHumanReadableCopyright"] as? String
|
|
let branch = Bundle.main.infoDictionary?["NSHumanReadableCopyright"] as? String
|
|
|
let pump_ = pumpManager?.localizedTitle ?? ""
|
|
let pump_ = pumpManager?.localizedTitle ?? ""
|
|
|
let cgm = settingsManager.settings.cgm
|
|
let cgm = settingsManager.settings.cgm
|
|
|
- var file = OpenAPS.Monitor.dailyStats
|
|
|
|
|
|
|
+ let file = OpenAPS.Monitor.dailyStats
|
|
|
var iPa: Decimal = 75
|
|
var iPa: Decimal = 75
|
|
|
if preferences.useCustomPeakTime {
|
|
if preferences.useCustomPeakTime {
|
|
|
iPa = preferences.insulinPeakTime
|
|
iPa = preferences.insulinPeakTime
|
|
@@ -768,6 +761,54 @@ final class BaseAPSManager: APSManager, Injectable {
|
|
|
iPa = 50
|
|
iPa = 50
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // Retrieve the loopStats data
|
|
|
|
|
+ let lsData = storage.retrieve(OpenAPS.Monitor.loopStats, as: [LoopStats].self)?
|
|
|
|
|
+ .sorted { $0.createdAt > $1.createdAt } ?? []
|
|
|
|
|
+ var successRate: Double?
|
|
|
|
|
+ var roundedMinutesBetweenLoops: Double?
|
|
|
|
|
+
|
|
|
|
|
+ if !lsData.isEmpty {
|
|
|
|
|
+ var i = 0.0
|
|
|
|
|
+ var successNR = 0.0
|
|
|
|
|
+ var errorNR = 0.0
|
|
|
|
|
+ for each in lsData {
|
|
|
|
|
+ i += 1
|
|
|
|
|
+ if each.loopStatus.contains("Success") {
|
|
|
|
|
+ successNR += 1
|
|
|
|
|
+ } else {
|
|
|
|
|
+ errorNR += 1
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ successRate = (successNR / Double(i)) * 100
|
|
|
|
|
+
|
|
|
|
|
+ let loopDataTime = lsData[0].createdAt - lsData[Int(i) - 1].createdAt
|
|
|
|
|
+ let minutesBetweenLoops = (loopDataTime.timeInterval / Double(i)) / 60
|
|
|
|
|
+ roundedMinutesBetweenLoops = round(minutesBetweenLoops * 10) / 10
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Retrieve the 10 days data array
|
|
|
|
|
+ var uniqEvents_1 = storage.retrieve(OpenAPS.Monitor.tenDaysStats, as: [TenDaysStats].self)?
|
|
|
|
|
+ .filter { $0.createdAt.addingTimeInterval(365.days.timeInterval) > Date() }
|
|
|
|
|
+ .sorted { $0.createdAt > $1.createdAt } ?? []
|
|
|
|
|
+
|
|
|
|
|
+ var index = 0
|
|
|
|
|
+ var total: Decimal = 0
|
|
|
|
|
+ var thirtyDays: Decimal = 0
|
|
|
|
|
+ var ninetyDays: Decimal = 0
|
|
|
|
|
+
|
|
|
|
|
+ for uniqEvent in uniqEvents_1 {
|
|
|
|
|
+ if uniqEvent.past10daysAverage != 0 {
|
|
|
|
|
+ total += uniqEvent.past10daysAverage
|
|
|
|
|
+ index += 1
|
|
|
|
|
+ }
|
|
|
|
|
+ if index == 3 {
|
|
|
|
|
+ thirtyDays = total / 3
|
|
|
|
|
+ }
|
|
|
|
|
+ if index == 9 {
|
|
|
|
|
+ ninetyDays = total / 9
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// HbA1c estimation (%, mmol/mol)
|
|
// HbA1c estimation (%, mmol/mol)
|
|
|
let NGSPa1CStatisticValue = (46.7 + tir().averageGlucose_1) / 28.7 // NGSP (%)
|
|
let NGSPa1CStatisticValue = (46.7 + tir().averageGlucose_1) / 28.7 // NGSP (%)
|
|
|
let IFCCa1CStatisticValue = 10.929 *
|
|
let IFCCa1CStatisticValue = 10.929 *
|
|
@@ -775,30 +816,31 @@ final class BaseAPSManager: APSManager, Injectable {
|
|
|
// 7 days
|
|
// 7 days
|
|
|
let NGSPa1CStatisticValue_7 = (46.7 + tir().averageGlucose_7) / 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
|
|
|
|
|
- let NGSPa1CStatisticValue_30 = (46.7 + tir().averageGlucose_30) / 28.7
|
|
|
|
|
|
|
+ // 30 days
|
|
|
|
|
+ let NGSPa1CStatisticValue_30 = (46.7 + thirtyDays) / 28.7
|
|
|
let IFCCa1CStatisticValue_30 = 10.929 * (NGSPa1CStatisticValue_30 - 2.152)
|
|
let IFCCa1CStatisticValue_30 = 10.929 * (NGSPa1CStatisticValue_30 - 2.152)
|
|
|
- // All days
|
|
|
|
|
|
|
+ // Total days (up t0 10 days)
|
|
|
let NGSPa1CStatisticValue_total = (46.7 + tir().averageGlucose) / 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)
|
|
|
|
|
+ // 90 Days
|
|
|
|
|
+ let NGSPa1CStatisticValue_90 = (46.7 + ninetyDays) / 28.7
|
|
|
|
|
+ let IFCCa1CStatisticValue_90 = 10.929 * (NGSPa1CStatisticValue_90 - 2.152)
|
|
|
|
|
|
|
|
// HbA1c string and BG string:
|
|
// HbA1c string and BG string:
|
|
|
-
|
|
|
|
|
var HbA1c_string_1 = ""
|
|
var HbA1c_string_1 = ""
|
|
|
var string7Days = ""
|
|
var string7Days = ""
|
|
|
var string30Days = ""
|
|
var string30Days = ""
|
|
|
|
|
+ var string90Days = ""
|
|
|
var stringTotal = ""
|
|
var stringTotal = ""
|
|
|
-
|
|
|
|
|
var bgString1day = ""
|
|
var bgString1day = ""
|
|
|
var bgString7Days = ""
|
|
var bgString7Days = ""
|
|
|
var bgString30Days = ""
|
|
var bgString30Days = ""
|
|
|
|
|
+ var bgString90Days = ""
|
|
|
var bgAverageTotalString = ""
|
|
var bgAverageTotalString = ""
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
let daysBG = tir().daysWithBG
|
|
let daysBG = tir().daysWithBG
|
|
|
-
|
|
|
|
|
let avg1 = tir().averageGlucose_1
|
|
let avg1 = tir().averageGlucose_1
|
|
|
let avg7 = tir().averageGlucose_7
|
|
let avg7 = tir().averageGlucose_7
|
|
|
- let avg30 = tir().averageGlucose_30
|
|
|
|
|
let avgTot = tir().averageGlucose
|
|
let avgTot = tir().averageGlucose
|
|
|
|
|
|
|
|
if avg1 != 0 {
|
|
if avg1 != 0 {
|
|
@@ -812,12 +854,19 @@ final class BaseAPSManager: APSManager, Injectable {
|
|
|
" HbA1c 7 days (mmol/mol): \(roundDecimal(IFCCa1CStatisticValue_7, 1)). HbA1c 7 days (%): \(roundDecimal(NGSPa1CStatisticValue_7, 1))."
|
|
" 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)."
|
|
bgString7Days = " Average BG (mmol/l) 7 days: \(roundDecimal(avg7 * 0.0555, 1)). Average BG (mg/dl) 7 days: \(avg7)."
|
|
|
}
|
|
}
|
|
|
- if avg30 != 0 {
|
|
|
|
|
|
|
+ if thirtyDays != 0 {
|
|
|
string30Days =
|
|
string30Days =
|
|
|
" HbA1c 30 days (mmol/mol): \(roundDecimal(IFCCa1CStatisticValue_30, 1)). HbA1c 30 days (%): \(roundDecimal(NGSPa1CStatisticValue_30, 1))."
|
|
" HbA1c 30 days (mmol/mol): \(roundDecimal(IFCCa1CStatisticValue_30, 1)). HbA1c 30 days (%): \(roundDecimal(NGSPa1CStatisticValue_30, 1))."
|
|
|
bgString30Days =
|
|
bgString30Days =
|
|
|
- " Average BG 30 days (mmol/l): \(roundDecimal(avg30 * 0.0555, 1)). Average BG 30 days (mg/dl): \(avg30). "
|
|
|
|
|
|
|
+ " Average BG 30 days (mmol/l): \(roundDecimal(thirtyDays * 0.0555, 1)). Average BG 30 days (mg/dl): \(roundDecimal(thirtyDays, 0)). "
|
|
|
|
|
+ }
|
|
|
|
|
+ if ninetyDays != 0 {
|
|
|
|
|
+ string90Days =
|
|
|
|
|
+ " HbA1c 90 days (mmol/mol): \(roundDecimal(IFCCa1CStatisticValue_90, 1)). HbA1c 90 days (%): \(roundDecimal(NGSPa1CStatisticValue_90, 1))."
|
|
|
|
|
+ bgString90Days =
|
|
|
|
|
+ " Average BG 90 days (mmol/l): \(roundDecimal(ninetyDays * 0.0555, 1)). Average BG 90 days (mg/dl): \(roundDecimal(ninetyDays, 0)). "
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
if avgTot != 0, daysBG >= 2 {
|
|
if avgTot != 0, daysBG >= 2 {
|
|
|
stringTotal =
|
|
stringTotal =
|
|
|
" HbA1c Total (\(daysBG)) Days (mmol/mol): \(roundDecimal(IFCCa1CStatisticValue_total, 1)). HbA1c Total (\(daysBG)) Days (mg/dl): \(roundDecimal(NGSPa1CStatisticValue_total, 1)) %."
|
|
" HbA1c Total (\(daysBG)) Days (mmol/mol): \(roundDecimal(IFCCa1CStatisticValue_total, 1)). HbA1c Total (\(daysBG)) Days (mg/dl): \(roundDecimal(NGSPa1CStatisticValue_total, 1)) %."
|
|
@@ -825,7 +874,7 @@ final class BaseAPSManager: APSManager, Injectable {
|
|
|
"BG Average Total (\(daysBG)) Days (mmol/l): \(roundDecimal(avgTot * 0.0555, 1)). BG Average Total (\(daysBG)) Days (mmg/dl): \(avgTot)."
|
|
"BG Average Total (\(daysBG)) Days (mmol/l): \(roundDecimal(avgTot * 0.0555, 1)). BG Average Total (\(daysBG)) Days (mmg/dl): \(avgTot)."
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- let HbA1c_string = HbA1c_string_1 + string7Days + string30Days + stringTotal
|
|
|
|
|
|
|
+ let HbA1c_string = HbA1c_string_1 + string7Days + string30Days + string90Days + stringTotal
|
|
|
|
|
|
|
|
var tirString =
|
|
var tirString =
|
|
|
"TIR (24 hours): \(tir().TIR_1) %. Time with Hypoglucemia: \(tir().hypos_1) % (< 4 / 72). Time with Hyperglucemia: \(tir().hypers_1) % (> 10 / 180)."
|
|
"TIR (24 hours): \(tir().TIR_1) %. Time with Hypoglucemia: \(tir().hypos_1) % (< 4 / 72). Time with Hyperglucemia: \(tir().hypers_1) % (> 10 / 180)."
|
|
@@ -835,11 +884,11 @@ final class BaseAPSManager: APSManager, Injectable {
|
|
|
" Total days (\(daysBG)) TIR: \(tir().TIR) %. Time with Hypoglucemia: \(tir().hypos) % (< 4 / 72). Time with Hyperglucemia: \(tir().hypers) % (> 10 / 180)."
|
|
" Total days (\(daysBG)) TIR: \(tir().TIR) %. Time with Hypoglucemia: \(tir().hypos) % (< 4 / 72). Time with Hyperglucemia: \(tir().hypers) % (> 10 / 180)."
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- let bgAverageString = bgString1day + bgString7Days + bgString30Days + bgAverageTotalString
|
|
|
|
|
|
|
+ let bgAverageString = bgString1day + bgString7Days + bgString30Days + bgString90Days + bgAverageTotalString
|
|
|
|
|
|
|
|
let dailystat = DailyStats(
|
|
let dailystat = DailyStats(
|
|
|
createdAt: 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",
|
|
|
FAX_Build_Date: buildDate,
|
|
FAX_Build_Date: buildDate,
|
|
@@ -853,11 +902,51 @@ final class BaseAPSManager: APSManager, Injectable {
|
|
|
Carbs_24h: carbTotal,
|
|
Carbs_24h: carbTotal,
|
|
|
TIR: tirString,
|
|
TIR: tirString,
|
|
|
BG_Average: bgAverageString,
|
|
BG_Average: bgAverageString,
|
|
|
- HbA1c: HbA1c_string
|
|
|
|
|
|
|
+ HbA1c: HbA1c_string,
|
|
|
|
|
+ Loop_Cycles: "Success Rate : \(round(successRate ?? 0)) %. Average Time Between Loop Cycles: \(roundedMinutesBetweenLoops ?? 0) min."
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- file = OpenAPS.Monitor.dailyStats
|
|
|
|
|
- storage.save(dailystat, as: file)
|
|
|
|
|
|
|
+ let savedDailyStas = storage.retrieve(OpenAPS.Monitor.dailyStats, as: [DailyStats].self)?
|
|
|
|
|
+ .sorted { $0.createdAt > $1.createdAt } ?? []
|
|
|
|
|
+ let lastDailyStatsEntry = savedDailyStas.count - 1
|
|
|
|
|
+
|
|
|
|
|
+ var uniqeEvents: [DailyStats] = []
|
|
|
|
|
+
|
|
|
|
|
+ if lastDailyStatsEntry <= 0 {
|
|
|
|
|
+ storage.save(dailystat, as: file)
|
|
|
|
|
+ } else if Date() > savedDailyStas[0].createdAt.addingTimeInterval(1.days.timeInterval) {
|
|
|
|
|
+ storage.transaction { storage in
|
|
|
|
|
+ storage.append(dailystat, to: file, uniqBy: \.createdAt)
|
|
|
|
|
+ uniqeEvents = storage.retrieve(file, as: [DailyStats].self)?
|
|
|
|
|
+ .filter { $0.createdAt.addingTimeInterval(365.days.timeInterval) > Date() }
|
|
|
|
|
+ .sorted { $0.createdAt > $1.createdAt } ?? []
|
|
|
|
|
+ storage.save(Array(uniqeEvents), as: file)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ func loopStats(error: Error? = nil) {
|
|
|
|
|
+ let file = OpenAPS.Monitor.loopStats
|
|
|
|
|
+ var errString = "Success"
|
|
|
|
|
+
|
|
|
|
|
+ if let error = error {
|
|
|
|
|
+ errString = error.localizedDescription
|
|
|
|
|
+ }
|
|
|
|
|
+ let loopstat = LoopStats(
|
|
|
|
|
+ createdAt: Date(),
|
|
|
|
|
+ loopStatus: errString
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ var uniqEvents: [LoopStats] = []
|
|
|
|
|
+
|
|
|
|
|
+ storage.transaction { storage in
|
|
|
|
|
+ storage.append(loopstat, to: file, uniqBy: \.createdAt)
|
|
|
|
|
+ uniqEvents = storage.retrieve(file, as: [LoopStats].self)?
|
|
|
|
|
+ .filter { $0.createdAt.addingTimeInterval(24.hours.timeInterval) > Date() }
|
|
|
|
|
+ .sorted { $0.createdAt > $1.createdAt } ?? []
|
|
|
|
|
+
|
|
|
|
|
+ storage.save(Array(uniqEvents), as: file)
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Time In Range (%) and Average Glucose (24 hours). This function looks dumb. I will refactor it later.
|
|
// Time In Range (%) and Average Glucose (24 hours). This function looks dumb. I will refactor it later.
|
|
@@ -866,7 +955,7 @@ final class BaseAPSManager: APSManager, Injectable {
|
|
|
averageGlucose: Decimal,
|
|
averageGlucose: Decimal,
|
|
|
averageGlucose_1: Decimal,
|
|
averageGlucose_1: Decimal,
|
|
|
averageGlucose_7: Decimal,
|
|
averageGlucose_7: Decimal,
|
|
|
- averageGlucose_30: Decimal,
|
|
|
|
|
|
|
+ averageGlucose_10: Decimal,
|
|
|
hypos: Decimal,
|
|
hypos: Decimal,
|
|
|
hypers: Decimal,
|
|
hypers: Decimal,
|
|
|
TIR: Decimal,
|
|
TIR: Decimal,
|
|
@@ -891,10 +980,11 @@ final class BaseAPSManager: APSManager, Injectable {
|
|
|
let startDate = glucose![0].date
|
|
let startDate = glucose![0].date
|
|
|
var end1 = false
|
|
var end1 = false
|
|
|
var end7 = false
|
|
var end7 = false
|
|
|
- var end30 = false
|
|
|
|
|
|
|
+ var end10 = false
|
|
|
var bg_1: Decimal = 0
|
|
var bg_1: Decimal = 0
|
|
|
var bg_7: Decimal = 0
|
|
var bg_7: Decimal = 0
|
|
|
- var bg_30: Decimal = 0
|
|
|
|
|
|
|
+ var bg_10: Decimal = 0
|
|
|
|
|
+ var bg_total: Decimal = 0
|
|
|
var j = -1
|
|
var j = -1
|
|
|
|
|
|
|
|
for entry in glucose! {
|
|
for entry in glucose! {
|
|
@@ -913,14 +1003,16 @@ final class BaseAPSManager: APSManager, Injectable {
|
|
|
end7 = true
|
|
end7 = true
|
|
|
bg_7 = bg / nr_bgs
|
|
bg_7 = bg / nr_bgs
|
|
|
}
|
|
}
|
|
|
- if startDate - entry.date > 2.59E9, !end30 {
|
|
|
|
|
- end30 = true
|
|
|
|
|
- bg_30 = bg / nr_bgs
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if startDate - entry.date >= 8.64E8, !end10 {
|
|
|
|
|
+ end10 = true
|
|
|
|
|
+ bg_10 = bg / nr_bgs
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- let bg_90 = bg / nr_bgs
|
|
|
|
|
|
|
+ bg_total = bg / nr_bgs
|
|
|
|
|
+
|
|
|
let fullTime = glucose![0].date - glucose![endIndex].date
|
|
let fullTime = glucose![0].date - glucose![endIndex].date
|
|
|
var fullTime_1 = glucose![0].date - glucose![oneDayGlucoseIndex].date
|
|
var fullTime_1 = glucose![0].date - glucose![oneDayGlucoseIndex].date
|
|
|
|
|
|
|
@@ -1004,11 +1096,36 @@ final class BaseAPSManager: APSManager, Injectable {
|
|
|
|
|
|
|
|
let TIR_1 = 100 - (hypos_1 + hypers_1)
|
|
let TIR_1 = 100 - (hypos_1 + hypers_1)
|
|
|
|
|
|
|
|
|
|
+ // Add 10 day average to weeklyStats.json
|
|
|
|
|
+ let file_10 = OpenAPS.Monitor.tenDaysStats
|
|
|
|
|
+ let tensDaysStats = storage.retrieve(file_10, as: [TenDaysStats].self)
|
|
|
|
|
+
|
|
|
|
|
+ let lastTenDaysStatEntry = tensDaysStats?[0].past10daysAverage ?? 0
|
|
|
|
|
+
|
|
|
|
|
+ print("Count entries on TenDaysData: \(lastTenDaysStatEntry)")
|
|
|
|
|
+
|
|
|
|
|
+ let tenStats = TenDaysStats(
|
|
|
|
|
+ createdAt: Date(), past10daysAverage: roundDecimal(bg_10, 1)
|
|
|
|
|
+ )
|
|
|
|
|
+ var uniqEvents: [TenDaysStats] = []
|
|
|
|
|
+
|
|
|
|
|
+ if lastTenDaysStatEntry == 0, daysBG >= 10 {
|
|
|
|
|
+ storage.save(tenStats, as: file_10)
|
|
|
|
|
+ } else if daysBG >= 10, Date() > tensDaysStats?[0].createdAt.addingTimeInterval(10.days.timeInterval) ?? Date() {
|
|
|
|
|
+ storage.transaction { storage in
|
|
|
|
|
+ storage.append(tenStats, to: file_10, uniqBy: \.createdAt)
|
|
|
|
|
+ uniqEvents = storage.retrieve(file_10, as: [TenDaysStats].self)?
|
|
|
|
|
+ .filter { $0.createdAt.addingTimeInterval(365.days.timeInterval) > Date() }
|
|
|
|
|
+ .sorted { $0.createdAt > $1.createdAt } ?? []
|
|
|
|
|
+ storage.save(Array(uniqEvents), as: file_10)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
return (
|
|
return (
|
|
|
- roundDecimal(bg_90, 0),
|
|
|
|
|
|
|
+ roundDecimal(bg_total, 0),
|
|
|
roundDecimal(bg_1, 0),
|
|
roundDecimal(bg_1, 0),
|
|
|
roundDecimal(bg_7, 0),
|
|
roundDecimal(bg_7, 0),
|
|
|
- roundDecimal(bg_30, 0),
|
|
|
|
|
|
|
+ roundDecimal(bg_10, 0),
|
|
|
roundDecimal(hypos, 1),
|
|
roundDecimal(hypos, 1),
|
|
|
roundDecimal(hypers, 1),
|
|
roundDecimal(hypers, 1),
|
|
|
roundDecimal(TIR, 1),
|
|
roundDecimal(TIR, 1),
|