Ivan Valkou 5 лет назад
Родитель
Сommit
2872cf1a62

+ 4 - 0
FreeAPS.xcodeproj/project.pbxproj

@@ -131,6 +131,7 @@
 		38BF021725E7CBBC00579895 /* PumpManagerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38BF021625E7CBBC00579895 /* PumpManagerExtensions.swift */; };
 		38BF021725E7CBBC00579895 /* PumpManagerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38BF021625E7CBBC00579895 /* PumpManagerExtensions.swift */; };
 		38BF021B25E7D06400579895 /* PumpSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38BF021A25E7D06400579895 /* PumpSettingsView.swift */; };
 		38BF021B25E7D06400579895 /* PumpSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38BF021A25E7D06400579895 /* PumpSettingsView.swift */; };
 		38BF021D25E7E3AF00579895 /* Reservoir.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38BF021C25E7E3AF00579895 /* Reservoir.swift */; };
 		38BF021D25E7E3AF00579895 /* Reservoir.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38BF021C25E7E3AF00579895 /* Reservoir.swift */; };
+		38BF021F25E7F0DE00579895 /* DeviceDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38BF021E25E7F0DE00579895 /* DeviceDataManager.swift */; };
 		38FE826A25CC82DB001FF17A /* NetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38FE826925CC82DB001FF17A /* NetworkService.swift */; };
 		38FE826A25CC82DB001FF17A /* NetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38FE826925CC82DB001FF17A /* NetworkService.swift */; };
 		38FE826D25CC8461001FF17A /* NightscoutAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38FE826C25CC8461001FF17A /* NightscoutAPI.swift */; };
 		38FE826D25CC8461001FF17A /* NightscoutAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38FE826C25CC8461001FF17A /* NightscoutAPI.swift */; };
 		45252C95D220E796FDB3B022 /* ConfigEditorDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8A87AA037BD079BA3528BA /* ConfigEditorDataFlow.swift */; };
 		45252C95D220E796FDB3B022 /* ConfigEditorDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8A87AA037BD079BA3528BA /* ConfigEditorDataFlow.swift */; };
@@ -605,6 +606,7 @@
 		38BF021625E7CBBC00579895 /* PumpManagerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PumpManagerExtensions.swift; sourceTree = "<group>"; };
 		38BF021625E7CBBC00579895 /* PumpManagerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PumpManagerExtensions.swift; sourceTree = "<group>"; };
 		38BF021A25E7D06400579895 /* PumpSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PumpSettingsView.swift; sourceTree = "<group>"; };
 		38BF021A25E7D06400579895 /* PumpSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PumpSettingsView.swift; sourceTree = "<group>"; };
 		38BF021C25E7E3AF00579895 /* Reservoir.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Reservoir.swift; sourceTree = "<group>"; };
 		38BF021C25E7E3AF00579895 /* Reservoir.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Reservoir.swift; sourceTree = "<group>"; };
+		38BF021E25E7F0DE00579895 /* DeviceDataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceDataManager.swift; sourceTree = "<group>"; };
 		38FE826925CC82DB001FF17A /* NetworkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkService.swift; sourceTree = "<group>"; };
 		38FE826925CC82DB001FF17A /* NetworkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkService.swift; sourceTree = "<group>"; };
 		38FE826C25CC8461001FF17A /* NightscoutAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutAPI.swift; sourceTree = "<group>"; };
 		38FE826C25CC8461001FF17A /* NightscoutAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutAPI.swift; sourceTree = "<group>"; };
 		3BF768BD6264FF7D71D66767 /* NightscoutConfigProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = NightscoutConfigProvider.swift; sourceTree = "<group>"; };
 		3BF768BD6264FF7D71D66767 /* NightscoutConfigProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = NightscoutConfigProvider.swift; sourceTree = "<group>"; };
@@ -980,6 +982,7 @@
 			children = (
 			children = (
 				3811DF0B25CAAABD00A708ED /* APSManager.swift */,
 				3811DF0B25CAAABD00A708ED /* APSManager.swift */,
 				3811DF0F25CAAAE200A708ED /* BaseAPSManager.swift */,
 				3811DF0F25CAAAE200A708ED /* BaseAPSManager.swift */,
