TempTargetsStorage.swift 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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 currentTarget = recent()
  53. .last(where: {
  54. $0.createdAt.addingTimeInterval(Int($0.duration).minutes.timeInterval) > Date()
  55. && $0.createdAt <= Date()
  56. })
  57. else {
  58. return nil
  59. }
  60. if let cancel = recent().last(where: { $0.createdAt <= Date() }), cancel.duration == 0 {
  61. return nil
  62. }
  63. return currentTarget
  64. }
  65. func nightscoutTretmentsNotUploaded() -> [NigtscoutTreatment] {
  66. let uploaded = storage.retrieve(OpenAPS.Nightscout.uploadedTempTargets, as: [NigtscoutTreatment].self) ?? []
  67. let eventsManual = recent().filter { $0.enteredBy == TempTarget.manual }
  68. let treatments = eventsManual.map {
  69. NigtscoutTreatment(
  70. duration: Int($0.duration),
  71. rawDuration: nil,
  72. rawRate: nil,
  73. absolute: nil,
  74. rate: nil,
  75. eventType: .nsTempTarget,
  76. createdAt: $0.createdAt,
  77. enteredBy: TempTarget.manual,
  78. bolus: nil,
  79. insulin: nil,
  80. notes: nil,
  81. carbs: nil,
  82. targetTop: $0.targetTop,
  83. targetBottom: $0.targetBottom
  84. )
  85. }
  86. return Array(Set(treatments).subtracting(Set(uploaded)))
  87. }
  88. func storePresets(_ targets: [TempTarget]) {
  89. storage.remove(OpenAPS.FreeAPS.tempTargetsPresets)
  90. storeTempTargets(targets, isPresets: true)
  91. }
  92. func presets() -> [TempTarget] {
  93. storage.retrieve(OpenAPS.FreeAPS.tempTargetsPresets, as: [TempTarget].self)?.reversed() ?? []
  94. }
  95. }