Skip to content

Commit

Permalink
Fix the dexcom share in Trio
Browse files Browse the repository at this point in the history
The PR allows to fecth BG of Dexcom share as a CGM as well as to fetch BG of Dexcom share with the Dexcom G6 CGM.

The PR changes the logic of the CGM for all CGM based on Loop submodules (PluginSource).
  • Loading branch information
avouspierre committed Jun 8, 2024
1 parent aeb4ee1 commit 61ec999
Showing 1 changed file with 38 additions and 22 deletions.
60 changes: 38 additions & 22 deletions FreeAPS/Sources/APS/CGM/PluginSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,26 @@ final class PluginSource: GlucoseSource {
cgmManager?.cgmManagerDelegate = self
}

/// Function that fetches blood glucose data
/// This function combines two data fetching mechanisms (`callBLEFetch` and `fetchIfNeeded`) into a single publisher.
/// It returns the first non-empty result from either of the sources within a 5-minute timeout period.
/// If no valid data is fetched within the timeout, it returns an empty array.
///
/// - Parameter timer: An optional `DispatchTimer` (not used in the function but can be used to trigger fetch logic).
/// - Returns: An `AnyPublisher` that emits an array of `BloodGlucose` values or an empty array if an error occurs or the timeout is reached.
func fetch(_: DispatchTimer?) -> AnyPublisher<[BloodGlucose], Never> {
Publishers.Merge(
callBLEFetch(),
fetchIfNeeded()
)
.filter { !$0.isEmpty }
.first()
.timeout(60 * 5, scheduler: processQueue, options: nil, customError: nil)
.replaceError(with: [])
.eraseToAnyPublisher()
}

func callBLEFetch() -> AnyPublisher<[BloodGlucose], Never> {
Future<[BloodGlucose], Error> { [weak self] promise in
self?.promise = promise
}
Expand All @@ -35,17 +54,15 @@ final class PluginSource: GlucoseSource {
}

func fetchIfNeeded() -> AnyPublisher<[BloodGlucose], Never> {
Future<[BloodGlucose], Error> { _ in
Future<[BloodGlucose], Error> { [weak self] promise in
guard let self = self else { return }
self.processQueue.async {
guard let cgmManager = self.cgmManager else { return }
cgmManager.fetchNewDataIfNeeded { result in
self.processCGMReadingResult(cgmManager, readingResult: result) {
// nothing to do
}
promise(self.readCGMResult(readingResult: result))
}
}
}
.timeout(60, scheduler: processQueue, options: nil, customError: nil)
.replaceError(with: [])
.replaceEmpty(with: [])
.eraseToAnyPublisher()
Expand Down Expand Up @@ -92,11 +109,10 @@ extension PluginSource: CGMManagerDelegate {
glucoseManager?.cgmGlucoseSourceType = .none
}

func cgmManager(_ manager: CGMManager, hasNew readingResult: CGMReadingResult) {
func cgmManager(_: CGMManager, hasNew readingResult: CGMReadingResult) {
dispatchPrecondition(condition: .onQueue(processQueue))
processCGMReadingResult(manager, readingResult: readingResult) {
debug(.deviceManager, "CGM PLUGIN - Direct return done")
}
promise?(readCGMResult(readingResult: readingResult))
debug(.deviceManager, "CGM PLUGIN - Direct return done")
}

func cgmManager(_: LoopKit.CGMManager, hasNew events: [LoopKit.PersistedCgmEvent]) {
Expand Down Expand Up @@ -140,11 +156,7 @@ extension PluginSource: CGMManagerDelegate {
}
}

private func processCGMReadingResult(
_: CGMManager,
readingResult: CGMReadingResult,
completion: @escaping () -> Void
) {
private func readCGMResult(readingResult: CGMReadingResult) -> Result<[BloodGlucose], Error> {
debug(.deviceManager, "PLUGIN CGM - Process CGM Reading Result launched with \(readingResult)")
switch readingResult {
case let .newData(values):
Expand Down Expand Up @@ -177,20 +189,24 @@ extension PluginSource: CGMManagerDelegate {
transmitterID: sensorTransmitterID
)
}
promise?(.success(bloodGlucose))
completion()
return .success(bloodGlucose)
case .unreliableData:
// loopManager.receivedUnreliableCGMReading()
promise?(.failure(GlucoseDataError.unreliableData))
completion()
return .failure(GlucoseDataError.unreliableData)
case .noData:
promise?(.failure(GlucoseDataError.noData))
completion()
return .failure(GlucoseDataError.noData)
case let .error(error):
promise?(.failure(error))
completion()
return .failure(error)
}
}

private func processCGMReadingResultCompletion(
_: CGMManager,
readingResult: CGMReadingResult,
completion: @escaping (Result<[BloodGlucose], Error>) -> Void
) {
completion(readCGMResult(readingResult: readingResult))
}
}

extension PluginSource {
Expand Down

0 comments on commit 61ec999

Please sign in to comment.