|
|
@@ -154,6 +154,69 @@ final class BaseDeviceDataManager: DeviceDataManager, Injectable {
|
|
|
|
|
|
return staticPumpManagersByIdentifier[managerIdentifier]
|
|
|
}
|
|
|
+
|
|
|
+ // MARK: - GlucoseSource
|
|
|
+
|
|
|
+ @Persisted(key: "BaseDeviceDataManager.lastFetchGlucoseDate") private var lastFetchGlucoseDate: Date = .distantPast
|
|
|
+
|
|
|
+ func fetch() -> AnyPublisher<[BloodGlucose], Never> {
|
|
|
+ guard let medtronic = pumpManager as? MinimedPumpManager else {
|
|
|
+ warning(.deviceManager, "Fetch minilink glucose failed: Pump is not Medtronic")
|
|
|
+ return Just([]).eraseToAnyPublisher()
|
|
|
+ }
|
|
|
+
|
|
|
+ guard lastFetchGlucoseDate.addingTimeInterval(4.5 * 60) < Date() else {
|
|
|
+ return Just([]).eraseToAnyPublisher()
|
|
|
+ }
|
|
|
+
|
|
|
+ return Future<[BloodGlucose], Error> { promise in
|
|
|
+ self.processQueue.async {
|
|
|
+ medtronic.fetchNewDataIfNeeded { result in
|
|
|
+ switch result {
|
|
|
+ case .noData:
|
|
|
+ promise(.success([]))
|
|
|
+ case let .newData(glucose):
|
|
|
+ let directions: [BloodGlucose.Direction?] = [nil]
|
|
|
+ + glucose.windows(ofCount: 2).map { window -> BloodGlucose.Direction? in
|
|
|
+ let pair = Array(window)
|
|
|
+ guard pair.count == 2 else { return nil }
|
|
|
+ let firstValue = Int(pair[0].quantity.doubleValue(for: .milligramsPerDeciliter))
|
|
|
+ let secondValue = Int(pair[1].quantity.doubleValue(for: .milligramsPerDeciliter))
|
|
|
+ return .init(trend: secondValue - firstValue)
|
|
|
+ }
|
|
|
+
|
|
|
+ let results = glucose.enumerated().map { index, sample -> BloodGlucose in
|
|
|
+ let value = Int(sample.quantity.doubleValue(for: .milligramsPerDeciliter))
|
|
|
+ return BloodGlucose(
|
|
|
+ _id: sample.syncIdentifier,
|
|
|
+ sgv: value,
|
|
|
+ direction: directions[index],
|
|
|
+ date: Decimal(Int(sample.date.timeIntervalSince1970 * 1000)),
|
|
|
+ dateString: sample.date,
|
|
|
+ unfiltered: nil,
|
|
|
+ filtered: nil,
|
|
|
+ noise: nil,
|
|
|
+ glucose: value,
|
|
|
+ type: "sgv"
|
|
|
+ )
|
|
|
+ }
|
|
|
+ if let lastDate = results.last?.dateString {
|
|
|
+ self.lastFetchGlucoseDate = lastDate
|
|
|
+ }
|
|
|
+
|
|
|
+ promise(.success(results))
|
|
|
+ case let .error(error):
|
|
|
+ warning(.deviceManager, "Fetch minilink glucose failed", error: error)
|
|
|
+ promise(.failure(error))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .timeout(60, scheduler: processQueue, options: nil, customError: nil)
|
|
|
+ .replaceError(with: [])
|
|
|
+ .replaceEmpty(with: [])
|
|
|
+ .eraseToAnyPublisher()
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
extension BaseDeviceDataManager: PumpManagerDelegate {
|