Procházet zdrojové kódy

Fix for false Not Looping alarm using bt-heartbeat

Jonas Björkert před 1 rokem
rodič
revize
718d223e79

+ 2 - 1
LoopFollow/Controllers/Alarms.swift

@@ -337,12 +337,12 @@ extension MainViewController {
         
         
         //check for not looping alert
         //check for not looping alert
         if IsNightscoutEnabled() {
         if IsNightscoutEnabled() {
+//            LogManager.shared.log(category: .alarm, message: "Checking NotLooping LastLoopTime was \(UserDefaultsRepository.alertLastLoopTime.value) that gives a diff of: \(Double(dateTimeUtils.getNowTimeIntervalUTC() - UserDefaultsRepository.alertLastLoopTime.value))")
             if UserDefaultsRepository.alertNotLoopingActive.value
             if UserDefaultsRepository.alertNotLoopingActive.value
                 && !UserDefaultsRepository.alertNotLoopingIsSnoozed.value
                 && !UserDefaultsRepository.alertNotLoopingIsSnoozed.value
                 && (Double(dateTimeUtils.getNowTimeIntervalUTC() - UserDefaultsRepository.alertLastLoopTime.value) >= Double(UserDefaultsRepository.alertNotLooping.value * 60))
                 && (Double(dateTimeUtils.getNowTimeIntervalUTC() - UserDefaultsRepository.alertLastLoopTime.value) >= Double(UserDefaultsRepository.alertNotLooping.value * 60))
                 && UserDefaultsRepository.alertLastLoopTime.value > 0 {
                 && UserDefaultsRepository.alertLastLoopTime.value > 0 {
                 
                 
-                var trigger = true
                 if (UserDefaultsRepository.alertNotLoopingUseLimits.value
                 if (UserDefaultsRepository.alertNotLoopingUseLimits.value
                     && (
                     && (
                         (Float(currentBG) >= UserDefaultsRepository.alertNotLoopingUpperLimit.value
                         (Float(currentBG) >= UserDefaultsRepository.alertNotLoopingUpperLimit.value
@@ -361,6 +361,7 @@ extension MainViewController {
                         if !UserDefaultsRepository.alertNotLoopingDayTimeAudible.value { playSound = false }
                         if !UserDefaultsRepository.alertNotLoopingDayTimeAudible.value { playSound = false }
                     }
                     }
                     triggerAlarm(sound: UserDefaultsRepository.alertNotLoopingSound.value, snooozedBGReadingTime: nil, overrideVolume: UserDefaultsRepository.overrideSystemOutputVolume.value, numLoops: numLoops, snoozeTime: UserDefaultsRepository.alertNotLoopingSnooze.value, audio: playSound)
                     triggerAlarm(sound: UserDefaultsRepository.alertNotLoopingSound.value, snooozedBGReadingTime: nil, overrideVolume: UserDefaultsRepository.overrideSystemOutputVolume.value, numLoops: numLoops, snoozeTime: UserDefaultsRepository.alertNotLoopingSnooze.value, audio: playSound)
+                    LogManager.shared.log(category: .alarm, message: "!!!Not Looping!!!")
                     return
                     return
                 }
                 }
             }
             }

+ 2 - 0
LoopFollow/Controllers/Nightscout/DeviceStatus.swift

@@ -182,5 +182,7 @@ extension MainViewController {
                 )
                 )
             }
             }
         }
         }
+//        LogManager.shared.log(category: .alarm, message: "updateDeviceStatusDisplay done")
+
     }
     }
 }
 }

+ 4 - 0
LoopFollow/Controllers/Nightscout/DeviceStatusOpenAPS.swift

