TherapySettingsViewModel.swift 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. //
  2. // TherapySettingsViewModel.swift
  3. // LoopKitUI
  4. //
  5. // Created by Rick Pasetto on 7/13/20.
  6. // Copyright © 2020 LoopKit Authors. All rights reserved.
  7. //
  8. import Combine
  9. import LoopKit
  10. import HealthKit
  11. import SwiftUI
  12. public protocol TherapySettingsViewModelDelegate: AnyObject {
  13. func syncBasalRateSchedule(items: [RepeatingScheduleValue<Double>], completion: @escaping (Result<BasalRateSchedule, Error>) -> Void)
  14. func syncDeliveryLimits(deliveryLimits: DeliveryLimits, completion: @escaping (Result<DeliveryLimits, Error>) -> Void)
  15. func saveCompletion(for therapySetting: TherapySetting, therapySettings: TherapySettings)
  16. func pumpSupportedIncrements() -> PumpSupportedIncrements?
  17. }
  18. public class TherapySettingsViewModel: ObservableObject {
  19. @Published public var therapySettings: TherapySettings
  20. private let initialTherapySettings: TherapySettings
  21. let sensitivityOverridesEnabled: Bool
  22. public var prescription: Prescription?
  23. private weak var delegate: TherapySettingsViewModelDelegate?
  24. public init(therapySettings: TherapySettings,
  25. pumpSupportedIncrements: (() -> PumpSupportedIncrements?)? = nil,
  26. sensitivityOverridesEnabled: Bool = false,
  27. prescription: Prescription? = nil,
  28. delegate: TherapySettingsViewModelDelegate? = nil) {
  29. self.therapySettings = therapySettings
  30. self.initialTherapySettings = therapySettings
  31. self.sensitivityOverridesEnabled = sensitivityOverridesEnabled
  32. self.prescription = prescription
  33. self.delegate = delegate
  34. }
  35. var deliveryLimits: DeliveryLimits {
  36. return DeliveryLimits(maximumBasalRate: therapySettings.maximumBasalRatePerHour.map { HKQuantity(unit: .internationalUnitsPerHour, doubleValue: $0) },
  37. maximumBolus: therapySettings.maximumBolus.map { HKQuantity(unit: .internationalUnit(), doubleValue: $0) } )
  38. }
  39. var suspendThreshold: GlucoseThreshold? {
  40. return therapySettings.suspendThreshold
  41. }
  42. var glucoseTargetRangeSchedule: GlucoseRangeSchedule? {
  43. return therapySettings.glucoseTargetRangeSchedule
  44. }
  45. func glucoseTargetRangeSchedule(for glucoseUnit: HKUnit) -> GlucoseRangeSchedule? {
  46. return glucoseTargetRangeSchedule?.schedule(for: glucoseUnit)
  47. }
  48. var correctionRangeOverrides: CorrectionRangeOverrides {
  49. return CorrectionRangeOverrides(preMeal: therapySettings.correctionRangeOverrides?.preMeal,
  50. workout: therapySettings.correctionRangeOverrides?.workout)
  51. }
  52. var correctionRangeScheduleRange: ClosedRange<HKQuantity> {
  53. precondition(therapySettings.glucoseTargetRangeSchedule != nil)
  54. return therapySettings.glucoseTargetRangeSchedule!.scheduleRange()
  55. }
  56. var insulinSensitivitySchedule: InsulinSensitivitySchedule? {
  57. return therapySettings.insulinSensitivitySchedule
  58. }
  59. func insulinSensitivitySchedule(for glucoseUnit: HKUnit) -> InsulinSensitivitySchedule? {
  60. return insulinSensitivitySchedule?.schedule(for: glucoseUnit)
  61. }
  62. /// Reset to initial
  63. public func reset() {
  64. therapySettings = initialTherapySettings
  65. }
  66. }
  67. // MARK: Passing along to the delegate
  68. extension TherapySettingsViewModel {
  69. public var maximumBasalScheduleEntryCount: Int? {
  70. pumpSupportedIncrements()?.maximumBasalScheduleEntryCount
  71. }
  72. public func pumpSupportedIncrements() -> PumpSupportedIncrements? {
  73. return delegate?.pumpSupportedIncrements()
  74. }
  75. public func syncBasalRateSchedule(items: [RepeatingScheduleValue<Double>], completion: @escaping (Result<BasalRateSchedule, Error>) -> Void) {
  76. delegate?.syncBasalRateSchedule(items: items, completion: completion)
  77. }
  78. public func syncDeliveryLimits(deliveryLimits: DeliveryLimits, completion: @escaping (Result<DeliveryLimits, Error>) -> Void) {
  79. delegate?.syncDeliveryLimits(deliveryLimits: deliveryLimits, completion: completion)
  80. }
  81. }
  82. // MARK: Saving
  83. extension TherapySettingsViewModel {
  84. public func saveCorrectionRange(range: GlucoseRangeSchedule) {
  85. therapySettings.glucoseTargetRangeSchedule = range
  86. delegate?.saveCompletion(for: TherapySetting.glucoseTargetRange, therapySettings: therapySettings)
  87. }
  88. public func saveCorrectionRangeOverride(preset: CorrectionRangeOverrides.Preset,
  89. correctionRangeOverrides: CorrectionRangeOverrides) {
  90. therapySettings.correctionRangeOverrides = correctionRangeOverrides
  91. switch preset {
  92. case .preMeal:
  93. delegate?.saveCompletion(for: TherapySetting.preMealCorrectionRangeOverride, therapySettings: therapySettings)
  94. case .workout:
  95. delegate?.saveCompletion(for: TherapySetting.workoutCorrectionRangeOverride, therapySettings: therapySettings)
  96. }
  97. }
  98. public func saveSuspendThreshold(quantity: HKQuantity, withDisplayGlucoseUnit displayGlucoseUnit: HKUnit) {
  99. therapySettings.suspendThreshold = GlucoseThreshold(unit: displayGlucoseUnit, value: quantity.doubleValue(for: displayGlucoseUnit))
  100. delegate?.saveCompletion(for: TherapySetting.suspendThreshold, therapySettings: therapySettings)
  101. }
  102. public func saveBasalRates(basalRates: BasalRateSchedule) {
  103. therapySettings.basalRateSchedule = basalRates
  104. delegate?.saveCompletion(for: TherapySetting.basalRate, therapySettings: therapySettings)
  105. }
  106. public func saveDeliveryLimits(limits: DeliveryLimits) {
  107. therapySettings.maximumBasalRatePerHour = limits.maximumBasalRate?.doubleValue(for: .internationalUnitsPerHour)
  108. therapySettings.maximumBolus = limits.maximumBolus?.doubleValue(for: .internationalUnit())
  109. delegate?.saveCompletion(for: TherapySetting.deliveryLimits, therapySettings: therapySettings)
  110. }
  111. public func saveInsulinModel(insulinModelPreset: ExponentialInsulinModelPreset) {
  112. therapySettings.defaultRapidActingModel = insulinModelPreset
  113. delegate?.saveCompletion(for: TherapySetting.insulinModel, therapySettings: therapySettings)
  114. }
  115. public func saveCarbRatioSchedule(carbRatioSchedule: CarbRatioSchedule) {
  116. therapySettings.carbRatioSchedule = carbRatioSchedule
  117. delegate?.saveCompletion(for: TherapySetting.carbRatio, therapySettings: therapySettings)
  118. }
  119. public func saveInsulinSensitivitySchedule(insulinSensitivitySchedule: InsulinSensitivitySchedule) {
  120. therapySettings.insulinSensitivitySchedule = insulinSensitivitySchedule
  121. delegate?.saveCompletion(for: TherapySetting.insulinSensitivity, therapySettings: therapySettings)
  122. }
  123. }