TempTargetSetup.swift 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import CoreData
  2. import Foundation
  3. extension Home.StateModel {
  4. func setupTempTargetsStored() {
  5. Task {
  6. do {
  7. let ids = try await self.fetchTempTargets()
  8. let tempTargetObjects: [TempTargetStored] = try await CoreDataStack.shared
  9. .getNSManagedObject(with: ids, context: viewContext)
  10. await updateTempTargetsArray(with: tempTargetObjects)
  11. } catch {
  12. debug(
  13. .default,
  14. "\(DebuggingIdentifiers.failed) Error setting up tempTargetStored: \(error.localizedDescription)"
  15. )
  16. }
  17. }
  18. }
  19. private func fetchTempTargets() async throws -> [NSManagedObjectID] {
  20. let results = try await CoreDataStack.shared.fetchEntitiesAsync(
  21. ofType: TempTargetStored.self,
  22. onContext: tempTargetFetchContext,
  23. predicate: NSPredicate.tempTargetsForMainChart,
  24. key: "date",
  25. ascending: false
  26. )
  27. return try await tempTargetFetchContext.perform {
  28. guard let fetchedResults = results as? [TempTargetStored] else {
  29. throw CoreDataError.fetchError(function: #function, file: #file)
  30. }
  31. return fetchedResults.map(\.objectID)
  32. }
  33. }
  34. @MainActor private func updateTempTargetsArray(with objects: [TempTargetStored]) {
  35. tempTargetStored = objects
  36. }
  37. // Setup expired TempTargets
  38. func setupTempTargetsRunStored() {
  39. Task {
  40. do {
  41. let ids = try await self.fetchTempTargetRunStored()
  42. let tempTargetRunObjects: [TempTargetRunStored] = try await CoreDataStack.shared
  43. .getNSManagedObject(with: ids, context: viewContext)
  44. await updateTempTargetRunStoredArray(with: tempTargetRunObjects)
  45. } catch {
  46. debug(
  47. .default,
  48. "\(DebuggingIdentifiers.failed) Error setting up temp targetsRunStored: \(error.localizedDescription)"
  49. )
  50. }
  51. }
  52. }
  53. private func fetchTempTargetRunStored() async throws -> [NSManagedObjectID] {
  54. let predicate = NSPredicate(format: "startDate >= %@", Date.oneDayAgo as NSDate)
  55. let results = try await CoreDataStack.shared.fetchEntitiesAsync(
  56. ofType: TempTargetRunStored.self,
  57. onContext: tempTargetFetchContext,
  58. predicate: predicate,
  59. key: "startDate",
  60. ascending: false
  61. )
  62. return try await tempTargetFetchContext.perform {
  63. guard let fetchedResults = results as? [TempTargetRunStored] else {
  64. throw CoreDataError.fetchError(function: #function, file: #file)
  65. }
  66. return fetchedResults.map(\.objectID)
  67. }
  68. }
  69. @MainActor private func updateTempTargetRunStoredArray(with objects: [TempTargetRunStored]) {
  70. tempTargetRunStored = objects
  71. }
  72. @MainActor func cancelTempTarget(withID id: NSManagedObjectID) async {
  73. do {
  74. guard let profileToCancel = try viewContext.existingObject(with: id) as? TempTargetStored else { return }
  75. profileToCancel.enabled = false
  76. guard viewContext.hasChanges else { return }
  77. try viewContext.save()
  78. // Do not save Cancel-Temp Targets from Nightscout to RunStoredEntity
  79. if profileToCancel.duration != 0, profileToCancel.target != 0 {
  80. await saveToTempTargetRunStored(object: profileToCancel)
  81. }
  82. // We also need to update the storage for temp targets
  83. tempTargetStorage.saveTempTargetsToStorage([TempTarget.cancel(at: Date())])
  84. Foundation.NotificationCenter.default.post(name: .didUpdateTempTargetConfiguration, object: nil)
  85. } catch let error as NSError {
  86. debugPrint("\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to cancel Temp Target with error: \(error)")
  87. }
  88. }
  89. @MainActor func saveToTempTargetRunStored(object: TempTargetStored) async {
  90. let newTempTargetRunStored = TempTargetRunStored(context: viewContext)
  91. newTempTargetRunStored.id = UUID()
  92. newTempTargetRunStored.name = object.name
  93. newTempTargetRunStored.startDate = object.date ?? .distantPast
  94. newTempTargetRunStored.endDate = Date()
  95. newTempTargetRunStored.target = object.target ?? 0
  96. newTempTargetRunStored.tempTarget = object
  97. newTempTargetRunStored.isUploadedToNS = false
  98. do {
  99. guard viewContext.hasChanges else { return }
  100. try viewContext.save()
  101. } catch let error as NSError {
  102. debugPrint("\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to save Temp Target with error: \(error)")
  103. }
  104. }
  105. func computeAdjustedPercentage(halfBasalTargetValue: Decimal, tempTargetValue: Decimal) -> Int {
  106. let normalTarget: Decimal = 100
  107. let deviationFromNormal = halfBasalTargetValue - normalTarget
  108. let adjustmentFactor = deviationFromNormal + (tempTargetValue - normalTarget)
  109. let adjustmentRatio: Decimal = (deviationFromNormal * adjustmentFactor <= 0) ? autosensMax : deviationFromNormal /
  110. adjustmentFactor
  111. return Int(Double(min(adjustmentRatio, autosensMax) * 100).rounded())
  112. }
  113. }