DeviceDataManager.swift 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import Combine
  2. import Foundation
  3. import LoopKit
  4. import LoopKitUI
  5. import MinimedKit
  6. import OmniKit
  7. import SwiftDate
  8. import UserNotifications
  9. private let staticPumpManagers: [PumpManagerUI.Type] = [
  10. MinimedPumpManager.self,
  11. OmnipodPumpManager.self
  12. ]
  13. private let staticPumpManagersByIdentifier: [String: PumpManagerUI.Type] = staticPumpManagers.reduce(into: [:]) { map, Type in
  14. map[Type.managerIdentifier] = Type
  15. }
  16. final class DeviceDataManager {
  17. var pumpManager: PumpManagerUI? {
  18. didSet {
  19. pumpManager?.pumpManagerDelegate = self
  20. UserDefaults.standard.pumpManagerRawValue = pumpManager?.rawValue
  21. if let pumpManager = pumpManager {
  22. pumpDisplayState.value = PumpDisplayState(name: pumpManager.localizedTitle, image: pumpManager.smallImage)
  23. } else {
  24. pumpDisplayState.value = nil
  25. }
  26. }
  27. }
  28. let pumpDisplayState = CurrentValueSubject<PumpDisplayState?, Never>(nil)
  29. init() {
  30. setupPumpManager()
  31. }
  32. func setupPumpManager() {
  33. if let pumpManagerRawValue = UserDefaults.standard.pumpManagerRawValue {
  34. pumpManager = pumpManagerFromRawValue(pumpManagerRawValue)
  35. }
  36. }
  37. private func pumpManagerFromRawValue(_ rawValue: [String: Any]) -> PumpManagerUI? {
  38. guard let rawState = rawValue["state"] as? PumpManager.RawStateValue,
  39. let Manager = pumpManagerTypeFromRawValue(rawValue)
  40. else {
  41. return nil
  42. }
  43. return Manager.init(rawState: rawState) as? PumpManagerUI
  44. }
  45. private func pumpManagerTypeFromRawValue(_ rawValue: [String: Any]) -> PumpManager.Type? {
  46. guard let managerIdentifier = rawValue["managerIdentifier"] as? String else {
  47. return nil
  48. }
  49. return staticPumpManagersByIdentifier[managerIdentifier]
  50. }
  51. }
  52. extension DeviceDataManager: PumpManagerDelegate {
  53. func pumpManager(_: PumpManager, didAdjustPumpClockBy _: TimeInterval) {
  54. // log.debug("didAdjustPumpClockBy %@", adjustment)
  55. }
  56. func pumpManagerDidUpdateState(_ pumpManager: PumpManager) {
  57. UserDefaults.standard.pumpManagerRawValue = pumpManager.rawValue
  58. }
  59. func pumpManagerBLEHeartbeatDidFire(_ pumpManager: PumpManager) {
  60. print("[DeviceDataManager] Pump Heartbeat")
  61. pumpManager.ensureCurrentPumpData {
  62. print("[DeviceDataManager] Pump Data updated")
  63. }
  64. }
  65. func pumpManagerMustProvideBLEHeartbeat(_: PumpManager) -> Bool {
  66. true
  67. }
  68. func pumpManager(_: PumpManager, didUpdate status: PumpManagerStatus, oldStatus _: PumpManagerStatus) {
  69. print("[DeviceDataManager] new pump status Bolus: \(status.bolusState)")
  70. print("[DeviceDataManager] new pump status Basal: \(String(describing: status.basalDeliveryState))")
  71. }
  72. func pumpManagerWillDeactivate(_: PumpManager) {
  73. pumpManager = nil
  74. }
  75. func pumpManager(_: PumpManager, didUpdatePumpRecordsBasalProfileStartEvents _: Bool) {}
  76. func pumpManager(_: PumpManager, didError error: PumpManagerError) {
  77. print("[DeviceDataManager] error: \(error.localizedDescription)")
  78. }
  79. func pumpManager(
  80. _: PumpManager,
  81. hasNewPumpEvents events: [NewPumpEvent],
  82. lastReconciliation _: Date?,
  83. completion: @escaping (_ error: Error?) -> Void
  84. ) {
  85. print("[DeviceDataManager] new pump events: \(events.compactMap(\.dose?.type))")
  86. completion(nil)
  87. }
  88. func pumpManager(
  89. _: PumpManager,
  90. didReadReservoirValue units: Double,
  91. at date: Date,
  92. completion: @escaping (Result<
  93. (newValue: ReservoirValue, lastValue: ReservoirValue?, areStoredValuesContinuous: Bool),
  94. Error
  95. >) -> Void
  96. ) {
  97. print("[DeviceDataManager] Reservoir Value \(units), at: \(date)")
  98. completion(.success((
  99. newValue: Reservoir(startDate: Date(), unitVolume: units),
  100. lastValue: nil,
  101. areStoredValuesContinuous: true
  102. )))
  103. }
  104. func pumpManagerRecommendsLoop(_: PumpManager) {
  105. print("[DeviceDataManager] recomends loop")
  106. // pumpManager.enactBolus(units: 0.1, automatic: true) { _ in
  107. // print("[DeviceDataManager] Bolus done")
  108. // }
  109. }
  110. func startDateToFilterNewPumpEvents(for _: PumpManager) -> Date {
  111. Date().addingTimeInterval(-2.hours.timeInterval)
  112. }
  113. }
  114. // MARK: - DeviceManagerDelegate
  115. extension DeviceDataManager: DeviceManagerDelegate {
  116. func scheduleNotification(
  117. for _: DeviceManager,
  118. identifier: String,
  119. content: UNNotificationContent,
  120. trigger: UNNotificationTrigger?
  121. ) {
  122. let request = UNNotificationRequest(
  123. identifier: identifier,
  124. content: content,
  125. trigger: trigger
  126. )
  127. DispatchQueue.main.async {
  128. UNUserNotificationCenter.current().add(request)
  129. }
  130. }
  131. func clearNotification(for _: DeviceManager, identifier: String) {
  132. DispatchQueue.main.async {
  133. UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [identifier])
  134. }
  135. }
  136. func removeNotificationRequests(for _: DeviceManager, identifiers: [String]) {
  137. DispatchQueue.main.async {
  138. UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: identifiers)
  139. }
  140. }
  141. func deviceManager(
  142. _: DeviceManager,
  143. logEventForDeviceIdentifier _: String?,
  144. type _: DeviceLogEntryType,
  145. message _: String,
  146. completion _: ((Error?) -> Void)?
  147. ) {}
  148. }
  149. // MARK: - AlertPresenter
  150. extension DeviceDataManager: AlertPresenter {
  151. func issueAlert(_: Alert) {}
  152. func retractAlert(identifier _: Alert.Identifier) {}
  153. }