LibreTransmitterSource.swift 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import Combine
  2. import Foundation
  3. import LibreTransmitter
  4. import LoopKitUI
  5. import Swinject
  6. protocol LibreTransmitterSource: GlucoseSource {
  7. var manager: LibreTransmitterManager? { get set }
  8. }
  9. final class BaseLibreTransmitterSource: LibreTransmitterSource, Injectable {
  10. var cgmManager: CGMManagerUI?
  11. var cgmType: CGMType = .libreTransmitter
  12. private let processQueue = DispatchQueue(label: "BaseLibreTransmitterSource.processQueue")
  13. @Injected() var glucoseStorage: GlucoseStorage!
  14. @Injected() var calibrationService: CalibrationService!
  15. private var promise: Future<[BloodGlucose], Error>.Promise?
  16. var glucoseManager: FetchGlucoseManager?
  17. var manager: LibreTransmitterManager? {
  18. didSet {
  19. configured = manager != nil
  20. manager?.cgmManagerDelegate = self
  21. }
  22. }
  23. @Persisted(key: "LibreTransmitterManager.configured") private(set) var configured = false
  24. init(resolver: Resolver) {
  25. if configured {
  26. manager = LibreTransmitterManager()
  27. manager?.cgmManagerDelegate = self
  28. }
  29. injectServices(resolver)
  30. }
  31. func fetch(_: DispatchTimer?) -> AnyPublisher<[BloodGlucose], Never> {
  32. Future<[BloodGlucose], Error> { [weak self] promise in
  33. self?.promise = promise
  34. }
  35. .timeout(60, scheduler: processQueue, options: nil, customError: nil)
  36. .replaceError(with: [])
  37. .replaceEmpty(with: [])
  38. .eraseToAnyPublisher()
  39. }
  40. func fetchIfNeeded() -> AnyPublisher<[BloodGlucose], Never> {
  41. fetch(nil)
  42. }
  43. func sourceInfo() -> [String: Any]? {
  44. if let battery = manager?.battery {
  45. return ["transmitterBattery": battery]
  46. }
  47. return nil
  48. }
  49. }
  50. extension BaseLibreTransmitterSource: LibreTransmitterManagerDelegate {
  51. var queue: DispatchQueue { processQueue }
  52. func startDateToFilterNewData(for _: LibreTransmitterManager) -> Date? {
  53. glucoseStorage.syncDate()
  54. }
  55. func cgmManager(_ manager: LibreTransmitterManager, hasNew result: Result<[LibreGlucose], Error>) {
  56. switch result {
  57. case let .success(newGlucose):
  58. let glucose = newGlucose.map { value -> BloodGlucose in
  59. BloodGlucose(
  60. _id: UUID().uuidString,
  61. sgv: Int(value.glucose),
  62. direction: manager.glucoseDisplay?.trendType
  63. .map { .init(trendType: $0) },
  64. date: Decimal(Int(value.startDate.timeIntervalSince1970 * 1000)),
  65. dateString: value.startDate,
  66. unfiltered: Decimal(value.unsmoothedGlucose),
  67. filtered: nil,
  68. noise: nil,
  69. glucose: Int(value.glucose),
  70. type: "sgv",
  71. activationDate: value.sensorStartDate ?? manager.sensorStartDate,
  72. sessionStartDate: value.sensorStartDate ?? manager.sensorStartDate,
  73. transmitterID: manager.sensorSerialNumber
  74. )
  75. }
  76. NSLog("Debug Libre \(glucose)")
  77. promise?(.success(glucose))
  78. case let .failure(error):
  79. warning(.service, "LibreTransmitter error:", error: error)
  80. promise?(.failure(error))
  81. }
  82. }
  83. func overcalibration(for _: LibreTransmitterManager) -> ((Double) -> (Double))? {
  84. calibrationService.calibrate
  85. }
  86. }