@@ -33,7 +33,11 @@ extension MainViewController {
 
 
                 if wasEnacted {
                 if wasEnacted {
                     UserDefaultsRepository.alertLastLoopTime.value = lastLoopTime
                     UserDefaultsRepository.alertLastLoopTime.value = lastLoopTime
+//                    LogManager.shared.log(category: .alarm, message: "New LastLoopTime: \(lastLoopTime)")
+
                     evaluateNotLooping(lastLoopTime: UserDefaultsRepository.alertLastLoopTime.value)
                     evaluateNotLooping(lastLoopTime: UserDefaultsRepository.alertLastLoopTime.value)
+                } else {
+                    LogManager.shared.log(category: .alarm, message: "Last devicestatus was not enacted")
                 }
                 }
 
 
                 if let timestamp = enactedOrSuggested["timestamp"] as? String,
                 if let timestamp = enactedOrSuggested["timestamp"] as? String,

+ 35 - 26
LoopFollow/Task/TaskScheduler.swift

@@ -9,7 +9,7 @@
 import Foundation
 import Foundation
 import UIKit
 import UIKit
 
 
-enum TaskID {
+enum TaskID: CaseIterable {
     case profile
     case profile
     case deviceStatus
     case deviceStatus
     case treatments
     case treatments
@@ -39,8 +39,8 @@ class TaskScheduler {
 
 
     func scheduleTask(id: TaskID, nextRun: Date, action: @escaping () -> Void) {
     func scheduleTask(id: TaskID, nextRun: Date, action: @escaping () -> Void) {
         queue.async {
         queue.async {
-            let timeString = self.formatTime(nextRun)
-            LogManager.shared.log(category: .taskScheduler, message: "scheduleTask(\(id)): nextRun = \(timeString)")
+//            let timeString = self.formatTime(nextRun)
+//            LogManager.shared.log(category: .taskScheduler, message: "scheduleTask(\(id)): nextRun = \(timeString)")
             
             
             self.tasks[id] = ScheduledTask(nextRun: nextRun, action: action)
             self.tasks[id] = ScheduledTask(nextRun: nextRun, action: action)
             self.rescheduleTimer()
             self.rescheduleTimer()
@@ -48,13 +48,16 @@ class TaskScheduler {
     }
     }
 
 
     func rescheduleTask(id: TaskID, to newRunDate: Date) {
     func rescheduleTask(id: TaskID, to newRunDate: Date) {
+//        let timeString = self.formatTime(newRunDate)
+//        LogManager.shared.log(category: .taskScheduler, message: "rescheduleTask(\(id)): nextRun = \(timeString)")
+
         queue.async {
         queue.async {
             guard var existingTask = self.tasks[id] else {
             guard var existingTask = self.tasks[id] else {
                 return
                 return
             }
             }
             existingTask.nextRun = newRunDate
             existingTask.nextRun = newRunDate
             self.tasks[id] = existingTask
             self.tasks[id] = existingTask
-            self.rescheduleTimer()
+            self.checkTasksNow()
         }
         }
     }
     }
 
 
@@ -84,6 +87,7 @@ class TaskScheduler {
         let interval = earliestTask.nextRun.timeIntervalSinceNow
         let interval = earliestTask.nextRun.timeIntervalSinceNow
         let safeInterval = max(interval, 0)
         let safeInterval = max(interval, 0)
 
 
+        // Comment out this block to simulate heartbeat execution only
         DispatchQueue.main.async {
         DispatchQueue.main.async {
             self.currentTimer = Timer.scheduledTimer(withTimeInterval: safeInterval, repeats: false) { [weak self] _ in
             self.currentTimer = Timer.scheduledTimer(withTimeInterval: safeInterval, repeats: false) { [weak self] _ in
                 guard let self = self else { return }
                 guard let self = self else { return }
@@ -99,16 +103,35 @@ class TaskScheduler {
         BackgroundAlertManager.shared.scheduleBackgroundAlert()
         BackgroundAlertManager.shared.scheduleBackgroundAlert()
 
 
         let now = Date()
         let now = Date()
-        for (id, task) in tasks {
-            if task.nextRun <= now {
-                var updatedTask = task
-                updatedTask.nextRun = .distantFuture
-                tasks[id] = updatedTask
-
-                DispatchQueue.main.async {
-                    task.action()
+        let tasksToSkipAlarmCheck: Set<TaskID> = [.deviceStatus, .treatments, .fetchBG]
+
+        for taskID in TaskID.allCases {
+            guard let task = tasks[taskID], task.nextRun <= now else {
+                continue
+            }
+
+            // Check if we should skip alarmCheck
+            if taskID == .alarmCheck {
+                let shouldSkip = tasksToSkipAlarmCheck.contains {
+                    guard let checkTask = tasks[$0] else { return false }
+                    return checkTask.nextRun <= now || checkTask.nextRun == .distantFuture
+                }
+
+                if shouldSkip {
+//                    LogManager.shared.log(category: .taskScheduler, message: "Skipping alarmCheck because one of the specified tasks is due or set to distant future.")
+                    continue
                 }
                 }
             }
             }
+
+            var updatedTask = task
+            updatedTask.nextRun = .distantFuture
+            tasks[taskID] = updatedTask
+
+//            LogManager.shared.log(category: .taskScheduler, message: "Executing task \(taskID.description) at \(formatTime(now)).")
+
+            DispatchQueue.main.async {
+                task.action()
+            }
         }
         }
     }
     }
 
 
@@ -119,17 +142,3 @@ class TaskScheduler {
         return formatter.string(from: date)
         return formatter.string(from: date)
     }
     }
 }
 }
-
-private extension TaskID {
-    var description: String {
-        switch self {
-        case .profile: return "profile"
-        case .deviceStatus: return "deviceStatus"
-        case .fetchBG: return "fetchBG"
-        case .treatments: return "treatments"
-        case .calendarWrite: return "calendarWrite"
-        case .minAgoUpdate: return "minAgoUpdate"
-        case .alarmCheck: return "alarmCheck"
-        }
-    }
-}