TrioRemoteControl+Meal.swift 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import Foundation
  2. extension TrioRemoteControl {
  3. func handleMealCommand(_ payload: CommandPayload) async throws {
  4. guard payload.carbs != nil || payload.fat != nil || payload.protein != nil else {
  5. await logError("Command rejected: meal data is incomplete or invalid.", payload: payload)
  6. return
  7. }
  8. let carbsDecimal = payload.carbs != nil ? Decimal(payload.carbs!) : nil
  9. let fatDecimal = payload.fat != nil ? Decimal(payload.fat!) : nil
  10. let proteinDecimal = payload.protein != nil ? Decimal(payload.protein!) : nil
  11. let settings = await TrioApp.resolver.resolve(SettingsManager.self)?.settings
  12. let maxCarbs = settings?.maxCarbs ?? Decimal(0)
  13. let maxFat = settings?.maxFat ?? Decimal(0)
  14. let maxProtein = settings?.maxProtein ?? Decimal(0)
  15. if let carbs = carbsDecimal, carbs > maxCarbs {
  16. await logError(
  17. "Command rejected: carbs amount (\(carbs)g) exceeds the maximum allowed (\(maxCarbs)g).",
  18. payload: payload
  19. )
  20. return
  21. }
  22. if let fat = fatDecimal, fat > maxFat {
  23. await logError("Command rejected: fat amount (\(fat)g) exceeds the maximum allowed (\(maxFat)g).", payload: payload)
  24. return
  25. }
  26. if let protein = proteinDecimal, protein > maxProtein {
  27. await logError(
  28. "Command rejected: protein amount (\(protein)g) exceeds the maximum allowed (\(maxProtein)g).",
  29. payload: payload
  30. )
  31. return
  32. }
  33. let payloadDate = Date(timeIntervalSince1970: payload.timestamp)
  34. let taskContext = CoreDataStack.shared.newTaskContext()
  35. let results = try await CoreDataStack.shared.fetchEntitiesAsync(
  36. ofType: CarbEntryStored.self, onContext: taskContext, predicate: NSPredicate(
  37. format: "date > %@",
  38. payloadDate as NSDate
  39. ), key: "date", ascending: false
  40. )
  41. await taskContext.perform {
  42. guard let recentCarbEntries = results as? [CarbEntryStored] else { return }
  43. if !recentCarbEntries.isEmpty {
  44. Task {
  45. await self.logError(
  46. "Command rejected: newer carb entries have been logged since the command was sent.",
  47. payload: payload
  48. )
  49. return
  50. }
  51. }
  52. }
  53. let actualDate = payload.scheduledTime.map { Date(timeIntervalSince1970: $0) }
  54. let mealEntry = CarbsEntry(
  55. id: UUID().uuidString, createdAt: Date(), actualDate: actualDate,
  56. carbs: carbsDecimal ?? 0, fat: fatDecimal, protein: proteinDecimal,
  57. note: "Remote meal command", enteredBy: CarbsEntry.local, isFPU: false,
  58. fpuID: fatDecimal ?? 0 > 0 || proteinDecimal ?? 0 > 0 ? UUID().uuidString : nil
  59. )
  60. try await carbsStorage.storeCarbs([mealEntry], areFetchedFromRemote: false)
  61. if payload.bolusAmount == nil {
  62. await logSuccess(
  63. "Remote command processed successfully. \(payload.humanReadableDescription())",
  64. payload: payload,
  65. customNotificationMessage: "Meal logged"
  66. )
  67. }
  68. }
  69. }