TrioRemoteControl+Override.swift 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import CoreData
  2. import Foundation
  3. extension TrioRemoteControl {
  4. @MainActor internal func handleCancelOverrideCommand(_ pushMessage: PushMessage) async {
  5. await disableAllActiveOverrides()
  6. debug(
  7. .remoteControl,
  8. "Remote command processed successfully. \(pushMessage.humanReadableDescription())"
  9. )
  10. }
  11. @MainActor internal func handleStartOverrideCommand(_ pushMessage: PushMessage) async {
  12. do {
  13. guard let overrideName = pushMessage.overrideName, !overrideName.isEmpty else {
  14. await logError("Command rejected: override name is missing.", pushMessage: pushMessage)
  15. return
  16. }
  17. let presetIDs = try await overrideStorage.fetchForOverridePresets()
  18. let presets = try presetIDs.compactMap { id in
  19. try viewContext.existingObject(with: id) as? OverrideStored
  20. }
  21. if let preset = presets.first(where: { $0.name == overrideName }) {
  22. await enactOverridePreset(preset: preset, pushMessage: pushMessage)
  23. } else {
  24. await logError(
  25. "Command rejected: override preset '\(overrideName)' not found.",
  26. pushMessage: pushMessage
  27. )
  28. }
  29. } catch {
  30. debug(
  31. .remoteControl,
  32. "\(DebuggingIdentifiers.failed) Failed to handle start override command: \(error.localizedDescription)"
  33. )
  34. await logError(
  35. "Command failed: \(error.localizedDescription)",
  36. pushMessage: pushMessage
  37. )
  38. }
  39. }
  40. @MainActor private func enactOverridePreset(preset: OverrideStored, pushMessage: PushMessage) async {
  41. preset.enabled = true
  42. preset.date = Date()
  43. preset.isUploadedToNS = false
  44. await disableAllActiveOverrides(except: preset.objectID)
  45. do {
  46. if viewContext.hasChanges {
  47. try viewContext.save()
  48. Foundation.NotificationCenter.default.post(name: .willUpdateOverrideConfiguration, object: nil)
  49. await awaitNotification(.didUpdateOverrideConfiguration)
  50. debug(.remoteControl, "Remote command processed successfully. \(pushMessage.humanReadableDescription())")
  51. }
  52. } catch {
  53. debug(.remoteControl, "Failed to enact override preset: \(error.localizedDescription)")
  54. }
  55. }
  56. @MainActor private func disableAllActiveOverrides(except overrideID: NSManagedObjectID? = nil) async {
  57. do {
  58. let ids = try await overrideStorage.loadLatestOverrideConfigurations(fetchLimit: 0) // 0 = no fetch limit
  59. let didPostNotification = try await viewContext.perform { () -> Bool in
  60. let results = try ids.compactMap { id in
  61. try self.viewContext.existingObject(with: id) as? OverrideStored
  62. }
  63. guard !results.isEmpty else { return false }
  64. for canceledOverride in results where canceledOverride.enabled {
  65. if let overrideID = overrideID, canceledOverride.objectID == overrideID {
  66. continue
  67. }
  68. let newOverrideRunStored = OverrideRunStored(context: self.viewContext)
  69. newOverrideRunStored.id = UUID()
  70. newOverrideRunStored.name = canceledOverride.name
  71. newOverrideRunStored.startDate = canceledOverride.date ?? .distantPast
  72. newOverrideRunStored.endDate = Date()
  73. newOverrideRunStored.target = NSDecimalNumber(
  74. decimal: self.overrideStorage.calculateTarget(override: canceledOverride)
  75. )
  76. newOverrideRunStored.override = canceledOverride
  77. newOverrideRunStored.isUploadedToNS = false
  78. canceledOverride.enabled = false
  79. canceledOverride.isUploadedToNS = false
  80. }
  81. if self.viewContext.hasChanges {
  82. try self.viewContext.save()
  83. Foundation.NotificationCenter.default.post(name: .willUpdateOverrideConfiguration, object: nil)
  84. return true
  85. } else {
  86. return false
  87. }
  88. }
  89. if didPostNotification {
  90. await awaitNotification(.didUpdateOverrideConfiguration)
  91. }
  92. } catch {
  93. debug(
  94. .remoteControl,
  95. "\(DebuggingIdentifiers.failed) Failed to disable active overrides: \(error.localizedDescription)"
  96. )
  97. }
  98. }
  99. }