+				38BF021E25E7F0DE00579895 /* DeviceDataManager.swift */,
 				38A504F625DDA0E200C5B9E8 /* Extensions */,
 				38A504F625DDA0E200C5B9E8 /* Extensions */,
 				388E5A5825B6F0070019842D /* OpenAPS */,
 				388E5A5825B6F0070019842D /* OpenAPS */,
 			);
 			);
@@ -1642,6 +1645,7 @@
 				38BF021B25E7D06400579895 /* PumpSettingsView.swift in Sources */,
 				38BF021B25E7D06400579895 /* PumpSettingsView.swift in Sources */,
 				3811DEEA25CA063400A708ED /* SyncAccess.swift in Sources */,
 				3811DEEA25CA063400A708ED /* SyncAccess.swift in Sources */,
 				3811DE4F25C9D4B800A708ED /* AuthotizedRootDataFlow.swift in Sources */,
 				3811DE4F25C9D4B800A708ED /* AuthotizedRootDataFlow.swift in Sources */,
+				38BF021F25E7F0DE00579895 /* DeviceDataManager.swift in Sources */,
 				3811DE5025C9D4B800A708ED /* AuthotizedRootProvider.swift in Sources */,
 				3811DE5025C9D4B800A708ED /* AuthotizedRootProvider.swift in Sources */,
 				38A504A425DD9C4000C5B9E8 /* UserDefaultsExtensions.swift in Sources */,
 				38A504A425DD9C4000C5B9E8 /* UserDefaultsExtensions.swift in Sources */,
 				38FE826A25CC82DB001FF17A /* NetworkService.swift in Sources */,
 				38FE826A25CC82DB001FF17A /* NetworkService.swift in Sources */,

+ 7 - 176
FreeAPS/Sources/APS/BaseAPSManager.swift

@@ -1,198 +1,29 @@
 import Combine
 import Combine
 import Foundation
 import Foundation
-import LoopKit
 import LoopKitUI
 import LoopKitUI
-import MinimedKit
-import MinimedKitUI
-import NightscoutUploadKit
-import OmniKit
-import RileyLinkBLEKit
-import RileyLinkKit
-import RileyLinkKitUI
-import SwiftDate
 import Swinject
 import Swinject
