Timers.swift 13 KB

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