TrioRemoteControl+Override.swift 4.2 KB

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