-import UserNotifications
-
-private let staticPumpManagers: [PumpManagerUI.Type] = [
-    MinimedPumpManager.self,
-    OmnipodPumpManager.self
-]
-
-private let staticPumpManagersByIdentifier: [String: PumpManagerUI.Type] = staticPumpManagers.reduce(into: [:]) { map, Type in
-    map[Type.managerIdentifier] = Type
-}
 
 
 final class BaseAPSManager: APSManager, Injectable {
 final class BaseAPSManager: APSManager, Injectable {
     private var openAPS: OpenAPS!
     private var openAPS: OpenAPS!
+    private let deviceDataManager = DeviceDataManager()
 
 
     var pumpManager: PumpManagerUI? {
     var pumpManager: PumpManagerUI? {
-        didSet {
-            pumpManager?.pumpManagerDelegate = self
-            UserDefaults.standard.pumpManagerRawValue = pumpManager?.rawValue
-            if let pumpManager = pumpManager {
-                pumpDisplayState.value = PumpDisplayState(name: pumpManager.localizedTitle, image: pumpManager.smallImage)
-            } else {
-                pumpDisplayState.value = nil
-            }
+        get {
+            deviceDataManager.pumpManager
+        }
+        set {
+            deviceDataManager.pumpManager = newValue
         }
         }
     }
     }
 
 
-    let pumpDisplayState = CurrentValueSubject<PumpDisplayState?, Never>(nil)
+    var pumpDisplayState: CurrentValueSubject<PumpDisplayState?, Never> { deviceDataManager.pumpDisplayState }
 
 
     init(resolver: Resolver) {
     init(resolver: Resolver) {
         injectServices(resolver)
         injectServices(resolver)
         openAPS = OpenAPS(storage: resolver.resolve(FileStorage.self)!)
         openAPS = OpenAPS(storage: resolver.resolve(FileStorage.self)!)
-        setupPumpManager()
-    }
-
-    private func setupPumpManager() {
-        if let pumpManagerRawValue = UserDefaults.standard.pumpManagerRawValue {
-            pumpManager = pumpManagerFromRawValue(pumpManagerRawValue)
-        }
     }
     }
 
 
     func runTest() {
     func runTest() {
         openAPS.test()
         openAPS.test()
     }
     }
-
-    private func pumpManagerFromRawValue(_ rawValue: [String: Any]) -> PumpManagerUI? {
-        guard let rawState = rawValue["state"] as? PumpManager.RawStateValue,
-              let Manager = pumpManagerTypeFromRawValue(rawValue)
-        else {
-            return nil
-        }
-
-        return Manager.init(rawState: rawState) as? PumpManagerUI
-    }
-
-    private func pumpManagerTypeFromRawValue(_ rawValue: [String: Any]) -> PumpManager.Type? {
-        guard let managerIdentifier = rawValue["managerIdentifier"] as? String else {
-            return nil
-        }
-
-        return staticPumpManagersByIdentifier[managerIdentifier]
-    }
-}
-
-extension BaseAPSManager: PumpManagerDelegate {
-    func pumpManager(_: PumpManager, didAdjustPumpClockBy _: TimeInterval) {
-//        log.debug("didAdjustPumpClockBy %@", adjustment)
-    }
-
-    func pumpManagerDidUpdateState(_ pumpManager: PumpManager) {
-        UserDefaults.standard.pumpManagerRawValue = pumpManager.rawValue
-    }
-
-    func pumpManagerBLEHeartbeatDidFire(_ pumpManager: PumpManager) {
-        print("[APSManager] Pump Heartbeat")
-        pumpManager.ensureCurrentPumpData {
-            print("[APSManager] Pump Data updated")
-        }
-    }
-
-    func pumpManagerMustProvideBLEHeartbeat(_: PumpManager) -> Bool {
-        true
-    }
-
-    func pumpManager(_: PumpManager, didUpdate status: PumpManagerStatus, oldStatus _: PumpManagerStatus) {
-        print("[APSManager] new pump status Bolus: \(status.bolusState)")
-        print("[APSManager] new pump status Basal: \(String(describing: status.basalDeliveryState))")
-    }
-
-    func pumpManagerWillDeactivate(_: PumpManager) {
-        pumpManager = nil
-    }
-
-    func pumpManager(_: PumpManager, didUpdatePumpRecordsBasalProfileStartEvents _: Bool) {}
-
-    func pumpManager(_: PumpManager, didError error: PumpManagerError) {
-        print("[APSManager] error: \(error.localizedDescription)")
-    }
-
-    func pumpManager(
-        _: PumpManager,
-        hasNewPumpEvents events: [NewPumpEvent],
-        lastReconciliation _: Date?,
-        completion: @escaping (_ error: Error?) -> Void
-    ) {
-        print("[APSManager] new pump events: \(events.compactMap(\.dose?.type))")
-        completion(nil)
-    }
-
-    func pumpManager(
-        _: PumpManager,
-        didReadReservoirValue units: Double,
-        at date: Date,
-        completion: @escaping (Result<
-            (newValue: ReservoirValue, lastValue: ReservoirValue?, areStoredValuesContinuous: Bool),
-            Error
-        >) -> Void
-    ) {
-        print("[APSManager] Reservoir Value \(units), at: \(date)")
-        completion(.success((
-            newValue: Reservoir(startDate: Date(), unitVolume: units),
-            lastValue: nil,
-            areStoredValuesContinuous: true
-        )))
-    }
-
-    func pumpManagerRecommendsLoop(_: PumpManager) {
-        print("[APSManager] recomends loop")
-//        pumpManager.enactBolus(units: 0.1, automatic: true) { _ in
-//            print("[APSManager] Bolus done")
-//        }
-    }
-
-    func startDateToFilterNewPumpEvents(for _: PumpManager) -> Date {
-        Date().addingTimeInterval(-2.hours.timeInterval)
-    }
-}
-
-// MARK: - DeviceManagerDelegate
-
-extension BaseAPSManager: DeviceManagerDelegate {
-    func scheduleNotification(
-        for _: DeviceManager,
-        identifier: String,
-        content: UNNotificationContent,
-        trigger: UNNotificationTrigger?
-    ) {
-        let request = UNNotificationRequest(
-            identifier: identifier,
-            content: content,
-            trigger: trigger
-        )
-
-        DispatchQueue.main.async {
-            UNUserNotificationCenter.current().add(request)
-        }
-    }
-
-    func clearNotification(for _: DeviceManager, identifier: String) {
-        DispatchQueue.main.async {
-            UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [identifier])
-        }
-    }
-
-    func removeNotificationRequests(for _: DeviceManager, identifiers: [String]) {
-        DispatchQueue.main.async {
-            UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: identifiers)
-        }
-    }
-
-    func deviceManager(
-        _: DeviceManager,
-        logEventForDeviceIdentifier _: String?,
-        type _: DeviceLogEntryType,
-        message _: String,
-        completion _: ((Error?) -> Void)?
-    ) {}
-}
-
-// MARK: - AlertPresenter
-
-extension BaseAPSManager: AlertPresenter {
-    func issueAlert(_: Alert) {}
-
-    func retractAlert(identifier _: Alert.Identifier) {}
 }
 }

