浏览代码

roundBasal and getMaxSafeBasalRate functions

Sam King 9 月之前
父节点
当前提交
dc67ec5c59
共有 2 个文件被更改,包括 70 次插入0 次删除
  1. 4 0
      Trio.xcodeproj/project.pbxproj
  2. 66 0
      Trio/Sources/APS/OpenAPSSwift/DetermineBasal/TempBasalFunctions.swift

+ 4 - 0
Trio.xcodeproj/project.pbxproj

@@ -302,6 +302,7 @@
 		3BA8D1B32DDB87150006191F /* DecimalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BA8D1B22DDB870F0006191F /* DecimalExtensions.swift */; };
 		3BAAE60C2DE7766C0049589B /* DynamicISFEnableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BAAE60B2DE776630049589B /* DynamicISFEnableTests.swift */; };
 		3BAC929B2E55FF5300B853DA /* DetermineBasalEnableSmbTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BAC929A2E55FF4F00B853DA /* DetermineBasalEnableSmbTests.swift */; };
+		3BAC929D2E56A85400B853DA /* TempBasalFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BAC929C2E56A84E00B853DA /* TempBasalFunctions.swift */; };
 		3BAD36B22D7CDC1A00CC298D /* MainLoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BAD36B12D7CDC1400CC298D /* MainLoadingView.swift */; };
 		3BAD36CC2D7D420E00CC298D /* CoreDataInitializationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BAD36CB2D7D420500CC298D /* CoreDataInitializationCoordinator.swift */; };
 		3BAE876E2E47F12900FCA8D2 /* DosingEngine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BAE876D2E47F12900FCA8D2 /* DosingEngine.swift */; };
@@ -1226,6 +1227,7 @@
 		3BA8D1B22DDB870F0006191F /* DecimalExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DecimalExtensions.swift; sourceTree = "<group>"; };
 		3BAAE60B2DE776630049589B /* DynamicISFEnableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicISFEnableTests.swift; sourceTree = "<group>"; };
 		3BAC929A2E55FF4F00B853DA /* DetermineBasalEnableSmbTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetermineBasalEnableSmbTests.swift; sourceTree = "<group>"; };
+		3BAC929C2E56A84E00B853DA /* TempBasalFunctions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TempBasalFunctions.swift; sourceTree = "<group>"; };
 		3BAD36B12D7CDC1400CC298D /* MainLoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainLoadingView.swift; sourceTree = "<group>"; };
 		3BAD36CB2D7D420500CC298D /* CoreDataInitializationCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataInitializationCoordinator.swift; sourceTree = "<group>"; };
 		3BAE876D2E47F12900FCA8D2 /* DosingEngine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DosingEngine.swift; sourceTree = "<group>"; };
@@ -3748,6 +3750,7 @@
 				DD30BA052E07667000DA677C /* DetermineBasal+Helpers.swift */,
 				DD30B9C62E06257300DA677C /* DetermineBasalGenerator.swift */,
 				3BAE876D2E47F12900FCA8D2 /* DosingEngine.swift */,
+				3BAC929C2E56A84E00B853DA /* TempBasalFunctions.swift */,
 			);
 			path = DetermineBasal;
 			sourceTree = "<group>";
@@ -4744,6 +4747,7 @@
 				388358C825EEF6D200E024B2 /* BasalProfileEntry.swift in Sources */,
 				DDA9AC092D672CF100E6F1A9 /* AppVersionChecker.swift in Sources */,
 				3811DE0B25C9D32F00A708ED /* BaseView.swift in Sources */,
+				3BAC929D2E56A85400B853DA /* TempBasalFunctions.swift in Sources */,
 				3811DE3225C9D49500A708ED /* HomeDataFlow.swift in Sources */,
 				DD32CFA22CC824E2003686D6 /* TrioRemoteControl+Helpers.swift in Sources */,
 				CE1856F52ADC4858007E39C7 /* AddCarbPresetIntent.swift in Sources */,

+ 66 - 0
Trio/Sources/APS/OpenAPSSwift/DetermineBasal/TempBasalFunctions.swift

@@ -0,0 +1,66 @@
+import Foundation
+
+enum TempBasalFunctionError: LocalizedError, Equatable {
+    case invalidMaxDailySafetyMultiplier
+    case invalidCurrentBasalSafetyMultiplier
+    case invalidBasalRateOnProfile
+
+    var errorDescription: String? {
+        switch self {
+        case .invalidMaxDailySafetyMultiplier:
+            return "The max daily safety multiplier set on Profile is invalid"
+        case .invalidCurrentBasalSafetyMultiplier:
+            return "The current daily basal safety multiplier set on Profile is invalid"
+        case .invalidBasalRateOnProfile:
+            return "The max currentBasal, maxBasal, or maxDailyBasl wasn't set on Profile"
+        }
+    }
+}
+
+enum TempBasalFunctions {
+    /// Rounds basal rates to match the basal increment for the pump as the basal rate increases
+    static func roundBasal(profile: Profile, basalRate: Decimal) -> Decimal {
+        // FIXME: Should we just call the pumpManager here?
+
+        let lowestRateScale: Decimal
+        if let model = profile.model, model.hasSuffix("54") || model.hasSuffix("23") {
+            lowestRateScale = 40
+        } else {
+            lowestRateScale = 20
+        }
+
+        let roundedBasal: Decimal
+        if basalRate < 1 {
+            roundedBasal = (basalRate * lowestRateScale).jsRounded() / lowestRateScale
+        } else if basalRate < 10 {
+            roundedBasal = (basalRate * 20).jsRounded() / 20
+        } else {
+            roundedBasal = (basalRate * 10).jsRounded() / 10
+        }
+
+        return roundedBasal
+    }
+
+    /// defines the max safe basal rate given a profile
+    static func getMaxSafeBasalRate(profile: Profile) throws -> Decimal {
+        guard !profile.maxDailySafetyMultiplier.isNaN else {
+            throw TempBasalFunctionError.invalidMaxDailySafetyMultiplier
+        }
+
+        guard !profile.currentBasalSafetyMultiplier.isNaN else {
+            throw TempBasalFunctionError.invalidCurrentBasalSafetyMultiplier
+        }
+
+        guard let currentBasal = profile.currentBasal, let maxDailyBasal = profile.maxDailyBasal,
+              let maxBasal = profile.maxBasal
+        else {
+            throw TempBasalFunctionError.invalidBasalRateOnProfile
+        }
+
+        return min(
+            maxBasal,
+            profile.maxDailySafetyMultiplier * maxDailyBasal,
+            profile.currentBasalSafetyMultiplier * currentBasal
+        )
+    }
+}