From a060d5e34ead44356d930b8d71a90782047aec3b Mon Sep 17 00:00:00 2001 From: Mike Plante Date: Sat, 4 May 2024 23:01:15 -0400 Subject: [PATCH] Scrub Stats Upload Removes the upload of statistics to Nightscout --- .../defaults/freeaps/freeaps_settings.json | 1 - FreeAPS/Sources/APS/APSManager.swift | 322 ------------------ FreeAPS/Sources/Models/FreeAPSSettings.swift | 5 - .../Sources/Modules/Home/HomeStateModel.swift | 3 - .../NightscoutConfigStateModel.swift | 2 - .../View/NightscoutConfigRootView.swift | 1 - .../Services/Network/NightscoutAPI.swift | 24 -- .../Services/Network/NightscoutManager.swift | 24 -- .../Services/Network/TidepoolManager.swift | 1 - 9 files changed, 383 deletions(-) diff --git a/FreeAPS/Resources/json/defaults/freeaps/freeaps_settings.json b/FreeAPS/Resources/json/defaults/freeaps/freeaps_settings.json index 575db3fcd..87e3205dc 100644 --- a/FreeAPS/Resources/json/defaults/freeaps/freeaps_settings.json +++ b/FreeAPS/Resources/json/defaults/freeaps/freeaps_settings.json @@ -34,7 +34,6 @@ "overrideHbA1cUnit" : false, "high" : 145, "low" : 70, - "uploadStats" : true, "hours" : 6, "xGridLines" : true, "yGridLines" : true, diff --git a/FreeAPS/Sources/APS/APSManager.swift b/FreeAPS/Sources/APS/APSManager.swift index 3747b3751..ac64f24ba 100644 --- a/FreeAPS/Sources/APS/APSManager.swift +++ b/FreeAPS/Sources/APS/APSManager.swift @@ -721,7 +721,6 @@ final class BaseAPSManager: APSManager, Injectable { } } nightscout.uploadStatus() - statistics() } } @@ -879,327 +878,6 @@ final class BaseAPSManager: APSManager, Injectable { return output } - // Add to statistics.JSON for upload to NS. - private func statistics() { - let now = Date() - if settingsManager.settings.uploadStats { - let hour = Calendar.current.component(.hour, from: now) - guard hour > 20 else { - return - } - coredataContext.performAndWait { [self] in - var stats = [StatsData]() - let requestStats = StatsData.fetchRequest() as NSFetchRequest - let sortStats = NSSortDescriptor(key: "lastrun", ascending: false) - requestStats.sortDescriptors = [sortStats] - requestStats.fetchLimit = 1 - try? stats = coredataContext.fetch(requestStats) - // Only save and upload once per day - guard (-1 * (stats.first?.lastrun ?? .distantPast).timeIntervalSinceNow.hours) > 22 else { return } - - let units = self.settingsManager.settings.units - let preferences = settingsManager.preferences - - // Carbs - var carbs = [Carbohydrates]() - var carbTotal: Decimal = 0 - let requestCarbs = Carbohydrates.fetchRequest() as NSFetchRequest - let daysAgo = Date().addingTimeInterval(-1.days.timeInterval) - requestCarbs.predicate = NSPredicate(format: "carbs > 0 AND date > %@", daysAgo as NSDate) - let sortCarbs = NSSortDescriptor(key: "date", ascending: true) - requestCarbs.sortDescriptors = [sortCarbs] - try? carbs = coredataContext.fetch(requestCarbs) - carbTotal = carbs.map({ carbs in carbs.carbs as? Decimal ?? 0 }).reduce(0, +) - - // TDD - var tdds = [TDD]() - var currentTDD: Decimal = 0 - var tddTotalAverage: Decimal = 0 - let requestTDD = TDD.fetchRequest() as NSFetchRequest - let sort = NSSortDescriptor(key: "timestamp", ascending: false) - let daysOf14Ago = Date().addingTimeInterval(-14.days.timeInterval) - requestTDD.predicate = NSPredicate(format: "timestamp > %@", daysOf14Ago as NSDate) - requestTDD.sortDescriptors = [sort] - try? tdds = coredataContext.fetch(requestTDD) - - if !tdds.isEmpty { - currentTDD = tdds[0].tdd?.decimalValue ?? 0 - let tddArray = tdds.compactMap({ insulin in insulin.tdd as? Decimal ?? 0 }) - tddTotalAverage = tddArray.reduce(0, +) / Decimal(tddArray.count) - } - - var algo_ = "Oref0" - - if preferences.sigmoid, preferences.enableDynamicCR { - algo_ = "Dynamic ISF + CR: Sigmoid" - } else if preferences.sigmoid, !preferences.enableDynamicCR { - algo_ = "Dynamic ISF: Sigmoid" - } else if preferences.useNewFormula, preferences.enableDynamicCR { - algo_ = "Dynamic ISF + CR: Logarithmic" - } else if preferences.useNewFormula, !preferences.sigmoid,!preferences.enableDynamicCR { - algo_ = "Dynamic ISF: Logarithmic" - } - let af = preferences.adjustmentFactor - let insulin_type = preferences.curve - let buildDate = Bundle.main.buildDate - let version = Bundle.main.releaseVersionNumber - let build = Bundle.main.buildVersionNumber - - // Read branch information from branch.txt instead of infoDictionary - var branch = "Unknown" - if let branchFileURL = Bundle.main.url(forResource: "branch", withExtension: "txt"), - let branchFileContent = try? String(contentsOf: branchFileURL) - { - let lines = branchFileContent.components(separatedBy: .newlines) - for line in lines { - let components = line.components(separatedBy: "=") - if components.count == 2 { - let key = components[0].trimmingCharacters(in: .whitespaces) - let value = components[1].trimmingCharacters(in: .whitespaces) - - if key == "BRANCH" { - branch = value - break - } - } - } - } else { - branch = "Unknown" - } - - let copyrightNotice_ = Bundle.main.infoDictionary?["NSHumanReadableCopyright"] as? String ?? "" - let pump_ = pumpManager?.localizedTitle ?? "" - let cgm = settingsManager.settings.cgm - let file = OpenAPS.Monitor.statistics - var iPa: Decimal = 75 - if preferences.useCustomPeakTime { - iPa = preferences.insulinPeakTime - } else if preferences.curve.rawValue == "rapid-acting" { - iPa = 65 - } else if preferences.curve.rawValue == "ultra-rapid" { - iPa = 50 - } - // CGM Readings - var glucose_24 = [Readings]() // Day - var glucose_7 = [Readings]() // Week - var glucose_30 = [Readings]() // Month - var glucose = [Readings]() // Total - let filter = DateFilter() - // 24h - let requestGFS_24 = Readings.fetchRequest() as NSFetchRequest - let sortGlucose_24 = NSSortDescriptor(key: "date", ascending: false) - requestGFS_24.predicate = NSPredicate(format: "glucose > 0 AND date > %@", filter.day) - requestGFS_24.sortDescriptors = [sortGlucose_24] - try? glucose_24 = coredataContext.fetch(requestGFS_24) - // Week - let requestGFS_7 = Readings.fetchRequest() as NSFetchRequest - let sortGlucose_7 = NSSortDescriptor(key: "date", ascending: false) - requestGFS_7.predicate = NSPredicate(format: "glucose > 0 AND date > %@", filter.week) - requestGFS_7.sortDescriptors = [sortGlucose_7] - try? glucose_7 = coredataContext.fetch(requestGFS_7) - // Month - let requestGFS_30 = Readings.fetchRequest() as NSFetchRequest - let sortGlucose_30 = NSSortDescriptor(key: "date", ascending: false) - requestGFS_30.predicate = NSPredicate(format: "glucose > 0 AND date > %@", filter.month) - requestGFS_30.sortDescriptors = [sortGlucose_30] - try? glucose_30 = coredataContext.fetch(requestGFS_30) - // Total - let requestGFS = Readings.fetchRequest() as NSFetchRequest - let sortGlucose = NSSortDescriptor(key: "date", ascending: false) - requestGFS.predicate = NSPredicate(format: "glucose > 0 AND date > %@", filter.total) - requestGFS.sortDescriptors = [sortGlucose] - try? glucose = coredataContext.fetch(requestGFS) - - // First date - let previous = glucose.last?.date ?? Date() - // Last date (recent) - let current = glucose.first?.date ?? Date() - // Total time in days - let numberOfDays = (current - previous).timeInterval / 8.64E4 - - // Get glucose computations for every case - let oneDayGlucose = glucoseStats(glucose_24) - let sevenDaysGlucose = glucoseStats(glucose_7) - let thirtyDaysGlucose = glucoseStats(glucose_30) - let totalDaysGlucose = glucoseStats(glucose) - - let median = Durations( - day: roundDecimal(Decimal(oneDayGlucose.median), 1), - week: roundDecimal(Decimal(sevenDaysGlucose.median), 1), - month: roundDecimal(Decimal(thirtyDaysGlucose.median), 1), - total: roundDecimal(Decimal(totalDaysGlucose.median), 1) - ) - - let overrideHbA1cUnit = settingsManager.settings.overrideHbA1cUnit - - let hbs = Durations( - day: ((units == .mmolL && !overrideHbA1cUnit) || (units == .mgdL && overrideHbA1cUnit)) ? - roundDecimal(Decimal(oneDayGlucose.ifcc), 1) : roundDecimal(Decimal(oneDayGlucose.ngsp), 1), - week: ((units == .mmolL && !overrideHbA1cUnit) || (units == .mgdL && overrideHbA1cUnit)) ? - roundDecimal(Decimal(sevenDaysGlucose.ifcc), 1) : roundDecimal(Decimal(sevenDaysGlucose.ngsp), 1), - month: ((units == .mmolL && !overrideHbA1cUnit) || (units == .mgdL && overrideHbA1cUnit)) ? - roundDecimal(Decimal(thirtyDaysGlucose.ifcc), 1) : roundDecimal(Decimal(thirtyDaysGlucose.ngsp), 1), - total: ((units == .mmolL && !overrideHbA1cUnit) || (units == .mgdL && overrideHbA1cUnit)) ? - roundDecimal(Decimal(totalDaysGlucose.ifcc), 1) : roundDecimal(Decimal(totalDaysGlucose.ngsp), 1) - ) - - var oneDay_: (TIR: Double, hypos: Double, hypers: Double, normal_: Double) = (0.0, 0.0, 0.0, 0.0) - var sevenDays_: (TIR: Double, hypos: Double, hypers: Double, normal_: Double) = (0.0, 0.0, 0.0, 0.0) - var thirtyDays_: (TIR: Double, hypos: Double, hypers: Double, normal_: Double) = (0.0, 0.0, 0.0, 0.0) - var totalDays_: (TIR: Double, hypos: Double, hypers: Double, normal_: Double) = (0.0, 0.0, 0.0, 0.0) - // Get TIR computations for every case - oneDay_ = tir(glucose_24) - sevenDays_ = tir(glucose_7) - thirtyDays_ = tir(glucose_30) - totalDays_ = tir(glucose) - - let tir = Durations( - day: roundDecimal(Decimal(oneDay_.TIR), 1), - week: roundDecimal(Decimal(sevenDays_.TIR), 1), - month: roundDecimal(Decimal(thirtyDays_.TIR), 1), - total: roundDecimal(Decimal(totalDays_.TIR), 1) - ) - let hypo = Durations( - day: Decimal(oneDay_.hypos), - week: Decimal(sevenDays_.hypos), - month: Decimal(thirtyDays_.hypos), - total: Decimal(totalDays_.hypos) - ) - let hyper = Durations( - day: Decimal(oneDay_.hypers), - week: Decimal(sevenDays_.hypers), - month: Decimal(thirtyDays_.hypers), - total: Decimal(totalDays_.hypers) - ) - let normal = Durations( - day: Decimal(oneDay_.normal_), - week: Decimal(sevenDays_.normal_), - month: Decimal(thirtyDays_.normal_), - total: Decimal(totalDays_.normal_) - ) - let range = Threshold( - low: units == .mmolL ? roundDecimal(settingsManager.settings.low.asMmolL, 1) : - roundDecimal(settingsManager.settings.low, 0), - high: units == .mmolL ? roundDecimal(settingsManager.settings.high.asMmolL, 1) : - roundDecimal(settingsManager.settings.high, 0) - ) - let TimeInRange = TIRs( - TIR: tir, - Hypos: hypo, - Hypers: hyper, - Threshold: range, - Euglycemic: normal - ) - let avgs = Durations( - day: roundDecimal(Decimal(oneDayGlucose.average), 1), - week: roundDecimal(Decimal(sevenDaysGlucose.average), 1), - month: roundDecimal(Decimal(thirtyDaysGlucose.average), 1), - total: roundDecimal(Decimal(totalDaysGlucose.average), 1) - ) - let avg = Averages(Average: avgs, Median: median) - // Standard Deviations - let standardDeviations = Durations( - day: roundDecimal(Decimal(oneDayGlucose.sd), 1), - week: roundDecimal(Decimal(sevenDaysGlucose.sd), 1), - month: roundDecimal(Decimal(thirtyDaysGlucose.sd), 1), - total: roundDecimal(Decimal(totalDaysGlucose.sd), 1) - ) - // CV = standard deviation / sample mean x 100 - let cvs = Durations( - day: roundDecimal(Decimal(oneDayGlucose.cv), 1), - week: roundDecimal(Decimal(sevenDaysGlucose.cv), 1), - month: roundDecimal(Decimal(thirtyDaysGlucose.cv), 1), - total: roundDecimal(Decimal(totalDaysGlucose.cv), 1) - ) - let variance = Variance(SD: standardDeviations, CV: cvs) - - // Loops - var lsr = [LoopStatRecord]() - let requestLSR = LoopStatRecord.fetchRequest() as NSFetchRequest - requestLSR.predicate = NSPredicate( - format: "interval > 0 AND start > %@", - Date().addingTimeInterval(-24.hours.timeInterval) as NSDate - ) - let sortLSR = NSSortDescriptor(key: "start", ascending: false) - requestLSR.sortDescriptors = [sortLSR] - try? lsr = coredataContext.fetch(requestLSR) - // Compute LoopStats for 24 hours - let oneDayLoops = loops(lsr) - let loopstat = LoopCycles( - loops: oneDayLoops.loops, - errors: oneDayLoops.errors, - readings: Int(oneDayGlucose.readings), - success_rate: oneDayLoops.success_rate, - avg_interval: oneDayLoops.avg_interval, - median_interval: oneDayLoops.median_interval, - min_interval: oneDayLoops.min_interval, - max_interval: oneDayLoops.max_interval, - avg_duration: oneDayLoops.avg_duration, - median_duration: oneDayLoops.median_duration, - min_duration: oneDayLoops.max_duration, - max_duration: oneDayLoops.max_duration - ) - - // Insulin - var insulinDistribution = [InsulinDistribution]() - var insulin = Ins( - TDD: 0, - bolus: 0, - temp_basal: 0, - scheduled_basal: 0, - total_average: 0 - ) - let requestInsulinDistribution = InsulinDistribution.fetchRequest() as NSFetchRequest - let sortInsulin = NSSortDescriptor(key: "date", ascending: false) - requestInsulinDistribution.sortDescriptors = [sortInsulin] - try? insulinDistribution = coredataContext.fetch(requestInsulinDistribution) - insulin = Ins( - TDD: roundDecimal(currentTDD, 2), - bolus: insulinDistribution.first != nil ? ((insulinDistribution.first?.bolus ?? 0) as Decimal) : 0, - temp_basal: insulinDistribution.first != nil ? ((insulinDistribution.first?.tempBasal ?? 0) as Decimal) : 0, - scheduled_basal: insulinDistribution - .first != nil ? ((insulinDistribution.first?.scheduledBasal ?? 0) as Decimal) : 0, - total_average: roundDecimal(tddTotalAverage, 1) - ) - - let hbA1cUnit = !overrideHbA1cUnit ? (units == .mmolL ? "mmol/mol" : "%") : (units == .mmolL ? "%" : "mmol/mol") - - let dailystat = Statistics( - created_at: Date(), - iPhone: UIDevice.current.getDeviceId, - iOS: UIDevice.current.getOSInfo, - Build_Version: version ?? "", - Build_Number: build ?? "1", - Branch: branch, - CopyRightNotice: String(copyrightNotice_.prefix(32)), - Build_Date: buildDate, - Algorithm: algo_, - AdjustmentFactor: af, - Pump: pump_, - CGM: cgm.rawValue, - insulinType: insulin_type.rawValue, - peakActivityTime: iPa, - Carbs_24h: carbTotal, - GlucoseStorage_Days: Decimal(roundDouble(numberOfDays, 1)), - Statistics: Stats( - Distribution: TimeInRange, - Glucose: avg, - HbA1c: hbs, Units: Units(Glucose: units.rawValue, HbA1c: hbA1cUnit), - LoopCycles: loopstat, - Insulin: insulin, - Variance: variance - ) - ) - storage.save(dailystat, as: file) - nightscout.uploadStatistics(dailystat: dailystat) - - let saveStatsCoreData = StatsData(context: self.coredataContext) - saveStatsCoreData.lastrun = Date() - try? self.coredataContext.save() - } - } - } - private func loopStats(loopStatRecord: LoopStats) { coredataContext.perform { let nLS = LoopStatRecord(context: self.coredataContext) diff --git a/FreeAPS/Sources/Models/FreeAPSSettings.swift b/FreeAPS/Sources/Models/FreeAPSSettings.swift index 217b926e7..a39b773b8 100644 --- a/FreeAPS/Sources/Models/FreeAPSSettings.swift +++ b/FreeAPS/Sources/Models/FreeAPSSettings.swift @@ -35,7 +35,6 @@ struct FreeAPSSettings: JSON, Equatable { var overrideHbA1cUnit: Bool = false var high: Decimal = 145 var low: Decimal = 70 - var uploadStats: Bool = true var hours: Int = 6 var xGridLines: Bool = true var yGridLines: Bool = true @@ -191,10 +190,6 @@ extension FreeAPSSettings: Decodable { settings.high = high } - if let uploadStats = try? container.decode(Bool.self, forKey: .uploadStats) { - settings.uploadStats = uploadStats - } - if let hours = try? container.decode(Int.self, forKey: .hours) { settings.hours = hours } diff --git a/FreeAPS/Sources/Modules/Home/HomeStateModel.swift b/FreeAPS/Sources/Modules/Home/HomeStateModel.swift index 92b4f2088..71e813a20 100644 --- a/FreeAPS/Sources/Modules/Home/HomeStateModel.swift +++ b/FreeAPS/Sources/Modules/Home/HomeStateModel.swift @@ -14,7 +14,6 @@ extension Home { private(set) var filteredHours = 24 @Published var glucose: [BloodGlucose] = [] @Published var suggestion: Suggestion? - @Published var uploadStats = false @Published var enactedSuggestion: Suggestion? @Published var recentGlucose: BloodGlucose? @Published var glucoseDelta: Int? @@ -76,7 +75,6 @@ extension Home { setupReservoir() suggestion = provider.suggestion - uploadStats = settingsManager.settings.uploadStats enactedSuggestion = provider.enactedSuggestion units = settingsManager.settings.units allowManualTemp = !settingsManager.settings.closedLoop @@ -392,7 +390,6 @@ extension Home.StateModel: func settingsDidChange(_ settings: FreeAPSSettings) { allowManualTemp = !settings.closedLoop - uploadStats = settingsManager.settings.uploadStats closedLoop = settingsManager.settings.closedLoop units = settingsManager.settings.units animatedBackground = settingsManager.settings.animatedBackground diff --git a/FreeAPS/Sources/Modules/NightscoutConfig/NightscoutConfigStateModel.swift b/FreeAPS/Sources/Modules/NightscoutConfig/NightscoutConfigStateModel.swift index 9ee7f5742..496fce9c6 100644 --- a/FreeAPS/Sources/Modules/NightscoutConfig/NightscoutConfigStateModel.swift +++ b/FreeAPS/Sources/Modules/NightscoutConfig/NightscoutConfigStateModel.swift @@ -22,7 +22,6 @@ extension NightscoutConfig { @Published var connecting = false @Published var backfilling = false @Published var isUploadEnabled = false // Allow uploads - @Published var uploadStats = false // Upload Statistics @Published var uploadGlucose = true // Upload Glucose @Published var changeUploadGlucose = true // if plugin, need to be change in CGM configuration @Published var useLocalSource = false @@ -46,7 +45,6 @@ extension NightscoutConfig { subscribeSetting(\.isUploadEnabled, on: $isUploadEnabled) { isUploadEnabled = $0 } subscribeSetting(\.useLocalGlucoseSource, on: $useLocalSource) { useLocalSource = $0 } subscribeSetting(\.localGlucosePort, on: $localPort.map(Int.init)) { localPort = Decimal($0) } - subscribeSetting(\.uploadStats, on: $uploadStats) { uploadStats = $0 } subscribeSetting(\.uploadGlucose, on: $uploadGlucose, initial: { uploadGlucose = $0 }) } diff --git a/FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutConfigRootView.swift b/FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutConfigRootView.swift index 7b329dc1c..79e096093 100644 --- a/FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutConfigRootView.swift +++ b/FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutConfigRootView.swift @@ -65,7 +65,6 @@ extension NightscoutConfig { Section { Toggle("Upload", isOn: $state.isUploadEnabled) if state.isUploadEnabled { - Toggle("Statistics", isOn: $state.uploadStats) Toggle("Glucose", isOn: $state.uploadGlucose).disabled(!state.changeUploadGlucose) } } header: { diff --git a/FreeAPS/Sources/Services/Network/NightscoutAPI.swift b/FreeAPS/Sources/Services/Network/NightscoutAPI.swift index ecf9b7b8d..a4d3b22d3 100644 --- a/FreeAPS/Sources/Services/Network/NightscoutAPI.swift +++ b/FreeAPS/Sources/Services/Network/NightscoutAPI.swift @@ -326,30 +326,6 @@ extension NightscoutAPI { .eraseToAnyPublisher() } - func uploadStats(_ stats: NightscoutStatistics) -> AnyPublisher { - var components = URLComponents() - components.scheme = url.scheme - components.host = url.host - components.port = url.port - components.path = Config.statusPath - - var request = URLRequest(url: components.url!) - request.allowsConstrainedNetworkAccess = false - request.timeoutInterval = Config.timeout - request.addValue("application/json", forHTTPHeaderField: "Content-Type") - - if let secret = secret { - request.addValue(secret.sha1(), forHTTPHeaderField: "api-secret") - } - request.httpBody = try! JSONCoding.encoder.encode(stats) - request.httpMethod = "POST" - - return service.run(request) - .retry(Config.retryCount) - .map { _ in () } - .eraseToAnyPublisher() - } - func uploadStatus(_ status: NightscoutStatus) -> AnyPublisher { var components = URLComponents() components.scheme = url.scheme diff --git a/FreeAPS/Sources/Services/Network/NightscoutManager.swift b/FreeAPS/Sources/Services/Network/NightscoutManager.swift index 2e0f2ecaf..f4c1d2ffb 100644 --- a/FreeAPS/Sources/Services/Network/NightscoutManager.swift +++ b/FreeAPS/Sources/Services/Network/NightscoutManager.swift @@ -13,7 +13,6 @@ protocol NightscoutManager: GlucoseSource { func deleteInsulin(at date: Date) func uploadStatus() func uploadGlucose() - func uploadStatistics(dailystat: Statistics) func uploadPreferences(_ preferences: Preferences) func uploadProfileAndSettings(_: Bool) var cgmURL: URL? { get } @@ -249,29 +248,6 @@ final class BaseNightscoutManager: NightscoutManager, Injectable { .store(in: &lifetime) } - func uploadStatistics(dailystat: Statistics) { - let stats = NightscoutStatistics( - dailystats: dailystat - ) - - guard let nightscout = nightscoutAPI, isUploadEnabled else { - return - } - - processQueue.async { - nightscout.uploadStats(stats) - .sink { completion in - switch completion { - case .finished: - debug(.nightscout, "Statistics uploaded") - case let .failure(error): - debug(.nightscout, error.localizedDescription) - } - } receiveValue: {} - .store(in: &self.lifetime) - } - } - func uploadPreferences(_ preferences: Preferences) { let prefs = NightscoutPreferences( preferences: settingsManager.preferences diff --git a/FreeAPS/Sources/Services/Network/TidepoolManager.swift b/FreeAPS/Sources/Services/Network/TidepoolManager.swift index 0380e186d..2850cf460 100644 --- a/FreeAPS/Sources/Services/Network/TidepoolManager.swift +++ b/FreeAPS/Sources/Services/Network/TidepoolManager.swift @@ -14,7 +14,6 @@ protocol TidePoolManager { // func uploadStatus() func uploadGlucose(device: HKDevice?) func forceUploadData(device: HKDevice?) -// func uploadStatistics(dailystat: Statistics) // func uploadPreferences(_ preferences: Preferences) // func uploadProfileAndSettings(_: Bool) }