TrioRemoteControl+Override.swift 4.0 KB

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