TrioRemoteControl+TempTarget.swift 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import Foundation
  2. import CoreData
  3. extension TrioRemoteControl {
  4. @MainActor func handleTempTargetCommand(_ pushMessage: PushMessage) async {
  5. guard let targetValue = pushMessage.target,
  6. let durationValue = pushMessage.duration
  7. else {
  8. await logError("Command rejected: temp target data is incomplete or invalid.", pushMessage: pushMessage)
  9. return
  10. }
  11. let durationInMinutes = Int(durationValue)
  12. let pushMessageDate = Date(timeIntervalSince1970: pushMessage.timestamp)
  13. let tempTarget = TempTarget(
  14. name: TempTarget.custom,
  15. createdAt: pushMessageDate,
  16. targetTop: Decimal(targetValue),
  17. targetBottom: Decimal(targetValue),
  18. duration: Decimal(durationInMinutes),
  19. enteredBy: TempTarget.local,
  20. reason: TempTarget.custom,
  21. isPreset: false,
  22. enabled: true,
  23. halfBasalTarget: settings.preferences.halfBasalExerciseTarget
  24. )
  25. await tempTargetsStorage.storeTempTarget(tempTarget: tempTarget)
  26. tempTargetsStorage.saveTempTargetsToStorage([tempTarget])
  27. debug(
  28. .remoteControl,
  29. "Remote command processed successfully. \(pushMessage.humanReadableDescription())"
  30. )
  31. }
  32. @MainActor func cancelTempTarget(_ pushMessage: PushMessage) async {
  33. debug(.remoteControl, "Cancelling temp target.")
  34. await disableAllActiveTempTargets()
  35. debug(
  36. .remoteControl,
  37. "Remote command processed successfully. \(pushMessage.humanReadableDescription())"
  38. )
  39. }
  40. @MainActor func disableAllActiveTempTargets() async {
  41. let ids = await tempTargetsStorage.loadLatestTempTargetConfigurations(fetchLimit: 0)
  42. let didPostNotification = await viewContext.perform { () -> Bool in
  43. do {
  44. let results = try ids.compactMap { id in
  45. try self.viewContext.existingObject(with: id) as? TempTargetStored
  46. }
  47. guard !results.isEmpty else {
  48. Task {
  49. await self.logError("Command rejected: no active temp target to cancel.")
  50. }
  51. return false
  52. }
  53. for canceledTempTarget in results where canceledTempTarget.enabled {
  54. let newTempTargetRunStored = TempTargetRunStored(context: self.viewContext)
  55. newTempTargetRunStored.id = UUID()
  56. newTempTargetRunStored.name = canceledTempTarget.name
  57. newTempTargetRunStored.startDate = canceledTempTarget.date ?? .distantPast
  58. newTempTargetRunStored.endDate = Date()
  59. newTempTargetRunStored
  60. .target = canceledTempTarget.target ?? 0
  61. newTempTargetRunStored.tempTarget = canceledTempTarget
  62. newTempTargetRunStored.isUploadedToNS = false
  63. canceledTempTarget.enabled = false
  64. canceledTempTarget.isUploadedToNS = false
  65. }
  66. if self.viewContext.hasChanges {
  67. try self.viewContext.save()
  68. Foundation.NotificationCenter.default.post(name: .willUpdateTempTargetConfiguration, object: nil)
  69. // Update the storage so oref can pick up cancellation
  70. self.tempTargetsStorage.saveTempTargetsToStorage([TempTarget.cancel(at: Date().addingTimeInterval(-1))])
  71. return true
  72. } else {
  73. return false
  74. }
  75. } catch {
  76. debugPrint(
  77. "\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to disable active TempTargets with error: \(error.localizedDescription)"
  78. )
  79. return false
  80. }
  81. }
  82. if didPostNotification {
  83. await awaitNotification(.didUpdateTempTargetConfiguration)
  84. }
  85. }
  86. }