Просмотр исходного кода

Use allowed basal rates via LoopKit device manager

Deniz Cengiz 1 год назад
Родитель
Сommit
4dac937289
2 измененных файлов с 32 добавлено и 14 удалено
  1. 10 2
      FreeAPS/Sources/APS/APSManager.swift
  2. 22 12
      FreeAPS/Sources/APS/Storage/TDDStorage.swift

+ 10 - 2
FreeAPS/Sources/APS/APSManager.swift

@@ -354,16 +354,24 @@ final class BaseAPSManager: APSManager, Injectable {
 
     /// Calculates and stores the Total Daily Dose (TDD)
     private func calculateAndStoreTDD() async {
+        guard let pumpManager else { return }
+
         // Get required data
         let pumpHistory = await pumpHistoryStorage.getPumpHistory()
         let basalProfile = await storage
             .retrieveAsync(OpenAPS.Settings.basalProfile, as: [BasalProfileEntry].self) ??
-            [BasalProfileEntry](from: OpenAPS.defaults(for: OpenAPS.Settings.basalProfile)) ?? [] // OpenAPS.defaults ensures we at least get default rate of 1u/hr for 24 hrs
+            [BasalProfileEntry](from: OpenAPS.defaults(for: OpenAPS.Settings.basalProfile)) ??
+            [] // OpenAPS.defaults ensures we at least get default rate of 1u/hr for 24 hrs
+
+        let basalIncrements = pumpManager.supportedBasalRates
 
         // Calculate TDD
         let tddResult = await tddStorage.calculateTDD(
             pumpHistory: pumpHistory,
-            basalProfile: basalProfile
+            basalProfile: basalProfile,
+            basalIncrement: Decimal(
+                basalIncrements.first(where: { $0 > 0.0 }) ?? 0.05
+            ) // supportedBasalRates must be non-empty, so we could force-unwrap here… but apparently sim-pump does not like that?!
         )
 
         // TODO: Move this to storage as well

+ 22 - 12
FreeAPS/Sources/APS/Storage/TDDStorage.swift

@@ -2,7 +2,8 @@ import Foundation
 import Swinject
 
 protocol TDDStorage {
-    func calculateTDD(pumpHistory: [PumpHistoryEvent], basalProfile: [BasalProfileEntry]) async -> TDDResult
+    func calculateTDD(pumpHistory: [PumpHistoryEvent], basalProfile: [BasalProfileEntry], basalIncrement: Decimal) async
+        -> TDDResult
 }
 
 /// Structure containing the results of TDD calculations
@@ -26,7 +27,11 @@ final class BaseTDDStorage: TDDStorage, Injectable {
     ///   - pumpHistory: Array of pump history events
     ///   - basalProfile: Array of basal profile entries
     /// - Returns: TDDResult containing all calculated values
-    func calculateTDD(pumpHistory: [PumpHistoryEvent], basalProfile: [BasalProfileEntry]) async -> TDDResult {
+    func calculateTDD(
+        pumpHistory: [PumpHistoryEvent],
+        basalProfile: [BasalProfileEntry],
+        basalIncrement: Decimal
+    ) async -> TDDResult {
         debug(.apsManager, "Starting TDD calculation with \(pumpHistory.count) pump events")
 
         var bolusInsulin: Decimal = 0
@@ -45,7 +50,8 @@ final class BaseTDDStorage: TDDStorage, Injectable {
                 scheduledBasalInsulin = calculateScheduledBasalInsulin(
                     from: calculatedGapStart,
                     to: endDate,
-                    basalProfile: basalProfile
+                    basalProfile: basalProfile,
+                    basalIncrement: basalIncrement
                 )
                 debug(.apsManager, "Added scheduled basal insulin: \(scheduledBasalInsulin)U")
             }
@@ -54,7 +60,7 @@ final class BaseTDDStorage: TDDStorage, Injectable {
         bolusInsulin = calculateBolusInsulin(pumpHistory)
         debug(.apsManager, "Total bolus insulin: \(bolusInsulin)U")
 
-        tempInsulin = calculateTempBasalInsulin(pumpHistory)
+        tempInsulin = calculateTempBasalInsulin(pumpHistory, basalIncrement: basalIncrement)
         debug(.apsManager, "Total temp basal insulin: \(tempInsulin)U")
 
         let total = bolusInsulin + tempInsulin + scheduledBasalInsulin
@@ -115,7 +121,7 @@ final class BaseTDDStorage: TDDStorage, Injectable {
     /// Calculates insulin delivered via temporary basal rates
     /// - Parameter pumpHistory: Array of pump history events
     /// - Returns: Total temporary basal insulin
-    private func calculateTempBasalInsulin(_ pumpHistory: [PumpHistoryEvent]) -> Decimal {
+    private func calculateTempBasalInsulin(_ pumpHistory: [PumpHistoryEvent], basalIncrement: Decimal) -> Decimal {
         var totalInsulin: Decimal = 0
 
         for (index, event) in pumpHistory.enumerated() {
@@ -125,7 +131,7 @@ final class BaseTDDStorage: TDDStorage, Injectable {
                   index > 0 else { continue }
 
             let duration = Decimal(pumpHistory[index - 1].duration ?? 0) / 60 // Convert to hours
-            let insulin = accountForIncrements(rate * duration)
+            let insulin = accountForIncrements(rate * duration, basalIncrement: basalIncrement)
             totalInsulin += insulin
 
             debug(.apsManager, "Temp basal: \(rate)U/hr for \(duration)hr = \(insulin)U")
@@ -140,7 +146,12 @@ final class BaseTDDStorage: TDDStorage, Injectable {
     ///   - to: End date
     ///   - basalProfile: Array of basal profile entries
     /// - Returns: Total scheduled basal insulin
-    private func calculateScheduledBasalInsulin(from: Date, to: Date, basalProfile: [BasalProfileEntry]) -> Decimal {
+    private func calculateScheduledBasalInsulin(
+        from: Date,
+        to: Date,
+        basalProfile: [BasalProfileEntry],
+        basalIncrement: Decimal
+    ) -> Decimal {
         var totalInsulin: Decimal = 0
         var currentDate = from
 
@@ -151,7 +162,7 @@ final class BaseTDDStorage: TDDStorage, Injectable {
             let nextScheduleTime = findNextScheduleTime(after: timeString, in: basalProfile)
             let durationInHours = calculateDuration(currentTime: timeString, nextScheduleTime: nextScheduleTime, endDate: to)
 
-            let insulin = accountForIncrements(basalRate * Decimal(durationInHours))
+            let insulin = accountForIncrements(basalRate * Decimal(durationInHours), basalIncrement: basalIncrement)
             totalInsulin += insulin
 
             currentDate = currentDate.addingTimeInterval(durationInHours * 3600)
@@ -163,9 +174,8 @@ final class BaseTDDStorage: TDDStorage, Injectable {
     /// Rounds insulin amounts according to pump increment constraints
     /// - Parameter insulin: Raw insulin amount
     /// - Returns: Rounded insulin amount
-    private func accountForIncrements(_ insulin: Decimal) -> Decimal {
-        let minimalDose: Decimal = 0.05 // For Omnipod, 0.1 for other pumps
-        let incrementsRaw = insulin / minimalDose
+    private func accountForIncrements(_ insulin: Decimal, basalIncrement: Decimal) -> Decimal {
+        let incrementsRaw = insulin / basalIncrement
 
         if incrementsRaw >= 1 {
             // Convert to NSDecimalNumber to use its rounding capabilities
@@ -181,7 +191,7 @@ final class BaseTDDStorage: TDDStorage, Injectable {
                     raiseOnDivideByZero: false
                 )
             )
-            return (roundedIncrements.decimalValue * minimalDose).rounded(toPlaces: 3)
+            return (roundedIncrements.decimalValue * basalIncrement).rounded(toPlaces: 3)
         }
         return 0
     }