+ 184 - 0
FreeAPS/Sources/APS/DeviceDataManager.swift

@@ -0,0 +1,184 @@
+import Combine
+import Foundation
+import LoopKit
+import LoopKitUI
+import MinimedKit
+import OmniKit
+import SwiftDate
+import UserNotifications
+
+private let staticPumpManagers: [PumpManagerUI.Type] = [
+    MinimedPumpManager.self,
+    OmnipodPumpManager.self
+]
+
+private let staticPumpManagersByIdentifier: [String: PumpManagerUI.Type] = staticPumpManagers.reduce(into: [:]) { map, Type in
+    map[Type.managerIdentifier] = Type
+}
+
+final class DeviceDataManager {
+    var pumpManager: PumpManagerUI? {
+        didSet {
+            pumpManager?.pumpManagerDelegate = self
+            UserDefaults.standard.pumpManagerRawValue = pumpManager?.rawValue
+            if let pumpManager = pumpManager {
+                pumpDisplayState.value = PumpDisplayState(name: pumpManager.localizedTitle, image: pumpManager.smallImage)
+            } else {
+                pumpDisplayState.value = nil
+            }
+        }
+    }
+
+    let pumpDisplayState = CurrentValueSubject<PumpDisplayState?, Never>(nil)
+
+    init() {
+        setupPumpManager()
+    }
+
+    func setupPumpManager() {
+        if let pumpManagerRawValue = UserDefaults.standard.pumpManagerRawValue {
+            pumpManager = pumpManagerFromRawValue(pumpManagerRawValue)
+        }
+    }
+
+    private func pumpManagerFromRawValue(_ rawValue: [String: Any]) -> PumpManagerUI? {
+        guard let rawState = rawValue["state"] as? PumpManager.RawStateValue,
+              let Manager = pumpManagerTypeFromRawValue(rawValue)
+        else {
+            return nil
+        }
+
+        return Manager.init(rawState: rawState) as? PumpManagerUI
+    }
+
+    private func pumpManagerTypeFromRawValue(_ rawValue: [String: Any]) -> PumpManager.Type? {
+        guard let managerIdentifier = rawValue["managerIdentifier"] as? String else {
+            return nil
+        }
+
+        return staticPumpManagersByIdentifier[managerIdentifier]
+    }
+}
+
+extension DeviceDataManager: PumpManagerDelegate {
+    func pumpManager(_: PumpManager, didAdjustPumpClockBy _: TimeInterval) {
+//        log.debug("didAdjustPumpClockBy %@", adjustment)
+    }
+
+    func pumpManagerDidUpdateState(_ pumpManager: PumpManager) {
+        UserDefaults.standard.pumpManagerRawValue = pumpManager.rawValue
+    }
+
+    func pumpManagerBLEHeartbeatDidFire(_ pumpManager: PumpManager) {
+        print("[DeviceDataManager] Pump Heartbeat")
+        pumpManager.ensureCurrentPumpData {
+            print("[DeviceDataManager] Pump Data updated")
+        }
+    }
+
+    func pumpManagerMustProvideBLEHeartbeat(_: PumpManager) -> Bool {
+        true
+    }
+
+    func pumpManager(_: PumpManager, didUpdate status: PumpManagerStatus, oldStatus _: PumpManagerStatus) {
+        print("[DeviceDataManager] new pump status Bolus: \(status.bolusState)")
+        print("[DeviceDataManager] new pump status Basal: \(String(describing: status.basalDeliveryState))")
+    }
+
+    func pumpManagerWillDeactivate(_: PumpManager) {
+        pumpManager = nil
+    }
+
+    func pumpManager(_: PumpManager, didUpdatePumpRecordsBasalProfileStartEvents _: Bool) {}
+
+    func pumpManager(_: PumpManager, didError error: PumpManagerError) {
+        print("[DeviceDataManager] error: \(error.localizedDescription)")
+    }
+
+    func pumpManager(
+        _: PumpManager,
+        hasNewPumpEvents events: [NewPumpEvent],
+        lastReconciliation _: Date?,
+        completion: @escaping (_ error: Error?) -> Void
+    ) {
+        print("[DeviceDataManager] new pump events: \(events.compactMap(\.dose?.type))")
+        completion(nil)
+    }
+
+    func pumpManager(
+        _: PumpManager,
+        didReadReservoirValue units: Double,
+        at date: Date,
+        completion: @escaping (Result<
+            (newValue: ReservoirValue, lastValue: ReservoirValue?, areStoredValuesContinuous: Bool),
+            Error
+        >) -> Void
+    ) {
+        print("[DeviceDataManager] Reservoir Value \(units), at: \(date)")
+        completion(.success((
+            newValue: Reservoir(startDate: Date(), unitVolume: units),
+            lastValue: nil,
+            areStoredValuesContinuous: true
+        )))
+    }
+
+    func pumpManagerRecommendsLoop(_: PumpManager) {
+        print("[DeviceDataManager] recomends loop")
+//        pumpManager.enactBolus(units: 0.1, automatic: true) { _ in
+//            print("[DeviceDataManager] Bolus done")
+//        }
+    }
+
+    func startDateToFilterNewPumpEvents(for _: PumpManager) -> Date {
+        Date().addingTimeInterval(-2.hours.timeInterval)
+    }
+}
+
+// MARK: - DeviceManagerDelegate
+
+extension DeviceDataManager: DeviceManagerDelegate {
+    func scheduleNotification(
+        for _: DeviceManager,
+        identifier: String,
+        content: UNNotificationContent,
+        trigger: UNNotificationTrigger?
+    ) {
+        let request = UNNotificationRequest(
+            identifier: identifier,
+            content: content,
+            trigger: trigger
+        )
+
+        DispatchQueue.main.async {
+            UNUserNotificationCenter.current().add(request)
+        }
+    }
+
+    func clearNotification(for _: DeviceManager, identifier: String) {
+        DispatchQueue.main.async {
+            UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [identifier])
+        }
+    }
+
+    func removeNotificationRequests(for _: DeviceManager, identifiers: [String]) {
+        DispatchQueue.main.async {
+            UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: identifiers)
+        }
+    }
+
+    func deviceManager(
+        _: DeviceManager,
+        logEventForDeviceIdentifier _: String?,
+        type _: DeviceLogEntryType,
+        message _: String,
+        completion _: ((Error?) -> Void)?
+    ) {}
+}
+
+// MARK: - AlertPresenter
+
+extension DeviceDataManager: AlertPresenter {
+    func issueAlert(_: Alert) {}
+
+    func retractAlert(identifier _: Alert.Identifier) {}
+}