Skip to content

Commit

Permalink
Fix for false Not Looping alarm using bt-heartbeat
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorkert committed Jan 23, 2025
1 parent 909beab commit 718d223
Showing 4 changed files with 43 additions and 27 deletions.
3 changes: 2 additions & 1 deletion LoopFollow/Controllers/Alarms.swift
Original file line number Diff line number Diff line change
@@ -337,12 +337,12 @@ extension MainViewController {

//check for not looping alert
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
&& !UserDefaultsRepository.alertNotLoopingIsSnoozed.value
&& (Double(dateTimeUtils.getNowTimeIntervalUTC() - UserDefaultsRepository.alertLastLoopTime.value) >= Double(UserDefaultsRepository.alertNotLooping.value * 60))
&& UserDefaultsRepository.alertLastLoopTime.value > 0 {

var trigger = true
if (UserDefaultsRepository.alertNotLoopingUseLimits.value
&& (
(Float(currentBG) >= UserDefaultsRepository.alertNotLoopingUpperLimit.value
@@ -361,6 +361,7 @@ extension MainViewController {
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)
LogManager.shared.log(category: .alarm, message: "!!!Not Looping!!!")
return
}
}
2 changes: 2 additions & 0 deletions LoopFollow/Controllers/Nightscout/DeviceStatus.swift
Original file line number Diff line number Diff line change
@@ -182,5 +182,7 @@ extension MainViewController {
)
}
}
// LogManager.shared.log(category: .alarm, message: "updateDeviceStatusDisplay done")

}
}
4 changes: 4 additions & 0 deletions LoopFollow/Controllers/Nightscout/DeviceStatusOpenAPS.swift
Original file line number Diff line number Diff line change
@@ -33,7 +33,11 @@ extension MainViewController {

if wasEnacted {
UserDefaultsRepository.alertLastLoopTime.value = lastLoopTime
// LogManager.shared.log(category: .alarm, message: "New LastLoopTime: \(lastLoopTime)")

evaluateNotLooping(lastLoopTime: UserDefaultsRepository.alertLastLoopTime.value)
} else {
LogManager.shared.log(category: .alarm, message: "Last devicestatus was not enacted")
}

if let timestamp = enactedOrSuggested["timestamp"] as? String,
61 changes: 35 additions & 26 deletions LoopFollow/Task/TaskScheduler.swift
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
import Foundation
import UIKit

enum TaskID {
enum TaskID: CaseIterable {
case profile
case deviceStatus
case treatments
@@ -39,22 +39,25 @@ class TaskScheduler {

func scheduleTask(id: TaskID, nextRun: Date, action: @escaping () -> Void) {
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.rescheduleTimer()
}
}

func rescheduleTask(id: TaskID, to newRunDate: Date) {
// let timeString = self.formatTime(newRunDate)
// LogManager.shared.log(category: .taskScheduler, message: "rescheduleTask(\(id)): nextRun = \(timeString)")

queue.async {
guard var existingTask = self.tasks[id] else {
return
}
existingTask.nextRun = newRunDate
self.tasks[id] = existingTask
self.rescheduleTimer()
self.checkTasksNow()
}
}

@@ -84,6 +87,7 @@ class TaskScheduler {
let interval = earliestTask.nextRun.timeIntervalSinceNow
let safeInterval = max(interval, 0)

// Comment out this block to simulate heartbeat execution only
DispatchQueue.main.async {
self.currentTimer = Timer.scheduledTimer(withTimeInterval: safeInterval, repeats: false) { [weak self] _ in
guard let self = self else { return }
@@ -99,16 +103,35 @@ class TaskScheduler {
BackgroundAlertManager.shared.scheduleBackgroundAlert()

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)
}
}

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"
}
}
}

0 comments on commit 718d223

Please sign in to comment.