Profile.swift 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // LoopFollow
  2. // Profile.swift
  3. // Created by Jonas Björkert on 2023-10-05.
  4. import Foundation
  5. extension MainViewController {
  6. // NS Profile Web Call
  7. func webLoadNSProfile() {
  8. NightscoutUtils.executeRequest(eventType: .profile, parameters: [:]) { (result: Result<NSProfile, Error>) in
  9. switch result {
  10. case let .success(profileData):
  11. self.updateProfile(profileData: profileData)
  12. case let .failure(error):
  13. LogManager.shared.log(category: .nightscout, message: "webLoadNSProfile, error fetching profile data: \(error.localizedDescription)")
  14. }
  15. }
  16. }
  17. // NS Profile Response Processor
  18. func updateProfile(profileData: NSProfile) {
  19. guard let store = profileData.store["default"] ?? profileData.store["Default"] else {
  20. return
  21. }
  22. profileManager.loadProfile(from: profileData)
  23. infoManager.updateInfoData(type: .profile, value: profileData.defaultProfile)
  24. basalProfile.removeAll()
  25. for basalEntry in store.basal {
  26. let entry = basalProfileStruct(value: basalEntry.value, time: basalEntry.time, timeAsSeconds: basalEntry.timeAsSeconds)
  27. basalProfile.append(entry)
  28. }
  29. // Don't process the basal or draw the graph until after the BG has been fully processeed and drawn
  30. if firstGraphLoad { return }
  31. var basalSegments: [DataStructs.basalProfileSegment] = []
  32. let graphHours = 24 * Storage.shared.downloadDays.value
  33. // Build scheduled basal segments from right to left by
  34. // moving pointers to the current midnight and current basal
  35. var midnight = dateTimeUtils.getTimeIntervalMidnightToday()
  36. var basalProfileIndex = basalProfile.count - 1
  37. var start = midnight + basalProfile[basalProfileIndex].timeAsSeconds
  38. var end = dateTimeUtils.getNowTimeIntervalUTC()
  39. // Move back until we're in the graph range
  40. while start > end {
  41. basalProfileIndex -= 1
  42. start = midnight + basalProfile[basalProfileIndex].timeAsSeconds
  43. }
  44. // Add records while they're still within the graph
  45. let graphStart = dateTimeUtils.getTimeIntervalNHoursAgo(N: graphHours)
  46. while end >= graphStart {
  47. let entry = DataStructs.basalProfileSegment(
  48. basalRate: basalProfile[basalProfileIndex].value, startDate: start, endDate: end
  49. )
  50. basalSegments.append(entry)
  51. basalProfileIndex -= 1
  52. if basalProfileIndex < 0 {
  53. basalProfileIndex = basalProfile.count - 1
  54. midnight = midnight.advanced(by: -24 * 60 * 60)
  55. }
  56. end = start - 1
  57. start = midnight + basalProfile[basalProfileIndex].timeAsSeconds
  58. }
  59. // reverse the result to get chronological order
  60. basalSegments.reverse()
  61. var firstPass = true
  62. // Runs the scheduled basal to the end of the prediction line
  63. var predictionEndTime = dateTimeUtils.getNowTimeIntervalUTC() + (3600 * Storage.shared.predictionToLoad.value)
  64. basalScheduleData.removeAll()
  65. for i in 0 ..< basalSegments.count {
  66. let timeStart = dateTimeUtils.getTimeIntervalNHoursAgo(N: graphHours)
  67. // This processed everything after the first one.
  68. if firstPass == false,
  69. basalSegments[i].startDate <= predictionEndTime
  70. {
  71. let startDot = basalGraphStruct(basalRate: basalSegments[i].basalRate, date: basalSegments[i].startDate)
  72. basalScheduleData.append(startDot)
  73. var endDate = basalSegments[i].endDate
  74. // if it's the last one needed, set it to end at the prediction end time
  75. if endDate > predictionEndTime || i == basalSegments.count - 1 {
  76. endDate = Double(predictionEndTime)
  77. }
  78. let endDot = basalGraphStruct(basalRate: basalSegments[i].basalRate, date: endDate)
  79. basalScheduleData.append(endDot)
  80. }
  81. // we need to manually set the first one
  82. // Check that this is the first one and there are no existing entries
  83. if firstPass == true {
  84. // check that the timestamp is > the current entry and < the next entry
  85. if timeStart >= basalSegments[i].startDate, timeStart < basalSegments[i].endDate {
  86. // Set the start time to match the BG start
  87. let startDot = basalGraphStruct(basalRate: basalSegments[i].basalRate, date: Double(timeStart + (60 * 5)))
  88. basalScheduleData.append(startDot)
  89. // set the enddot where the next one will start
  90. var endDate = basalSegments[i].endDate
  91. let endDot = basalGraphStruct(basalRate: basalSegments[i].basalRate, date: endDate)
  92. basalScheduleData.append(endDot)
  93. firstPass = false
  94. }
  95. }
  96. }
  97. if Storage.shared.graphBasal.value {
  98. updateBasalScheduledGraph()
  99. }
  100. }
  101. }