瀏覽代碼

Merge pull request #612 from nightscout/oref-swift-iob-bug-fix

Fix IoB temp basal duration for split crossing PumpResume event
Sam King 5 月之前
父節點
當前提交
985c9c37ff
共有 2 個文件被更改,包括 58 次插入2 次删除
  1. 1 2
      Trio/Sources/APS/OpenAPSSwift/Iob/IobHistory.swift
  2. 57 0
      TrioTests/OpenAPSSwiftTests/IobHistoryTests.swift

+ 1 - 2
Trio/Sources/APS/OpenAPSSwift/Iob/IobHistory.swift

@@ -261,8 +261,7 @@ struct IobHistory {
             if event.end < firstResumeDate {
                 return event.copyWith(duration: 0)
             } else {
-                let duration = event.duration ?? 0
-                let newDuration = duration - event.end.timeIntervalSince(firstResumeDate).secondsToMinutes
+                let newDuration = event.end.timeIntervalSince(firstResumeDate).secondsToMinutes
                 return event.copyWith(duration: newDuration, timestamp: firstResumeDate)
             }
         }

+ 57 - 0
TrioTests/OpenAPSSwiftTests/IobHistoryTests.swift

@@ -576,4 +576,61 @@ import Testing
 
         #expect(treatments.netInsulin().isWithin(0.01, of: -0.7))
     }
+
+    @Test(
+        "should handle temp basal overlapping resume with prior suspension"
+    ) func handleTempBasalOverlappingResumeWithPriorSuspension() async throws {
+        let basalprofile = createBasicBasalProfile()
+        let now = Calendar.current.startOfDay(for: Date()) + 10.hoursToSeconds // Ensure we are well past 8h ago
+        let resumeTime = now - 30.minutesToSeconds
+
+        // Temp basal starts 10 mins before resume, lasts 40 mins.
+        // So it ends 30 mins after resume.
+        let tempStart = resumeTime - 10.minutesToSeconds
+        let tempDuration = 40
+
+        let pumpHistory = [
+            ComputedPumpHistoryEvent.forTest(
+                type: .pumpResume,
+                timestamp: resumeTime
+            ),
+            ComputedPumpHistoryEvent.forTest(
+                type: .tempBasal,
+                timestamp: tempStart,
+                duration: nil,
+                rate: 2,
+                temp: .absolute
+            ),
+            ComputedPumpHistoryEvent.forTest(
+                type: .tempBasalDuration,
+                timestamp: tempStart,
+                durationMin: tempDuration
+            )
+        ]
+
+        var profile = Profile()
+        profile.dia = 3
+        profile.basalprofile = basalprofile
+        profile.currentBasal = 1
+        profile.maxDailyBasal = 1
+        profile.suspendZerosIob = true
+
+        let treatments = try IobHistory.calcTempTreatments(
+            history: pumpHistory,
+            profile: profile,
+            clock: now,
+            autosens: nil,
+            zeroTempDuration: nil
+        )
+
+        let tempBasals = treatments.filter { $0.type == .tempBasal && $0.rate == 2 }
+
+        #expect(tempBasals.count == 1)
+        if let temp = tempBasals.first {
+            // Should start at resumeTime
+            #expect(temp.timestamp == resumeTime)
+            // Should have duration of 30 minutes
+            #expect(temp.duration == 30)
+        }
+    }
 }