| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- import CGMBLEKit
- import Combine
- import Foundation
- final class DexcomSource: GlucoseSource {
- private let processQueue = DispatchQueue(label: "DexcomSource.processQueue")
- private let dexcomManager = TransmitterManager(
- state: TransmitterManagerState(transmitterID: UserDefaults.standard.dexcomTransmitterID ?? "8MBPEY")
- )
- private var promise: Future<[BloodGlucose], Error>.Promise?
- init() {
- dexcomManager.delegate = self
- }
- var transmitterID: String {
- dexcomManager.transmitter.ID
- }
- func fetch() -> AnyPublisher<[BloodGlucose], Never> {
- dexcomManager.transmitter.resumeScanning()
- return Future<[BloodGlucose], Error> { [weak self] promise in
- self?.promise = promise
- }
- .timeout(60, scheduler: processQueue, options: nil, customError: nil)
- .replaceError(with: [])
- .eraseToAnyPublisher()
- }
- deinit {
- dexcomManager.transmitter.stopScanning()
- }
- }
- extension DexcomSource: TransmitterManagerDelegate {
- func transmitterManager(_: TransmitterManager, didFailWith error: Error) {
- promise?(.failure(error))
- }
- func transmitterManager(_: TransmitterManager, didRead glucose: [CGMBLEKit.Glucose]) {
- let bloodGlucose = glucose.compactMap { glucose -> BloodGlucose? in
- guard let quantity = glucose.glucose else {
- return nil
- }
- let value = Int(quantity.doubleValue(for: .milligramsPerDeciliter))
- return BloodGlucose(
- sgv: value,
- direction: .init(trend: glucose.trend),
- date: Decimal(Int(glucose.readDate.timeIntervalSince1970 * 1000)),
- dateString: glucose.readDate,
- filtered: nil,
- noise: nil,
- glucose: value
- )
- }
- promise?(.success(bloodGlucose))
- }
- }
- extension BloodGlucose.Direction {
- init(trend: Int) {
- guard trend < Int(Int8.max) else {
- self = .none
- return
- }
- switch trend {
- case let x where x <= -30:
- self = .doubleDown
- case let x where x <= -20:
- self = .singleDown
- case let x where x <= -10:
- self = .fortyFiveDown
- case let x where x < 10:
- self = .flat
- case let x where x < 20:
- self = .fortyFiveUp
- case let x where x < 30:
- self = .singleUp
- default:
- self = .doubleUp
- }
- }
- }
|