PumpHistoryStorage.swift 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import Foundation
  2. import LoopKit
  3. import SwiftDate
  4. import Swinject
  5. protocol PumpHistoryStorage {
  6. func storePumpEvents(_ events: [NewPumpEvent])
  7. func storeJournalCarbs(_ carbs: Int)
  8. }
  9. final class BasePumpHistoryStorage: PumpHistoryStorage, Injectable {
  10. private let processQueue = DispatchQueue(label: "BasePumpHistoryStorage.processQueue")
  11. @Injected() private var storage: FileStorage!
  12. init(resolver: Resolver) {
  13. injectServices(resolver)
  14. }
  15. func storePumpEvents(_ events: [NewPumpEvent]) {
  16. processQueue.async {
  17. let eventsToStore = events.flatMap { event -> [PumpHistoryEvent] in
  18. let id = event.raw.md5String
  19. switch event.type {
  20. case .bolus:
  21. guard let dose = event.dose else { return [] }
  22. let amount = Decimal(string: dose.unitsInDeliverableIncrements.description)
  23. let minutes = Int((dose.endDate - dose.startDate).timeInterval / 60)
  24. return [PumpHistoryEvent(
  25. id: id,
  26. type: .bolus,
  27. timestamp: event.date,
  28. amount: amount,
  29. duration: minutes,
  30. durationMin: nil,
  31. rate: nil,
  32. temp: nil,
  33. carbInput: nil
  34. )]
  35. case .tempBasal:
  36. guard let dose = event.dose else { return [] }
  37. let rate = Decimal(string: dose.unitsPerHour.description)
  38. let minutes = Int((dose.endDate - dose.startDate).timeInterval / 60)
  39. return [
  40. PumpHistoryEvent(
  41. id: id,
  42. type: .tempBasalDuration,
  43. timestamp: event.date,
  44. amount: nil,
  45. duration: nil,
  46. durationMin: minutes,
  47. rate: rate,
  48. temp: nil,
  49. carbInput: nil
  50. ),
  51. PumpHistoryEvent(
  52. id: "_" + id,
  53. type: .tempBasal,
  54. timestamp: event.date,
  55. amount: nil,
  56. duration: nil,
  57. durationMin: nil,
  58. rate: rate,
  59. temp: .absolute,
  60. carbInput: nil
  61. )
  62. ]
  63. case .suspend:
  64. return [
  65. PumpHistoryEvent(
  66. id: id,
  67. type: .pumpSuspend,
  68. timestamp: event.date,
  69. amount: nil,
  70. duration: nil,
  71. durationMin: nil,
  72. rate: nil,
  73. temp: nil,
  74. carbInput: nil
  75. )
  76. ]
  77. case .resume:
  78. return [
  79. PumpHistoryEvent(
  80. id: id,
  81. type: .pumpResume,
  82. timestamp: event.date,
  83. amount: nil,
  84. duration: nil,
  85. durationMin: nil,
  86. rate: nil,
  87. temp: nil,
  88. carbInput: nil
  89. )
  90. ]
  91. case .rewind:
  92. return [
  93. PumpHistoryEvent(
  94. id: id,
  95. type: .rewind,
  96. timestamp: event.date,
  97. amount: nil,
  98. duration: nil,
  99. durationMin: nil,
  100. rate: nil,
  101. temp: nil,
  102. carbInput: nil
  103. )
  104. ]
  105. case .prime:
  106. return [
  107. PumpHistoryEvent(
  108. id: id,
  109. type: .prime,
  110. timestamp: event.date,
  111. amount: nil,
  112. duration: nil,
  113. durationMin: nil,
  114. rate: nil,
  115. temp: nil,
  116. carbInput: nil
  117. )
  118. ]
  119. default:
  120. return []
  121. }
  122. }
  123. self.processNewEvents(eventsToStore)
  124. }
  125. }
  126. func storeJournalCarbs(_ carbs: Int) {
  127. processQueue.async {
  128. let eventsToStore = [
  129. PumpHistoryEvent(
  130. id: UUID().uuidString,
  131. type: .journalCarbs,
  132. timestamp: Date(),
  133. amount: nil,
  134. duration: nil,
  135. durationMin: nil,
  136. rate: nil,
  137. temp: nil,
  138. carbInput: carbs
  139. )
  140. ]
  141. self.processNewEvents(eventsToStore)
  142. }
  143. }
  144. private func processNewEvents(_ events: [PumpHistoryEvent]) {
  145. dispatchPrecondition(condition: .onQueue(processQueue))
  146. let file = OpenAPS.Monitor.pumpHistory
  147. try? storage.transaction { storage in
  148. try storage.append(events, to: file, uniqBy: \.id)
  149. let uniqEvents = try storage.retrieve(file, as: [PumpHistoryEvent].self)
  150. .filter { $0.timestamp.addingTimeInterval(1.days.timeInterval) > Date() }
  151. .sorted { $0.timestamp > $1.timestamp }
  152. try storage.save(Array(uniqEvents), as: file)
  153. }
  154. }
  155. }