TempTargetsStorage.swift 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import Foundation
  2. import SwiftDate
  3. import Swinject
  4. protocol TempTargetsObserver {
  5. func tempTargetsDidUpdate(_ targers: [TempTarget])
  6. }
  7. protocol TempTargetsStorage {
  8. func storeTempTargets(_ targets: [TempTarget])
  9. func syncDate() -> Date
  10. func recent() -> [TempTarget]
  11. func nightscoutTretmentsNotUploaded() -> [NigtscoutTreatment]
  12. func storePresets(_ targets: [TempTarget])
  13. func presets() -> [TempTarget]
  14. }
  15. final class BaseTempTargetsStorage: TempTargetsStorage, Injectable {
  16. private let processQueue = DispatchQueue(label: "BaseTempTargetsStorage.processQueue")
  17. @Injected() private var storage: FileStorage!
  18. @Injected() private var broadcaster: Broadcaster!
  19. init(resolver: Resolver) {
  20. injectServices(resolver)
  21. }
  22. func storeTempTargets(_ targets: [TempTarget]) {
  23. storeTempTargets(targets, isPresets: false)
  24. }
  25. private func storeTempTargets(_ targets: [TempTarget], isPresets: Bool) {
  26. processQueue.sync {
  27. let file = isPresets ? OpenAPS.FreeAPS.tempTargetsPresets : OpenAPS.Settings.tempTargets
  28. var uniqEvents: [TempTarget] = []
  29. self.storage.transaction { storage in
  30. storage.append(targets, to: file, uniqBy: \.createdAt)
  31. uniqEvents = storage.retrieve(file, as: [TempTarget].self)?
  32. .filter {
  33. guard !isPresets else { return true }
  34. return $0.createdAt.addingTimeInterval(1.days.timeInterval) > Date()
  35. }
  36. .sorted { $0.createdAt > $1.createdAt } ?? []
  37. storage.save(Array(uniqEvents), as: file)
  38. }
  39. broadcaster.notify(TempTargetsObserver.self, on: processQueue) {
  40. $0.tempTargetsDidUpdate(uniqEvents)
  41. }
  42. }
  43. }
  44. func syncDate() -> Date {
  45. guard let events = storage.retrieve(OpenAPS.Settings.tempTargets, as: [TempTarget].self),
  46. let recent = events.filter({ $0.enteredBy != TempTarget.manual }).first
  47. else {
  48. return Date().addingTimeInterval(-1.days.timeInterval)
  49. }
  50. return recent.createdAt.addingTimeInterval(-6.minutes.timeInterval)
  51. }
  52. func recent() -> [TempTarget] {
  53. storage.retrieve(OpenAPS.Settings.tempTargets, as: [TempTarget].self)?.reversed() ?? []
  54. }
  55. func nightscoutTretmentsNotUploaded() -> [NigtscoutTreatment] {
  56. let uploaded = storage.retrieve(OpenAPS.Nightscout.uploadedTempTargets, as: [NigtscoutTreatment].self) ?? []
  57. let eventsManual = recent().filter { $0.enteredBy == CarbsEntry.manual }
  58. let treatments = eventsManual.map {
  59. NigtscoutTreatment(
  60. duration: Int($0.duration),
  61. rawDuration: nil,
  62. rawRate: nil,
  63. absolute: nil,
  64. rate: nil,
  65. eventType: .nsTempTarget,
  66. createdAt: $0.createdAt,
  67. entededBy: TempTarget.manual,
  68. bolus: nil,
  69. insulin: nil,
  70. notes: nil,
  71. carbs: nil,
  72. targetTop: $0.targetTop,
  73. targetBottom: $0.targetBottom
  74. )
  75. }
  76. return Array(Set(treatments).subtracting(Set(uploaded)))
  77. }
  78. func storePresets(_ targets: [TempTarget]) {
  79. storage.remove(OpenAPS.FreeAPS.tempTargetsPresets)
  80. storeTempTargets(targets, isPresets: true)
  81. }
  82. func presets() -> [TempTarget] {
  83. storage.retrieve(OpenAPS.FreeAPS.tempTargetsPresets, as: [TempTarget].self)?.reversed() ?? []
  84. }
  85. }