Treatments.swift 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. // LoopFollow
  2. // Treatments.swift
  3. import Foundation
  4. extension MainViewController {
  5. // NS Treatments Web Call
  6. // Downloads Basal, Bolus, Carbs, BG Check, Notes, Overrides
  7. func WebLoadNSTreatments() {
  8. if !Storage.shared.downloadTreatments.value { return }
  9. let startTimeString = dateTimeUtils.getDateTimeString(addingDays: -1 * Storage.shared.downloadDays.value)
  10. let endTimeString = dateTimeUtils.getDateTimeString(addingHours: 6)
  11. let estimatedCount = max(Storage.shared.downloadDays.value * 100, 5000)
  12. let parameters: [String: String] = [
  13. "find[created_at][$gte]": startTimeString,
  14. "find[created_at][$lte]": endTimeString,
  15. "count": "\(estimatedCount)",
  16. ]
  17. NightscoutUtils.executeDynamicRequest(eventType: .treatments, parameters: parameters) { (result: Result<Any, Error>) in
  18. switch result {
  19. case let .success(data):
  20. if let entries = data as? [[String: AnyObject]] {
  21. DispatchQueue.main.async {
  22. self.updateTreatments(entries: entries)
  23. }
  24. } else {
  25. LogManager.shared.log(category: .nightscout, message: "WebLoadNSTreatments, Unexpected data structure")
  26. }
  27. case let .failure(error):
  28. LogManager.shared.log(category: .nightscout, message: "WebLoadNSTreatments, error \(error.localizedDescription)")
  29. }
  30. }
  31. }
  32. // Process and split out treatments to individual tasks
  33. func updateTreatments(entries: [[String: AnyObject]]) {
  34. // Deduplicate entries by "id" field (Trio/Loop UUID)
  35. var seenIDs = Set<String>()
  36. let uniqueEntries = entries.filter { entry in
  37. guard let id = entry["id"] as? String else { return true }
  38. return seenIDs.insert(id).inserted
  39. }
  40. var tempBasal: [[String: AnyObject]] = []
  41. var bolus: [[String: AnyObject]] = []
  42. var smb: [[String: AnyObject]] = []
  43. var carbs: [[String: AnyObject]] = []
  44. var temporaryOverride: [[String: AnyObject]] = []
  45. var temporaryTarget: [[String: AnyObject]] = []
  46. var note: [[String: AnyObject]] = []
  47. var bgCheck: [[String: AnyObject]] = []
  48. var suspendPump: [[String: AnyObject]] = []
  49. var resumePump: [[String: AnyObject]] = []
  50. var pumpSiteChange: [cageData] = []
  51. var cgmSensorStart: [sageData] = []
  52. var insulinCartridge: [iageData] = []
  53. for entry in uniqueEntries {
  54. guard let eventType = entry["eventType"] as? String else {
  55. continue
  56. }
  57. switch eventType {
  58. case "Temp Basal":
  59. tempBasal.append(entry)
  60. case "Correction Bolus", "Bolus", "External Insulin":
  61. if let automatic = entry["automatic"] as? Bool, automatic {
  62. smb.append(entry)
  63. } else {
  64. bolus.append(entry)
  65. }
  66. case "SMB":
  67. smb.append(entry)
  68. case "Meal Bolus":
  69. carbs.append(entry)
  70. bolus.append(entry)
  71. case "Carb Correction":
  72. carbs.append(entry)
  73. case "Temporary Override", "Exercise":
  74. temporaryOverride.append(entry)
  75. case "Temporary Target":
  76. temporaryTarget.append(entry)
  77. case "Note":
  78. note.append(entry)
  79. case "BG Check":
  80. bgCheck.append(entry)
  81. case "Suspend Pump":
  82. suspendPump.append(entry)
  83. case "Resume Pump":
  84. resumePump.append(entry)
  85. case "Pump Site Change", "Site Change":
  86. if let createdAt = entry["created_at"] as? String {
  87. let newEntry = cageData(created_at: createdAt)
  88. pumpSiteChange.append(newEntry)
  89. }
  90. case "Sensor Start":
  91. if let createdAt = entry["created_at"] as? String {
  92. let newEntry = sageData(created_at: createdAt)
  93. cgmSensorStart.append(newEntry)
  94. }
  95. case "Insulin Change":
  96. if let createdAt = entry["created_at"] as? String {
  97. let newEntry = iageData(created_at: createdAt)
  98. insulinCartridge.append(newEntry)
  99. }
  100. default:
  101. print("No Match: \(String(describing: entry))")
  102. }
  103. }
  104. if tempBasal.count > 0 {
  105. processNSBasals(entries: tempBasal)
  106. } else {
  107. if basalData.count > 0 {
  108. clearOldTempBasal()
  109. }
  110. }
  111. if bolus.count > 0 {
  112. processNSBolus(entries: bolus)
  113. } else {
  114. if bolusData.count > 0 {
  115. clearOldBolus()
  116. }
  117. }
  118. if smb.count > 0 {
  119. processNSSmb(entries: smb)
  120. } else {
  121. if smbData.count > 0 {
  122. clearOldSmb()
  123. }
  124. }
  125. updateTodaysCarbsFromEntries(entries: carbs)
  126. if carbs.count > 0 {
  127. processNSCarbs(entries: carbs)
  128. } else {
  129. if carbData.count > 0 {
  130. clearOldCarb()
  131. }
  132. }
  133. if bgCheck.count > 0 {
  134. processNSBGCheck(entries: bgCheck)
  135. } else {
  136. if bgCheckData.count > 0 {
  137. clearOldBGCheck()
  138. }
  139. }
  140. if temporaryOverride.count == 0, overrideGraphData.count > 0 {
  141. clearOldOverride()
  142. }
  143. if temporaryOverride.count > 0 {
  144. processNSOverrides(entries: temporaryOverride)
  145. }
  146. if temporaryTarget.count == 0, tempTargetGraphData.count > 0 {
  147. clearOldTempTarget()
  148. }
  149. if temporaryTarget.count > 0 {
  150. processNSTemporaryTarget(entries: temporaryTarget)
  151. }
  152. if suspendPump.count > 0 {
  153. processSuspendPump(entries: suspendPump)
  154. } else {
  155. if suspendGraphData.count > 0 {
  156. clearOldSuspend()
  157. }
  158. }
  159. if resumePump.count > 0 {
  160. processResumePump(entries: resumePump)
  161. } else {
  162. if resumeGraphData.count > 0 {
  163. clearOldResume()
  164. }
  165. }
  166. processSage(entries: cgmSensorStart)
  167. if cgmSensorStart.count > 0 {
  168. processSensorStart(entries: cgmSensorStart)
  169. } else {
  170. if sensorStartGraphData.count > 0 {
  171. clearOldSensor()
  172. }
  173. }
  174. processIage(entries: insulinCartridge)
  175. if note.count > 0 {
  176. processNotes(entries: note)
  177. } else {
  178. if noteGraphData.count > 0 {
  179. clearOldNotes()
  180. }
  181. }
  182. processCage(entries: pumpSiteChange)
  183. }
  184. }