Skip to content

Commit 382b2cb

Browse files
authored
Merge pull request #432 from loopandlearn/debounce-alarm-checks
Debounce alarm checks and improve scheduling logic
2 parents 8b8d2ab + 309d6ea commit 382b2cb

File tree

6 files changed

+16
-24
lines changed

6 files changed

+16
-24
lines changed

LoopFollow/Alarm/AlarmCondition/RecBolusCondition.swift

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ struct RecBolusCondition: AlarmCondition {
1111

1212
func evaluate(alarm: Alarm, data: AlarmData, now _: Date) -> Bool {
1313
// ────────────────────────────────
14-
// 0. sanity checks
14+
// Reset alarm if below threshold
1515
// ────────────────────────────────
1616
guard let threshold = alarm.threshold, threshold > 0 else { return false }
1717
guard let rec = data.recBolus, rec >= threshold else {
@@ -20,13 +20,20 @@ struct RecBolusCondition: AlarmCondition {
2020
}
2121

2222
// ────────────────────────────────
23-
// 1. has it INCREASED past the last-notified value?
23+
// Check if we should alert (increase or first time)
2424
// ────────────────────────────────
25+
let shouldAlert: Bool
2526
if let last = Storage.shared.lastRecBolusNotified.value {
26-
if rec <= last + 1e-4 { return false }
27+
// Only alert if there's been more than 5% increase
28+
shouldAlert = rec > last * 1.05
29+
} else {
30+
// First time above threshold - alert
31+
shouldAlert = true
2732
}
2833

34+
// Always update the stored value when above threshold
2935
Storage.shared.lastRecBolusNotified.value = rec
30-
return true
36+
37+
return shouldAlert
3138
}
3239
}

LoopFollow/Alarm/AlarmManager.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ class AlarmManager {
105105
// If this alarm is active, but no longer fulfill the requirements, stop it.
106106
// Continue evaluating other alarams
107107
if Observable.shared.currentAlarm.value == alarm.id {
108+
LogManager.shared.log(category: .alarm, message: "Stopping alarm \(alarm) because it no longer meets its requirements", isDebug: true)
109+
108110
stopAlarm()
109111
}
110112

LoopFollow/Controllers/Nightscout/BGData.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ extension MainViewController {
171171
LogManager.shared.log(category: .nightscout,
172172
message: "Fresh reading. Scheduling next fetch in \(delayToSchedule) seconds.",
173173
isDebug: true)
174-
TaskScheduler.shared.rescheduleTask(id: .alarmCheck, to: Date())
174+
TaskScheduler.shared.rescheduleTask(id: .alarmCheck, to: Date().addingTimeInterval(3))
175175
}
176176

177177
TaskScheduler.shared.rescheduleTask(id: .fetchBG, to: Date().addingTimeInterval(delayToSchedule))

LoopFollow/Controllers/Nightscout/DeviceStatus.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ extension MainViewController {
199199
id: .deviceStatus,
200200
to: Date().addingTimeInterval(interval)
201201
)
202-
TaskScheduler.shared.rescheduleTask(id: .alarmCheck, to: Date())
202+
TaskScheduler.shared.rescheduleTask(id: .alarmCheck, to: Date().addingTimeInterval(3))
203203
}
204204
}
205205

LoopFollow/Task/TaskScheduler.swift

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -90,29 +90,12 @@ class TaskScheduler {
9090
BackgroundAlertManager.shared.scheduleBackgroundAlert()
9191

9292
let now = Date()
93-
let tasksToSkipAlarmCheck: Set<TaskID> = [.deviceStatus, .treatments, .fetchBG]
9493

9594
for taskID in TaskID.allCases {
9695
guard let task = tasks[taskID], task.nextRun <= now else {
9796
continue
9897
}
9998

100-
// Skip alarm checks if data-fetching tasks (deviceStatus, treatments, fetchBG) are currently due.
101-
// This ensures alarms are evaluated with the latest data, avoiding premature or incorrect triggers.
102-
// If skipped, reschedule alarmCheck 1 second later to retry after data updates.
103-
if taskID == .alarmCheck {
104-
let shouldSkip = tasksToSkipAlarmCheck.contains {
105-
guard let checkTask = tasks[$0] else { return false }
106-
return checkTask.nextRun <= now || checkTask.nextRun == .distantFuture
107-
}
108-
if shouldSkip {
109-
guard var existingTask = tasks[taskID] else { continue }
110-
existingTask.nextRun = Date().addingTimeInterval(1)
111-
tasks[taskID] = existingTask
112-
continue
113-
}
114-
}
115-
11699
var updatedTask = task
117100
updatedTask.nextRun = .distantFuture
118101
tasks[taskID] = updatedTask

LoopFollow/Task/TreatmentsTask.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ extension MainViewController {
2323
WebLoadNSTreatments()
2424

2525
TaskScheduler.shared.rescheduleTask(id: .treatments, to: Date().addingTimeInterval(2 * 60))
26-
TaskScheduler.shared.rescheduleTask(id: .alarmCheck, to: Date())
26+
TaskScheduler.shared.rescheduleTask(id: .alarmCheck, to: Date().addingTimeInterval(3))
2727
}
2828
}

0 commit comments

Comments
 (0)