Skip to content

Commit 882cbff

Browse files
committed
Merge commit '7b234dba046ac6ef554bf3cb115e501d53a14347'
Conflicts: Loop.xcodeproj/project.pbxproj
2 parents e71e7ae + 7b234db commit 882cbff

12 files changed

+2276
-71
lines changed

Loop.xcodeproj/project.pbxproj

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,10 @@
405405
C11BD0552523CFED00236B08 /* SimpleBolusViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C11BD0542523CFED00236B08 /* SimpleBolusViewModel.swift */; };
406406
C1201E2C23ECDBD0002DA84A /* WatchContextRequestUserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1201E2B23ECDBD0002DA84A /* WatchContextRequestUserInfo.swift */; };
407407
C1201E2D23ECDF3D002DA84A /* WatchContextRequestUserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1201E2B23ECDBD0002DA84A /* WatchContextRequestUserInfo.swift */; };
408+
C13072BA2A76AF31009A7C58 /* live_capture_predicted_glucose.json in Resources */ = {isa = PBXBuildFile; fileRef = C13072B92A76AF31009A7C58 /* live_capture_predicted_glucose.json */; };
409+
C13072BE2A76AF97009A7C58 /* live_capture_doses.json in Resources */ = {isa = PBXBuildFile; fileRef = C13072BD2A76AF97009A7C58 /* live_capture_doses.json */; };
410+
C13072C02A76B041009A7C58 /* live_capture_carb_entries.json in Resources */ = {isa = PBXBuildFile; fileRef = C13072BF2A76B041009A7C58 /* live_capture_carb_entries.json */; };
411+
C13072C42A76B0B1009A7C58 /* live_capture_historic_glucose.json in Resources */ = {isa = PBXBuildFile; fileRef = C13072C32A76B0B1009A7C58 /* live_capture_historic_glucose.json */; };
408412
C13255D6223E7BE2008AF50C /* BolusProgressTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C1F8B1DB223862D500DD66CF /* BolusProgressTableViewCell.xib */; };
409413
C13DA2B024F6C7690098BB29 /* UIViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C13DA2AF24F6C7690098BB29 /* UIViewController.swift */; };
410414
C148CEE724FD91BD00711B3B /* DeliveryUncertaintyAlertManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C148CEE624FD91BD00711B3B /* DeliveryUncertaintyAlertManager.swift */; };
@@ -1400,6 +1404,10 @@
14001404
C12CB9B423106A6100F84978 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Intents.strings; sourceTree = "<group>"; };
14011405
C12CB9B623106A6200F84978 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Intents.strings; sourceTree = "<group>"; };
14021406
C12CB9B823106A6300F84978 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Intents.strings; sourceTree = "<group>"; };
1407+
C13072B92A76AF31009A7C58 /* live_capture_predicted_glucose.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = live_capture_predicted_glucose.json; sourceTree = "<group>"; };
1408+
C13072BD2A76AF97009A7C58 /* live_capture_doses.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = live_capture_doses.json; sourceTree = "<group>"; };
1409+
C13072BF2A76B041009A7C58 /* live_capture_carb_entries.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = live_capture_carb_entries.json; sourceTree = "<group>"; };
1410+
C13072C32A76B0B1009A7C58 /* live_capture_historic_glucose.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = live_capture_historic_glucose.json; sourceTree = "<group>"; };
14031411
C13DA2AF24F6C7690098BB29 /* UIViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewController.swift; sourceTree = "<group>"; };
14041412
C148CEE624FD91BD00711B3B /* DeliveryUncertaintyAlertManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeliveryUncertaintyAlertManager.swift; sourceTree = "<group>"; };
14051413
C14952142995822A0095AA84 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = "<group>"; };
@@ -1829,7 +1837,6 @@
18291837
isa = PBXGroup;
18301838
children = (
18311839
1DA7A84024476E98008257F0 /* Alerts */,
1832-
E950CA9429002E4B00B5B692 /* LoopDataManager */,
18331840
C16575722538AFF6004AE16E /* CGMStalenessMonitorTests.swift */,
18341841
A91E4C2224F86F1000BE9213 /* CriticalEventLogExportManagerTests.swift */,
18351842
C16B983F26B4898800256B05 /* DoseEnactorTests.swift */,
@@ -2720,6 +2727,17 @@
27202727
path = LoopCore;
27212728
sourceTree = "<group>";
27222729
};
2730+
C13072B82A76AF0A009A7C58 /* live_capture */ = {
2731+
isa = PBXGroup;
2732+
children = (
2733+
C13072B92A76AF31009A7C58 /* live_capture_predicted_glucose.json */,
2734+
C13072BD2A76AF97009A7C58 /* live_capture_doses.json */,
2735+
C13072BF2A76B041009A7C58 /* live_capture_carb_entries.json */,
2736+
C13072C32A76B0B1009A7C58 /* live_capture_historic_glucose.json */,
2737+
);
2738+
path = live_capture;
2739+
sourceTree = "<group>";
2740+
};
27232741
C16DA84022E8E104008624C2 /* Plugins */ = {
27242742
isa = PBXGroup;
27252743
children = (
@@ -2826,13 +2844,6 @@
28262844
path = high_and_stable;
28272845
sourceTree = "<group>";
28282846
};
2829-
E950CA9429002E4B00B5B692 /* LoopDataManager */ = {
2830-
isa = PBXGroup;
2831-
children = (
2832-
);
2833-
path = LoopDataManager;
2834-
sourceTree = "<group>";
2835-
};
28362847
E95D37FF24EADE68005E2F50 /* Store Protocols */ = {
28372848
isa = PBXGroup;
28382849
children = (
@@ -2883,6 +2894,7 @@
28832894
E9C58A7624DB510500487A17 /* Fixtures */ = {
28842895
isa = PBXGroup;
28852896
children = (
2897+
C13072B82A76AF0A009A7C58 /* live_capture */,
28862898
E9B355312937068A0076AB04 /* meal_detection */,
28872899
E90909EC24E35B3400F963D2 /* high_and_falling */,
28882900
E90909E124E352C300F963D2 /* low_with_low_treatment */,
@@ -3372,7 +3384,9 @@
33723384
buildActionMask = 2147483647;
33733385
files = (
33743386
E93E86CE24E2E02200FF40C8 /* high_and_stable_momentum_effect.json in Resources */,
3387+
C13072BA2A76AF31009A7C58 /* live_capture_predicted_glucose.json in Resources */,
33753388
E93E865424DB6CBA00FF40C8 /* retrospective_output.json in Resources */,
3389+
C13072BE2A76AF97009A7C58 /* live_capture_doses.json in Resources */,
33763390
E9C58A7F24DB529A00487A17 /* counteraction_effect_falling_glucose.json in Resources */,
33773391
E93E865624DB731900FF40C8 /* predicted_glucose_without_retrospective.json in Resources */,
33783392
E9B3553D293706CB0076AB04 /* long_interval_counteraction_effect.json in Resources */,
@@ -3385,6 +3399,7 @@
33853399
E90909D224E34AC500F963D2 /* high_and_rising_with_cob_insulin_effect.json in Resources */,
33863400
E90909F224E35B4D00F963D2 /* high_and_falling_counteraction_effect.json in Resources */,
33873401
E90909EE24E35B4000F963D2 /* high_and_falling_predicted_glucose.json in Resources */,
3402+
C13072C02A76B041009A7C58 /* live_capture_carb_entries.json in Resources */,
33883403
E90909DD24E34F1600F963D2 /* low_and_falling_carb_effect.json in Resources */,
33893404
E90909E924E3530200F963D2 /* low_with_low_treatment_predicted_glucose.json in Resources */,
33903405
E90909D124E34AC500F963D2 /* high_and_rising_with_cob_momentum_effect.json in Resources */,
@@ -3410,6 +3425,7 @@
34103425
E93E86C324E1FE6100FF40C8 /* flat_and_stable_counteraction_effect.json in Resources */,
34113426
E9C58A7E24DB529A00487A17 /* dynamic_glucose_effect_partially_observed.json in Resources */,
34123427
E90909F324E35B4D00F963D2 /* high_and_falling_carb_effect.json in Resources */,
3428+
C13072C42A76B0B1009A7C58 /* live_capture_historic_glucose.json in Resources */,
34133429
E93E86CA24E2E02200FF40C8 /* high_and_stable_insulin_effect.json in Resources */,
34143430
E93E86BB24E1FDC400FF40C8 /* flat_and_stable_momentum_effect.json in Resources */,
34153431
E93E86CB24E2E02200FF40C8 /* high_and_stable_carb_effect.json in Resources */,

Loop/Managers/DeviceDataManager.swift

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ final class DeviceDataManager {
4545

4646
@Published var pumpIsAllowingAutomation: Bool
4747

48+
private var lastCGMLoopTrigger: Date = .distantPast
49+
4850
private let automaticDosingStatus: AutomaticDosingStatus
4951

5052
var closedLoopDisallowedLocalizedDescription: String? {
@@ -557,7 +559,6 @@ final class DeviceDataManager {
557559
private func processCGMReadingResult(_ manager: CGMManager, readingResult: CGMReadingResult, completion: @escaping () -> Void) {
558560
switch readingResult {
559561
case .newData(let values):
560-
log.default("CGMManager:%{public}@ did update with %d values", String(describing: type(of: manager)), values.count)
561562
loopManager.addGlucoseSamples(values) { result in
562563
if !values.isEmpty {
563564
DispatchQueue.main.async {
@@ -570,10 +571,8 @@ final class DeviceDataManager {
570571
loopManager.receivedUnreliableCGMReading()
571572
completion()
572573
case .noData:
573-
log.default("CGMManager:%{public}@ did update with no data", String(describing: type(of: manager)))
574574
completion()
575575
case .error(let error):
576-
log.default("CGMManager:%{public}@ did update with error: %{public}@", String(describing: type(of: manager)), String(describing: error))
577576
self.setLastError(error: error)
578577
completion()
579578
}
@@ -924,8 +923,14 @@ extension DeviceDataManager: CGMManagerDelegate {
924923

925924
func cgmManager(_ manager: CGMManager, hasNew readingResult: CGMReadingResult) {
926925
dispatchPrecondition(condition: .onQueue(queue))
926+
log.default("CGMManager:%{public}@ did update with %{public}@", String(describing: type(of: manager)), String(describing: readingResult))
927927
processCGMReadingResult(manager, readingResult: readingResult) {
928-
self.checkPumpDataAndLoop()
928+
let now = Date()
929+
if case .newData = readingResult, now.timeIntervalSince(self.lastCGMLoopTrigger) > .minutes(4.2) {
930+
self.log.default("Triggering loop from new CGM data at %{public}@", String(describing: now))
931+
self.lastCGMLoopTrigger = now
932+
self.checkPumpDataAndLoop()
933+
}
929934
}
930935
}
931936

@@ -1012,7 +1017,8 @@ extension DeviceDataManager: PumpManagerDelegate {
10121017

10131018
self.queue.async {
10141019
self.processCGMReadingResult(cgmManager, readingResult: result) {
1015-
if self.loopManager.lastLoopCompleted == nil || self.loopManager.lastLoopCompleted!.timeIntervalSinceNow < -.minutes(6) {
1020+
if self.loopManager.lastLoopCompleted == nil || self.loopManager.lastLoopCompleted!.timeIntervalSinceNow < -.minutes(4.2) {
1021+
self.log.default("Triggering Loop from refreshCGM()")
10161022
self.checkPumpDataAndLoop()
10171023
}
10181024
completion?()

Loop/Managers/LoopDataManager.swift

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ final class LoopDataManager {
2727
case loopFinished
2828
}
2929

30+
let loopLock = UnfairLock()
31+
3032
static let LoopUpdateContextKey = "com.loudnate.Loop.LoopDataManager.LoopUpdateContext"
3133

3234
private let carbStore: CarbStoreProtocol
@@ -840,7 +842,23 @@ extension LoopDataManager {
840842
///
841843
/// Executes an analysis of the current data, and recommends an adjustment to the current
842844
/// temporary basal rate.
845+
///
843846
func loop() {
847+
848+
if let lastLoopCompleted, Date().timeIntervalSince(lastLoopCompleted) < .minutes(2) {
849+
print("Looping too fast!")
850+
}
851+
852+
let available = loopLock.withLockIfAvailable {
853+
loopInternal()
854+
return true
855+
}
856+
if available == nil {
857+
print("Loop attempted while already looping!")
858+
}
859+
}
860+
861+
func loopInternal() {
844862

845863
dataAccessQueue.async {
846864

@@ -1347,14 +1365,15 @@ extension LoopDataManager {
13471365
let retrospectiveStart = glucose.date.addingTimeInterval(-type(of: retrospectiveCorrection).retrospectionInterval)
13481366
let earliestEffectDate = Date(timeInterval: .hours(-24), since: now())
13491367
let nextEffectDate = insulinCounteractionEffects.last?.endDate ?? earliestEffectDate
1368+
let insulinEffectStartDate = nextEffectDate.addingTimeInterval(.minutes(-5))
13501369

13511370
let updateGroup = DispatchGroup()
13521371
let effectCalculationError = Locked<Error?>(nil)
13531372

13541373
var insulinEffect: [GlucoseEffect]?
13551374
let basalDosingEnd = includingPendingInsulin ? nil : now()
13561375
updateGroup.enter()
1357-
doseStore.getGlucoseEffects(start: nextEffectDate, end: nil, basalDosingEnd: basalDosingEnd) { result in
1376+
doseStore.getGlucoseEffects(start: insulinEffectStartDate, end: nil, basalDosingEnd: basalDosingEnd) { result in
13581377
switch result {
13591378
case .failure(let error):
13601379
effectCalculationError.mutate { $0 = error }
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[
2+
{
3+
"startDate": "2023-07-29T18:17:07Z",
4+
"quantity": 50
5+
}
6+
]

0 commit comments

Comments
 (0)