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

Improve the bolus calculator. (#98)

When entering carbs and coming to the bolus recommendation screen, use the EventualBG instead of the minPredBG when computing recommended bolus. Only used when directly combined with carbs. If not everything else is as before.

To not make things overly complicated I'm using this new bolus recommendation for Watch App also, but always, until I find a neat way of collecting the manual state from the BolusStateModel.

For testing. Tested for about a week without any dramatic adverse effects, but needs more testing from more users.
Jon B Mårtensson 2 лет назад
Родитель
Сommit
6edda045d3

+ 1 - 1
Config.xcconfig

@@ -1,5 +1,5 @@
 APP_DISPLAY_NAME = iAPS
-APP_VERSION = 2.1.7
+APP_VERSION = 2.1.8
 APP_BUILD_NUMBER = 1
 COPYRIGHT_NOTICE =
 DEVELOPER_TEAM = ##TEAM_ID##

Разница между файлами не показана из-за своего большого размера
+ 1 - 2
FreeAPS/Resources/javascript/bundle/determine-basal.js


+ 2 - 0
FreeAPS/Sources/Models/Suggestion.swift

@@ -22,6 +22,7 @@ struct Suggestion: JSON, Equatable {
     let tdd: Decimal?
     let insulin: Insulin?
     let current_target: Decimal?
+    let insulinForManualBolus: Decimal?
 }
 
 struct Predictions: JSON, Equatable {
@@ -61,6 +62,7 @@ extension Suggestion {
         case tdd = "TDD"
         case insulin
         case current_target
+        case insulinForManualBolus
     }
 }
 

+ 3 - 1
FreeAPS/Sources/Modules/AddCarbs/AddCarbsStateModel.swift

@@ -16,6 +16,7 @@ extension AddCarbs {
         @Published var dish: String = ""
         @Published var selection: Presets?
         @Published var summation: [String] = []
+        @Published var manualBolus: Bool = false
 
         let coredataContext = CoreDataStack.shared.persistentContainer.viewContext
 
@@ -108,7 +109,8 @@ extension AddCarbs {
                 apsManager.determineBasalSync()
                 showModal(for: nil)
             } else {
-                showModal(for: .bolus(waitForSuggestion: true))
+                manualBolus.toggle()
+                showModal(for: .bolus(waitForSuggestion: true, manualBolus: manualBolus))
             }
         }
 

+ 19 - 5
FreeAPS/Sources/Modules/Bolus/BolusStateModel.swift

@@ -11,6 +11,8 @@ extension Bolus {
         @Published var insulinRecommended: Decimal = 0
         @Published var insulinRequired: Decimal = 0
         @Published var waitForSuggestion: Bool = false
+        @Published var manual: Bool = false
+
         var waitForSuggestionInitial: Bool = false
 
         override func subscribe() {
@@ -74,12 +76,24 @@ extension Bolus {
 
         func setupInsulinRequired() {
             DispatchQueue.main.async {
-                self.insulinRequired = self.provider.suggestion?.insulinReq ?? 0
+                // Manual Bolus recommendation screen after a carb entry (normally) yields a higher amount than the insulin reqiured amount computed for SMBs (auto boluses). Carbs combined with a manual bolus threfore now (test) uses the Eventual BG for glucose prediction, whereas the insulinReg for SMBs (and for manual boluses not combined with a carb entry) uses the minPredBG for glucose prediction (typically lower than Eventual BG).
+
+                if self.manual {
+                    self.insulinRequired = self.provider.suggestion?.insulinForManualBolus ?? 0
+
+                    if self.settingsManager.settings.insulinReqPercentage != 100 {
+                        self.insulinRecommended = self
+                            .insulinRequired * (self.settingsManager.settings.insulinReqPercentage / 100)
+                    } else { self.insulinRecommended = self.insulinRequired }
+
+                } else {
+                    self.insulinRequired = self.provider.suggestion?.insulinReq ?? 0
+                    self.insulinRecommended = self
+                        .insulinRequired * (self.settingsManager.settings.insulinReqPercentage / 100) * 2
+                }
+
                 self.insulinRecommended = self.apsManager
-                    .roundBolus(amount: max(
-                        self.insulinRequired * (self.settingsManager.settings.insulinReqPercentage / 100) * 2,
-                        0
-                    ))
+                    .roundBolus(amount: max(self.insulinRecommended, 0))
             }
         }
     }

+ 47 - 27
FreeAPS/Sources/Modules/Bolus/View/BolusRootView.swift

@@ -5,6 +5,7 @@ extension Bolus {
     struct RootView: BaseView {
         let resolver: Resolver
         let waitForSuggestion: Bool
+        let manualBolus: Bool
         @StateObject var state = StateModel()
         @State private var isAddInsulinAlertPresented = false
 
@@ -17,7 +18,7 @@ extension Bolus {
 
         var body: some View {
             Form {
-                Section(header: Text("Recommendation")) {
+                Section {
                     if state.waitForSuggestion {
                         HStack {
                             Text("Wait please").foregroundColor(.secondary)
@@ -25,35 +26,52 @@ extension Bolus {
                             ActivityIndicator(isAnimating: .constant(true), style: .medium) // fix iOS 15 bug
                         }
                     } else {
-                        HStack {
-                            Text("Insulin required").foregroundColor(.secondary)
-                            Spacer()
-                            Text(
-                                formatter
-                                    .string(from: state.insulinRequired as NSNumber)! +
-                                    NSLocalizedString(" U", comment: "Insulin unit")
-                            ).foregroundColor(.secondary)
-                        }.contentShape(Rectangle())
-                            .onTapGesture {
-                                state.amount = state.insulinRequired
-                            }
-                        HStack {
-                            Text("Insulin recommended")
-                            Spacer()
-                            Text(
-                                formatter
-                                    .string(from: state.insulinRecommended as NSNumber)! +
-                                    NSLocalizedString(" U", comment: "Insulin unit")
-                            ).foregroundColor(.secondary)
-                        }.contentShape(Rectangle())
-                            .onTapGesture {
-                                state.amount = state.insulinRecommended
-                            }
+                        if state.manual {
+                            HStack {
+                                Text("Insulin recommended")
+                                Spacer()
+                                Text(
+                                    formatter
+                                        .string(from: state.insulinRecommended as NSNumber)! +
+                                        NSLocalizedString(" U", comment: "Insulin unit")
+                                ).foregroundColor(.secondary)
+                            }.contentShape(Rectangle())
+                                .onTapGesture {
+                                    state.amount = state.insulinRecommended
+                                }
+                        } else {
+                            HStack {
+                                Text("Insulin required").foregroundColor(.secondary)
+                                Spacer()
+                                Text(
+                                    formatter
+                                        .string(from: state.insulinRequired as NSNumber)! +
+                                        NSLocalizedString(" U", comment: "Insulin unit")
+                                ).foregroundColor(.secondary)
+                            }.contentShape(Rectangle())
+                                .onTapGesture {
+                                    state.amount = state.insulinRequired
+                                }
+
+                            HStack {
+                                Text("Insulin recommended")
+                                Spacer()
+                                Text(
+                                    formatter
+                                        .string(from: state.insulinRecommended as NSNumber)! +
+                                        NSLocalizedString(" U", comment: "Insulin unit")
+                                ).foregroundColor(.secondary)
+                            }.contentShape(Rectangle())
+                                .onTapGesture {
+                                    state.amount = state.insulinRecommended
+                                }
+                        }
                     }
                 }
-
+                header: { Text("Recommendation") }
+                
                 if !state.waitForSuggestion {
-                    Section(header: Text("Bolus")) {
+                    Section {
                         HStack {
                             Text("Amount")
                             Spacer()
@@ -67,6 +85,7 @@ extension Bolus {
                             Text("U").foregroundColor(.secondary)
                         }
                     }
+                    header: { Text("Bolus") }
 
                     Section {
                         Button { state.add() }
@@ -103,6 +122,7 @@ extension Bolus {
                 configureView {
                     state.waitForSuggestionInitial = waitForSuggestion
                     state.waitForSuggestion = waitForSuggestion
+                    state.manual = manualBolus
                 }
             }
             .navigationTitle("Enact Bolus")

+ 1 - 1
FreeAPS/Sources/Modules/Home/View/HomeRootView.swift

@@ -502,7 +502,7 @@ extension Home {
                             .padding(8)
                     }.foregroundColor(.loopGreen)
                     Spacer()
-                    Button { state.showModal(for: .bolus(waitForSuggestion: false)) }
+                    Button { state.showModal(for: .bolus(waitForSuggestion: false, manualBolus: false)) }
                     label: {
                         Image("bolus")
                             .renderingMode(.template)

+ 0 - 6
FreeAPS/Sources/Modules/Stat/View/ChartsView.swift

@@ -1,9 +1,3 @@
-//
-//  FilteredLoopsView.swift
-//  FreeAPS
-//
-//  Created by Jon Mårtensson on 2023-05-29.
-//
 import Charts
 import CoreData
 import SwiftDate

+ 0 - 6
FreeAPS/Sources/Modules/Stat/View/StatsView.swift

@@ -1,9 +1,3 @@
-//
-//  FilteredLoopsView.swift
-//  FreeAPS
-//
-//  Created by Jon Mårtensson on 2023-05-29.
-//
 import CoreData
 import SwiftDate
 import SwiftUI

+ 3 - 3
FreeAPS/Sources/Router/Screen.swift

@@ -16,7 +16,7 @@ enum Screen: Identifiable, Hashable {
     case preferencesEditor
     case addCarbs
     case addTempTarget
-    case bolus(waitForSuggestion: Bool)
+    case bolus(waitForSuggestion: Bool, manualBolus: Bool)
     case manualTempBasal
     case autotuneConfig
     case dataTable
@@ -67,8 +67,8 @@ extension Screen {
             AddCarbs.RootView(resolver: resolver)
         case .addTempTarget:
             AddTempTarget.RootView(resolver: resolver)
-        case let .bolus(waitForSuggestion):
-            Bolus.RootView(resolver: resolver, waitForSuggestion: waitForSuggestion)
+        case let .bolus(waitForSuggestion, manualBolus):
+            Bolus.RootView(resolver: resolver, waitForSuggestion: waitForSuggestion, manualBolus: manualBolus)
         case .manualTempBasal:
             ManualTempBasal.RootView(resolver: resolver)
         case .autotuneConfig:

+ 8 - 2
FreeAPS/Sources/Services/WatchManager/WatchManager.swift

@@ -75,9 +75,15 @@ final class BaseWatchManager: NSObject, WatchManager, Injectable {
             self.state.maxBolus = self.settingsManager.pumpSettings.maxBolus
             self.state.carbsRequired = self.suggestion?.carbsReq
 
-            let insulinRequired = self.suggestion?.insulinReq ?? 0
+            var insulinRequired = self.suggestion?.insulinReq ?? 0
+            var double: Decimal = 2
+            if (self.suggestion?.cob ?? 0) > 0 {
+                insulinRequired = self.suggestion?.insulinForManualBolus ?? 0
+                double = 1
+            }
+
             self.state.bolusRecommended = self.apsManager
-                .roundBolus(amount: max(insulinRequired * (self.settingsManager.settings.insulinReqPercentage / 100) * 2, 0))
+                .roundBolus(amount: max(insulinRequired * (self.settingsManager.settings.insulinReqPercentage / 100) * double, 0))
 
             self.state.iob = self.suggestion?.iob
             self.state.cob = self.suggestion?.cob