BolusStateModel.swift 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import SwiftUI
  2. import Swinject
  3. extension Bolus {
  4. final class StateModel: BaseStateModel<Provider> {
  5. @Injected() var unlockmanager: UnlockManager!
  6. @Injected() var apsManager: APSManager!
  7. @Injected() var broadcaster: Broadcaster!
  8. @Injected() var pumpHistoryStorage: PumpHistoryStorage!
  9. @Published var amount: Decimal = 0
  10. @Published var insulinRecommended: Decimal = 0
  11. @Published var insulinRequired: Decimal = 0
  12. @Published var waitForSuggestion: Bool = false
  13. @Published var manual: Bool = false
  14. @Published var error: Bool = false
  15. @Published var errorString: String = ""
  16. @Published var evBG: Int = 0
  17. @Published var insulin: Decimal = 0
  18. @Published var target: Decimal = 0
  19. @Published var isf: Decimal = 0
  20. @Published var percentage: Decimal = 0
  21. @Published var units: GlucoseUnits = .mmolL
  22. var waitForSuggestionInitial: Bool = false
  23. override func subscribe() {
  24. setupInsulinRequired()
  25. broadcaster.register(SuggestionObserver.self, observer: self)
  26. units = settingsManager.settings.units
  27. percentage = settingsManager.settings.insulinReqPercentage
  28. if waitForSuggestionInitial {
  29. apsManager.determineBasal()
  30. .receive(on: DispatchQueue.main)
  31. .sink { [weak self] ok in
  32. guard let self = self else { return }
  33. if !ok {
  34. self.waitForSuggestion = false
  35. self.insulinRequired = 0
  36. self.insulinRecommended = 0
  37. }
  38. }.store(in: &lifetime)
  39. }
  40. }
  41. func add() {
  42. guard amount > 0 else {
  43. showModal(for: nil)
  44. return
  45. }
  46. let maxAmount = Double(min(amount, provider.pumpSettings().maxBolus))
  47. unlockmanager.unlock()
  48. .sink { _ in } receiveValue: { [weak self] _ in
  49. guard let self = self else { return }
  50. self.apsManager.enactBolus(amount: maxAmount, isSMB: false)
  51. self.showModal(for: nil)
  52. }
  53. .store(in: &lifetime)
  54. }
  55. func addWithoutBolus() {
  56. guard amount > 0 else {
  57. showModal(for: nil)
  58. return
  59. }
  60. pumpHistoryStorage.storeEvents(
  61. [
  62. PumpHistoryEvent(
  63. id: UUID().uuidString,
  64. type: .bolus,
  65. timestamp: Date(),
  66. amount: amount,
  67. duration: nil,
  68. durationMin: nil,
  69. rate: nil,
  70. temp: nil,
  71. carbInput: nil
  72. )
  73. ]
  74. )
  75. showModal(for: nil)
  76. }
  77. func setupInsulinRequired() {
  78. DispatchQueue.main.async {
  79. self.insulinRequired = self.provider.suggestion?.insulinReq ?? 0
  80. // 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 uses the minPredBG for glucose prediction (typically lower than Eventual BG).
  81. self.evBG = self.provider.suggestion?.eventualBG ?? 0
  82. self.insulin = self.provider.suggestion?.insulinForManualBolus ?? 0
  83. self.target = self.provider.suggestion?.current_target ?? 0
  84. self.isf = self.provider.suggestion?.isf ?? 0
  85. if self.settingsManager.settings.insulinReqPercentage != 100 {
  86. self.insulinRecommended = self.insulin * (self.settingsManager.settings.insulinReqPercentage / 100)
  87. } else { self.insulinRecommended = self.insulin }
  88. self.errorString = self.provider.suggestion?.manualBolusErrorString ?? ""
  89. if self.errorString.count > 8 { self.error = true }
  90. self.insulinRecommended = self.apsManager
  91. .roundBolus(amount: max(self.insulinRecommended, 0))
  92. }
  93. }
  94. }
  95. }
  96. extension Bolus.StateModel: SuggestionObserver {
  97. func suggestionDidUpdate(_: Suggestion) {
  98. DispatchQueue.main.async {
  99. self.waitForSuggestion = false
  100. }
  101. setupInsulinRequired()
  102. }
  103. }