From c740ea187818aebb472783bc445eb400bb1ff500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20B=20M=C3=A5rtensson?= <53905247+Jon-b-m@users.noreply.github.com> Date: Tue, 21 May 2024 22:36:43 +0200 Subject: [PATCH] Save settings and preferences and profiles to stat database (#698) * Share settings and profiles * Share Settings and Preferences --- .../Models/NightscoutPreferences.swift | 1 + .../Sources/Models/NightscoutSettings.swift | 3 +- FreeAPS/Sources/Models/NightscoutStatus.swift | 2 +- .../Services/Network/NightscoutAPI.swift | 46 ++++++++---- .../Services/Network/NightscoutManager.swift | 73 ++++++++++++++----- 5 files changed, 90 insertions(+), 35 deletions(-) diff --git a/FreeAPS/Sources/Models/NightscoutPreferences.swift b/FreeAPS/Sources/Models/NightscoutPreferences.swift index e6291e9338..f02213772f 100644 --- a/FreeAPS/Sources/Models/NightscoutPreferences.swift +++ b/FreeAPS/Sources/Models/NightscoutPreferences.swift @@ -3,4 +3,5 @@ import Foundation struct NightscoutPreferences: JSON { var report = "preferences" let preferences: Preferences? + let enteredBy: String } diff --git a/FreeAPS/Sources/Models/NightscoutSettings.swift b/FreeAPS/Sources/Models/NightscoutSettings.swift index 1ed366aa2b..5a757372a7 100644 --- a/FreeAPS/Sources/Models/NightscoutSettings.swift +++ b/FreeAPS/Sources/Models/NightscoutSettings.swift @@ -1,6 +1,7 @@ import Foundation struct NightscoutSettings: JSON { - let report = "settings" + var report = "settings" let settings: FreeAPSSettings? + let enteredBy: String } diff --git a/FreeAPS/Sources/Models/NightscoutStatus.swift b/FreeAPS/Sources/Models/NightscoutStatus.swift index 057e876a32..4102dde9d2 100644 --- a/FreeAPS/Sources/Models/NightscoutStatus.swift +++ b/FreeAPS/Sources/Models/NightscoutStatus.swift @@ -50,6 +50,6 @@ struct NightscoutProfileStore: JSON { let startDate: Date let mills: Int let units: String - let enteredBy: String + var enteredBy: String let store: [String: ScheduledNightscoutProfile] } diff --git a/FreeAPS/Sources/Services/Network/NightscoutAPI.swift b/FreeAPS/Sources/Services/Network/NightscoutAPI.swift index 65151b5702..926884acfd 100644 --- a/FreeAPS/Sources/Services/Network/NightscoutAPI.swift +++ b/FreeAPS/Sources/Services/Network/NightscoutAPI.swift @@ -559,20 +559,18 @@ extension NightscoutAPI { } func uploadPrefs(_ prefs: NightscoutPreferences) -> AnyPublisher { + let statURL = IAPSconfig.statURL var components = URLComponents() - components.scheme = url.scheme - components.host = url.host - components.port = url.port - components.path = Config.statusPath + components.scheme = statURL.scheme + components.host = statURL.host + components.port = statURL.port + components.path = Config.sharePath 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(prefs) request.httpMethod = "POST" @@ -583,20 +581,18 @@ extension NightscoutAPI { } func uploadSettings(_ settings: NightscoutSettings) -> AnyPublisher { + let statURL = IAPSconfig.statURL var components = URLComponents() - components.scheme = url.scheme - components.host = url.host - components.port = url.port - components.path = Config.statusPath + components.scheme = statURL.scheme + components.host = statURL.host + components.port = statURL.port + components.path = Config.sharePath 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(settings) request.httpMethod = "POST" @@ -630,6 +626,28 @@ extension NightscoutAPI { .eraseToAnyPublisher() } + func uploadSettingsToDatabase(_ profile: NightscoutProfileStore) -> AnyPublisher { + let statURL = IAPSconfig.statURL + var components = URLComponents() + components.scheme = statURL.scheme + components.host = statURL.host + components.port = statURL.port + components.path = Config.sharePath + + var request = URLRequest(url: components.url!) + request.allowsConstrainedNetworkAccess = false + request.timeoutInterval = Config.timeout + request.addValue("application/json", forHTTPHeaderField: "Content-Type") + + request.httpBody = try! JSONCoding.encoder.encode(profile) + request.httpMethod = "POST" + + return service.run(request) + .retry(Config.retryCount) + .map { _ in () } + .eraseToAnyPublisher() + } + func uploadPreferences(_ preferences: Preferences) -> 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 e5e52b87c4..b876c2b370 100644 --- a/FreeAPS/Sources/Services/Network/NightscoutManager.swift +++ b/FreeAPS/Sources/Services/Network/NightscoutManager.swift @@ -58,6 +58,10 @@ final class BaseNightscoutManager: NightscoutManager, Injectable { settingsManager.settings.isUploadEnabled } + private var isStatsUploadEnabled: Bool { + settingsManager.settings.uploadStats + } + private var isUploadGlucoseEnabled: Bool { settingsManager.settings.uploadGlucose } @@ -472,10 +476,10 @@ final class BaseNightscoutManager: NightscoutManager, Injectable { func uploadPreferences(_ preferences: Preferences) { let prefs = NightscoutPreferences( - preferences: settingsManager.preferences + preferences: settingsManager.preferences, enteredBy: getIdentifier() ) - guard let nightscout = nightscoutAPI, isUploadEnabled else { + guard let nightscout = nightscoutAPI, isStatsUploadEnabled else { return } @@ -484,7 +488,7 @@ final class BaseNightscoutManager: NightscoutManager, Injectable { .sink { completion in switch completion { case .finished: - debug(.nightscout, "Preferences uploaded") + debug(.nightscout, "Preferences uploaded to database") self.storage.save(preferences, as: OpenAPS.Nightscout.uploadedPreferences) case let .failure(error): debug(.nightscout, error.localizedDescription) @@ -496,10 +500,10 @@ final class BaseNightscoutManager: NightscoutManager, Injectable { func uploadSettings(_ settings: FreeAPSSettings) { let sets = NightscoutSettings( - settings: settingsManager.settings + settings: settingsManager.settings, enteredBy: getIdentifier() ) - guard let nightscout = nightscoutAPI, isUploadEnabled else { + guard let nightscout = nightscoutAPI, isStatsUploadEnabled else { return } @@ -508,7 +512,7 @@ final class BaseNightscoutManager: NightscoutManager, Injectable { .sink { completion in switch completion { case .finished: - debug(.nightscout, "Settings uploaded") + debug(.nightscout, "Settings uploaded to database") self.storage.save(settings, as: OpenAPS.Nightscout.uploadedSettings) case let .failure(error): debug(.nightscout, error.localizedDescription) @@ -730,7 +734,7 @@ final class BaseNightscoutManager: NightscoutManager, Injectable { store: [defaultProfile: ps] ) - guard let nightscout = nightscoutAPI, isNetworkReachable, isUploadEnabled else { + guard let nightscout = nightscoutAPI, isNetworkReachable, isUploadEnabled || isStatsUploadEnabled else { return } @@ -754,18 +758,39 @@ final class BaseNightscoutManager: NightscoutManager, Injectable { { NSLog("NightscoutManager uploadProfile, no profile change") } else { - processQueue.async { - nightscout.uploadProfile(p) - .sink { completion in - switch completion { - case .finished: - self.storage.save(p, as: OpenAPS.Nightscout.uploadedProfile) - debug(.nightscout, "Profile uploaded") - case let .failure(error): - debug(.nightscout, error.localizedDescription) - } - } receiveValue: {} - .store(in: &self.lifetime) + if isUploadEnabled { + processQueue.async { + nightscout.uploadProfile(p) + .sink { completion in + switch completion { + case .finished: + self.storage.save(p, as: OpenAPS.Nightscout.uploadedProfile) + debug(.nightscout, "Profile uploaded") + case let .failure(error): + debug(.nightscout, error.localizedDescription) + } + } receiveValue: {} + .store(in: &self.lifetime) + } + } + if isStatsUploadEnabled { + var q = p + q.enteredBy = getIdentifier() + processQueue.async { + nightscout.uploadSettingsToDatabase(q) + .sink { completion in + switch completion { + case .finished: + debug(.nightscout, "Profiles uploaded to database") + if !self.isUploadEnabled { + self.storage.save(p, as: OpenAPS.Nightscout.uploadedProfile) + } + case let .failure(error): + debug(.nightscout, error.localizedDescription) + } + } receiveValue: {} + .store(in: &self.lifetime) + } } } } @@ -775,6 +800,16 @@ final class BaseNightscoutManager: NightscoutManager, Injectable { uploadTreatments(glucoseStorage.nightscoutCGMStateNotUploaded(), fileToSave: OpenAPS.Nightscout.uploadedCGMState) } + private func getIdentifier() -> String { + var identfier = keychain.getValue(String.self, forKey: IAPSconfig.id) ?? "" + guard identfier.count > 1 else { + identfier = UUID().uuidString + keychain.setValue(identfier, forKey: IAPSconfig.id) + return identfier + } + return identfier + } + func uploadManualGlucose() { uploadTreatments( glucoseStorage.nightscoutManualGlucoseNotUploaded(),