AutotuneConfigStateModel.swift 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import Combine
  2. import LoopKit
  3. import SwiftUI
  4. extension AutotuneConfig {
  5. final class StateModel: BaseStateModel<Provider> {
  6. @Injected() var apsManager: APSManager!
  7. @Injected() private var storage: FileStorage!
  8. @Published var useAutotune = false
  9. @Published var onlyAutotuneBasals = false
  10. @Published var autotune: Autotune?
  11. private(set) var units: GlucoseUnits = .mgdL
  12. @Published var publishedDate = Date()
  13. @Persisted(key: "lastAutotuneDate") private var lastAutotuneDate = Date() {
  14. didSet {
  15. DispatchQueue.main.async {
  16. self.publishedDate = self.lastAutotuneDate
  17. }
  18. }
  19. }
  20. override func subscribe() {
  21. autotune = provider.autotune
  22. units = settingsManager.settings.units
  23. useAutotune = settingsManager.settings.useAutotune
  24. publishedDate = lastAutotuneDate
  25. subscribeSetting(\.onlyAutotuneBasals, on: $onlyAutotuneBasals) { onlyAutotuneBasals = $0 }
  26. $useAutotune
  27. .removeDuplicates()
  28. .flatMap { [weak self] use -> AnyPublisher<Bool, Never> in
  29. guard let self = self else {
  30. return Just(false).eraseToAnyPublisher()
  31. }
  32. self.settingsManager.settings.useAutotune = use
  33. return Future { promise in
  34. Task.init(priority: .background) {
  35. do {
  36. _ = try await self.apsManager.makeProfiles()
  37. promise(.success(true))
  38. } catch {
  39. promise(.success(false))
  40. }
  41. }
  42. }
  43. .eraseToAnyPublisher()
  44. }
  45. .cancellable()
  46. .store(in: &lifetime)
  47. }
  48. func run() {
  49. Task {
  50. do {
  51. if let result = await self.apsManager.autotune() {
  52. autotune = result
  53. _ = try await self.apsManager.makeProfiles()
  54. lastAutotuneDate = Date()
  55. }
  56. } catch {
  57. debugPrint("\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to run Autotune")
  58. }
  59. }
  60. }
  61. func delete() async {
  62. provider.deleteAutotune()
  63. autotune = nil
  64. do {
  65. _ = try await apsManager.makeProfiles()
  66. } catch {
  67. return
  68. }
  69. }
  70. func replace() {
  71. if let autotunedBasals = autotune {
  72. let basals = autotunedBasals.basalProfile
  73. .map { basal -> BasalProfileEntry in
  74. BasalProfileEntry(
  75. start: String(basal.start.prefix(5)),
  76. minutes: basal.minutes,
  77. rate: basal.rate
  78. )
  79. }
  80. guard let pump = apsManager.pumpManager else {
  81. storage.save(basals, as: OpenAPS.Settings.basalProfile)
  82. debug(.service, "Basals have been replaced with Autotuned Basals by user.")
  83. return
  84. }
  85. let syncValues = basals.map {
  86. RepeatingScheduleValue(startTime: TimeInterval($0.minutes * 60), value: Double($0.rate))
  87. }
  88. pump.syncBasalRateSchedule(items: syncValues) { result in
  89. switch result {
  90. case .success:
  91. self.storage.save(basals, as: OpenAPS.Settings.basalProfile)
  92. debug(.service, "Basals saved to pump!")
  93. case .failure:
  94. debug(.service, "Basals couldn't be save to pump")
  95. }
  96. }
  97. }
  98. }
  99. }
  100. }
  101. extension AutotuneConfig.StateModel: SettingsObserver {
  102. func settingsDidChange(_: FreeAPSSettings) {
  103. units = settingsManager.settings.units
  104. }
  105. }