Timers.swift 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. //
  2. // Timers.swift
  3. // LoopFollow
  4. //
  5. // Created by Jon Fawcett on 9/3/20.
  6. // Copyright © 2020 Jon Fawcett. All rights reserved.
  7. //
  8. import Foundation
  9. import UIKit
  10. extension MainViewController {
  11. func restartAllTimers() {
  12. if !bgTimer.isValid { startBGTimer(time: 2) }
  13. if !profileTimer.isValid { startProfileTimer(time: 3) }
  14. if !deviceStatusTimer.isValid { startDeviceStatusTimer(time: 4) }
  15. if !treatmentsTimer.isValid { startTreatmentsTimer(time: 5) }
  16. if !minAgoTimer.isValid { startMinAgoTimer(time: minAgoTimeInterval) }
  17. if !calendarTimer.isValid { startCalendarTimer(time: 15) }
  18. if !alarmTimer.isValid { startAlarmTimer(time: 30) }
  19. }
  20. func invalidateTimers() {
  21. bgTimer.invalidate()
  22. profileTimer.invalidate()
  23. deviceStatusTimer.invalidate()
  24. treatmentsTimer.invalidate()
  25. minAgoTimer.invalidate()
  26. calendarTimer.invalidate()
  27. alarmTimer.invalidate()
  28. }
  29. // min Ago Timer
  30. func startMinAgoTimer(time: TimeInterval) {
  31. minAgoTimer = Timer.scheduledTimer(timeInterval: time,
  32. target: self,
  33. selector: #selector(MainViewController.minAgoTimerDidEnd(_:)),
  34. userInfo: nil,
  35. repeats: true)
  36. }
  37. // Updates Min Ago display
  38. @objc func minAgoTimerDidEnd(_ timer:Timer) {
  39. // print("min ago timer ended")
  40. if bgData.count > 0 {
  41. let bgSeconds = bgData.last!.date
  42. let now = Date().timeIntervalSince1970
  43. let secondsAgo = now - bgSeconds
  44. // Update Min Ago Displays
  45. let formatter = DateComponentsFormatter()
  46. formatter.unitsStyle = .positional // Use the appropriate positioning for the current locale
  47. if secondsAgo < 270 {
  48. formatter.allowedUnits = [ .minute] // Units to display in the formatted string
  49. } else {
  50. formatter.allowedUnits = [ .minute, .second] // Units to display in the formatted string
  51. }
  52. //formatter.zeroFormattingBehavior = [ .pad ] // Pad with zeroes where appropriate for the locale
  53. let formattedDuration = formatter.string(from: secondsAgo)
  54. MinAgoText.text = formattedDuration ?? ""
  55. MinAgoText.text! += " min ago"
  56. latestMinAgoString = formattedDuration ?? ""
  57. latestMinAgoString += " min ago"
  58. if let snoozer = self.tabBarController!.viewControllers?[2] as? SnoozeViewController {
  59. snoozer.MinAgoLabel.text = formattedDuration ?? ""
  60. snoozer.MinAgoLabel.text! += " min ago"
  61. } else { return }
  62. } else {
  63. MinAgoText.text = ""
  64. latestMinAgoString = ""
  65. if let snoozer = self.tabBarController!.viewControllers?[2] as? SnoozeViewController {
  66. snoozer.MinAgoLabel.text = ""
  67. } else { return }
  68. }
  69. }
  70. // Runs a 60 second timer when an alarm is snoozed
  71. // Prevents the alarm from triggering again while saving the snooze time to settings
  72. // End function needs nothing done
  73. func startGraphNowTimer(time: TimeInterval = 60) {
  74. graphNowTimer = Timer.scheduledTimer(timeInterval: time,
  75. target: self,
  76. selector: #selector(MainViewController.graphNowTimerDidEnd(_:)),
  77. userInfo: nil,
  78. repeats: true)
  79. }
  80. @objc func graphNowTimerDidEnd(_ timer:Timer) {
  81. createVerticalLines()
  82. }
  83. // Runs a 60 second timer when an alarm is snoozed
  84. // Prevents the alarm from triggering again while saving the snooze time to settings
  85. // End function needs nothing done
  86. func startCheckAlarmTimer(time: TimeInterval = 60) {
  87. checkAlarmTimer = Timer.scheduledTimer(timeInterval: time,
  88. target: self,
  89. selector: #selector(MainViewController.checkAlarmTimerDidEnd(_:)),
  90. userInfo: nil,
  91. repeats: false)
  92. }
  93. @objc func checkAlarmTimerDidEnd(_ timer:Timer) {
  94. }
  95. // BG Timer
  96. // Runs to 5:10 after last reading timestamp
  97. // Failed or no reading re-attempts after 10 second delay
  98. // Changes to 30 second increments after 7:00
  99. // Changes to 1 minute increments after 10:00
  100. // Changes to 5 minute increments after 20:00 stale data
  101. func startBGTimer(time: TimeInterval = 60 * 5) {
  102. bgTimer = Timer.scheduledTimer(timeInterval: time,
  103. target: self,
  104. selector: #selector(MainViewController.bgTimerDidEnd(_:)),
  105. userInfo: nil,
  106. repeats: false)
  107. }
  108. @objc func bgTimerDidEnd(_ timer:Timer) {
  109. // reset timer to 1 minute if settings aren't entered
  110. if UserDefaultsRepository.shareUserName.value == "" && UserDefaultsRepository.sharePassword.value == "" && UserDefaultsRepository.url.value == "" {
  111. startBGTimer(time: 60)
  112. return
  113. }
  114. if UserDefaultsRepository.shareUserName.value != "" && UserDefaultsRepository.sharePassword.value != "" {
  115. webLoadDexShare()
  116. } else {
  117. webLoadNSBGData()
  118. }
  119. }
  120. // Device Status Timer
  121. // Runs to 5:10 after last reading timestamp
  122. // Failed or no update re-attempts after 10 second delay
  123. // Changes to 30 second increments after 7:00
  124. // Changes to 1 minute increments after 10:00
  125. // Changes to 5 minute increments after 20:00 stale data
  126. func startDeviceStatusTimer(time: TimeInterval = 60 * 5) {
  127. deviceStatusTimer = Timer.scheduledTimer(timeInterval: time,
  128. target: self,
  129. selector: #selector(MainViewController.deviceStatusTimerDidEnd(_:)),
  130. userInfo: nil,
  131. repeats: false)
  132. }
  133. @objc func deviceStatusTimerDidEnd(_ timer:Timer) {
  134. // reset timer to 1 minute if settings aren't entered
  135. if UserDefaultsRepository.url.value == "" || !UserDefaultsRepository.loopUser.value {
  136. startDeviceStatusTimer(time: 60)
  137. return
  138. }
  139. if UserDefaultsRepository.url.value != "" {
  140. webLoadNSDeviceStatus()
  141. }
  142. }
  143. // Treatments Timer
  144. // Runs on 2 minute intervals
  145. // Pauses with stale BG data
  146. func startTreatmentsTimer(time: TimeInterval = 60 * 2) {
  147. treatmentsTimer = Timer.scheduledTimer(timeInterval: time,
  148. target: self,
  149. selector: #selector(MainViewController.treatmentsTimerDidEnd(_:)),
  150. userInfo: nil,
  151. repeats: false)
  152. }
  153. @objc func treatmentsTimerDidEnd(_ timer:Timer) {
  154. // reset timer to 1 minute if settings aren't entered
  155. if UserDefaultsRepository.url.value == "" || !UserDefaultsRepository.loopUser.value {
  156. startTreatmentsTimer(time: 60)
  157. return
  158. }
  159. if UserDefaultsRepository.url.value != "" && UserDefaultsRepository.downloadTreatments.value {
  160. WebLoadNSTreatments()
  161. }
  162. startTreatmentsTimer()
  163. }
  164. // Profile Timer
  165. // Runs on 10 minute intervals
  166. // Pauses with stale BG data
  167. func startProfileTimer(time: TimeInterval = 60 * 10) {
  168. profileTimer = Timer.scheduledTimer(timeInterval: time,
  169. target: self,
  170. selector: #selector(MainViewController.profileTimerDidEnd(_:)),
  171. userInfo: nil,
  172. repeats: false)
  173. }
  174. @objc func profileTimerDidEnd(_ timer:Timer) {
  175. // reset timer to 1 minute if settings aren't entered
  176. if UserDefaultsRepository.url.value == "" || !UserDefaultsRepository.loopUser.value {
  177. startProfileTimer(time: 60)
  178. return
  179. }
  180. if !isStaleData() && UserDefaultsRepository.url.value != "" {
  181. webLoadNSProfile()
  182. startProfileTimer()
  183. }
  184. }
  185. // Cancel and reset the playing alarm if it has not been snoozed after 4 min 50 seconds.
  186. // This allows the next BG reading to either start the timer going or not fire if the situation has been resolved
  187. func startAlarmPlayingTimer(time: TimeInterval = 290) {
  188. let alarmPlayingTimer = Timer.scheduledTimer(timeInterval: time,
  189. target: self,
  190. selector: #selector(MainViewController.alarmPlayingTimerDidEnd(_:)),
  191. userInfo: nil,
  192. repeats: false)
  193. }
  194. @objc func alarmPlayingTimerDidEnd(_ timer:Timer) {
  195. if AlarmSound.isPlaying {
  196. stopAlarmAtNextReading()
  197. }
  198. }
  199. // Alarm Timer
  200. // Run the alarm checker every 15 seconds
  201. func startAlarmTimer(time: TimeInterval) {
  202. alarmTimer = Timer.scheduledTimer(timeInterval: time,
  203. target: self,
  204. selector: #selector(MainViewController.alarmTimerDidEnd(_:)),
  205. userInfo: nil,
  206. repeats: true)
  207. }
  208. @objc func alarmTimerDidEnd(_ timer:Timer) {
  209. if bgData.count > 0 {
  210. self.checkAlarms(bgs: bgData)
  211. }
  212. if overrideGraphData.count > 0 {
  213. self.checkOverrideAlarms()
  214. }
  215. }
  216. // Calendar Timer
  217. // Run the calendar writer every 30 seconds
  218. func startCalendarTimer(time: TimeInterval) {
  219. calendarTimer = Timer.scheduledTimer(timeInterval: time,
  220. target: self,
  221. selector: #selector(MainViewController.calendarTimerDidEnd(_:)),
  222. userInfo: nil,
  223. repeats: true)
  224. }
  225. @objc func calendarTimerDidEnd(_ timer:Timer) {
  226. if UserDefaultsRepository.writeCalendarEvent.value && UserDefaultsRepository.calendarIdentifier.value != "" {
  227. self.writeCalendar()
  228. }
  229. }
  230. // Timer to allow us to write min ago calendar entries but not update them every 30 seconds
  231. func startCalTimer(time: TimeInterval) {
  232. calTimer = Timer.scheduledTimer(timeInterval: time,
  233. target: self,
  234. selector: #selector(MainViewController.calTimerDidEnd(_:)),
  235. userInfo: nil,
  236. repeats: false)
  237. }
  238. // Nothing should be done when this timer ends because it just blocks the calendar from writing when it's active
  239. @objc func calTimerDidEnd(_ timer:Timer) {
  240. }
  241. }