TempTargetsStorage.swift 3.5 KB

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