TrioRemoteControl+TempTarget.swift 3.8 KB

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