Skip to content

Commit f0acfdd

Browse files
authored
Merge pull request #381 from loopandlearn/alarm-log
Add alarm log and some cleanup
2 parents 9e43be4 + 63b401f commit f0acfdd

File tree

4 files changed

+38
-32
lines changed

4 files changed

+38
-32
lines changed

LoopFollow/Controllers/Alarms.swift

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,12 @@
55
// Created by Jon Fawcett on 6/16/20.
66
// Copyright © 2020 Jon Fawcett. All rights reserved.
77
//
8-
//
9-
//
10-
//
11-
//
12-
//
13-
148

159
import Foundation
1610
import AVFoundation
1711
import CallKit
1812

1913
extension MainViewController {
20-
21-
2214
func checkAlarms(bgs: [ShareGlucoseData]) {
2315
// Don't check or fire alarms within 1 minute of prior alarm
2416
if checkAlarmTimer.isValid { return }
@@ -56,7 +48,6 @@ extension MainViewController {
5648

5749

5850
let currentBGTime = bgs[bgs.count - 1].date
59-
var alarmTriggered = false
6051
var numLoops = 0
6152
var playSound = true
6253
checkQuietHours()
@@ -401,15 +392,13 @@ extension MainViewController {
401392
// Get the latest bolus over the small bolus exclusion
402393
// Start with 0.0 bolus assuming there isn't one to cause a trigger and only add one if found
403394
var lastBolus = 0.0
404-
var lastBolusTime = 0.0
405395
var i = 1
406396
// check the boluses in reverse order setting it only if the time is after the carb time minus prebolus time.
407397
// This will make the loop stop at the most recent bolus that is over the minimum value or continue through all boluses
408398
while lastBolus < UserDefaultsRepository.alertMissedBolusIgnoreBolus.value && i <= bolusData.count {
409399
// Set the bolus if it's after the carb time minus prebolus time
410400
if (bolusData[bolusData.count - i].date >= lastCarbTime - Double(UserDefaultsRepository.alertMissedBolusPrebolus.value * 60)) {
411401
lastBolus = bolusData[bolusData.count - i].value
412-
lastBolusTime = bolusData[bolusData.count - i].date
413402
}
414403
i += 1
415404
}
@@ -693,6 +682,8 @@ extension MainViewController {
693682

694683
func triggerAlarm(sound: String, snooozedBGReadingTime: TimeInterval?, overrideVolume: Bool, numLoops: Int, snoozeTime: Int = 0, snoozeIncrement: Int = 5, audio: Bool = true)
695684
{
685+
LogManager.shared.log(category: .alarm, message: "Alarm triggered: \(AlarmSound.whichAlarm)")
686+
696687
var audioDuringCall = true
697688
if !UserDefaultsRepository.alertAudioDuringPhone.value && isOnPhoneCall() { audioDuringCall = false }
698689

@@ -909,13 +900,8 @@ extension MainViewController {
909900
func checkQuietHours() {
910901
if UserDefaultsRepository.quietHourStart.value == nil || UserDefaultsRepository.quietHourEnd.value == nil { return }
911902

912-
var startDateComponents = DateComponents()
913-
914903
let today = Date()
915904
let todayCalendar = Calendar.current
916-
let month = todayCalendar.component(.month, from: today)
917-
let day = todayCalendar.component(.day, from: today)
918-
let year = todayCalendar.component(.year, from: today)
919905
let hour = todayCalendar.component(.hour, from: today)
920906
let minute = todayCalendar.component(.minute, from: today)
921907
let todayMinutes = (60 * hour) + minute

LoopFollow/Controllers/Nightscout/BGData.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ extension MainViewController {
1919
dexShare?.fetchData(count) { (err, result) -> () in
2020

2121
if let error = err {
22-
LogManager.shared.log(category: .dexcom, message: "Error fetching Dexcom data: \(error.localizedDescription)")
22+
LogManager.shared.log(category: .dexcom, message: "Error fetching Dexcom data: \(error.localizedDescription)", limitIdentifier: "Error fetching Dexcom data")
2323
self.webLoadNSBGData()
2424
return
2525
}
2626

2727
guard let data = result else {
28-
LogManager.shared.log(category: .dexcom, message: "Received nil data from Dexcom")
28+
LogManager.shared.log(category: .dexcom, message: "Received nil data from Dexcom", limitIdentifier: "Received nil data from Dexcom")
2929
self.webLoadNSBGData()
3030
return
3131
}
@@ -34,7 +34,7 @@ extension MainViewController {
3434
let latestDate = data[0].date
3535
let now = dateTimeUtils.getNowTimeIntervalUTC()
3636
if (latestDate + 330) < now && IsNightscoutEnabled() {
37-
LogManager.shared.log(category: .dexcom, message: "Dexcom data is old, loading from NS instead")
37+
LogManager.shared.log(category: .dexcom, message: "Dexcom data is old, loading from NS instead", limitIdentifier: "Dexcom data is old, loading from NS instead")
3838
self.webLoadNSBGData()
3939
return
4040
}
@@ -105,7 +105,7 @@ extension MainViewController {
105105
self.ProcessDexBGData(data: nsData2, sourceName: sourceName)
106106
}
107107
case .failure(let error):
108-
LogManager.shared.log(category: .nightscout, message: "Failed to fetch data: \(error)")
108+
LogManager.shared.log(category: .nightscout, message: "Failed to fetch bg data: \(error)", limitIdentifier: "Failed to fetch bg data")
109109
DispatchQueue.main.async {
110110
TaskScheduler.shared.rescheduleTask(
111111
id: .fetchBG,
@@ -126,7 +126,7 @@ extension MainViewController {
126126
let graphHours = 24 * UserDefaultsRepository.downloadDays.value
127127

128128
guard !data.isEmpty else {
129-
LogManager.shared.log(category: .nightscout, message: "No bg data received. Skipping processing.")
129+
LogManager.shared.log(category: .nightscout, message: "No bg data received. Skipping processing.", limitIdentifier: "No bg data received. Skipping processing.")
130130
return
131131
}
132132

LoopFollow/Controllers/Nightscout/DeviceStatus.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,11 @@ extension MainViewController {
3030
}
3131

3232
private func handleDeviceStatusError() {
33-
LogManager.shared.log(category: .deviceStatus, message: "Device status fetch failed!")
33+
LogManager.shared.log(category: .deviceStatus, message: "Device status fetch failed!", limitIdentifier: "Device status fetch failed!")
3434
DispatchQueue.main.async {
3535
TaskScheduler.shared.rescheduleTask(id: .deviceStatus, to: Date().addingTimeInterval(10))
36+
self.evaluateNotLooping()
3637
}
37-
38-
evaluateNotLooping()
3938
}
4039

4140
func evaluateNotLooping() {

LoopFollow/Log/LogManager.swift

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ class LogManager {
1515
private let logDirectory: URL
1616
private let dateFormatter: DateFormatter
1717
private let consoleQueue = DispatchQueue(label: "com.loopfollow.log.console", qos: .background)
18+
19+
private let rateLimitQueue = DispatchQueue(label: "com.loopfollow.log.ratelimit")
20+
private var lastLoggedTimestamps: [String: Date] = [:]
1821

1922
enum Category: String, CaseIterable {
2023
case bluetooth = "Bluetooth"
@@ -30,26 +33,46 @@ class LogManager {
3033
}
3134

3235
init() {
33-
// Create log directory in the app's Documents folder
3436
let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
3537
logDirectory = documentsDirectory.appendingPathComponent("Logs")
36-
37-
// Ensure the directory exists
3838
if !fileManager.fileExists(atPath: logDirectory.path) {
3939
try? fileManager.createDirectory(at: logDirectory, withIntermediateDirectories: true, attributes: nil)
4040
}
41-
4241
dateFormatter = DateFormatter()
4342
dateFormatter.dateFormat = "yyyy-MM-dd"
4443
}
45-
46-
func log(category: Category, message: String, isDebug: Bool = false) {
44+
45+
/// Logs a message with an optional rate limit.
46+
///
47+
/// - Parameters:
48+
/// - category: The log category.
49+
/// - message: The message to log.
50+
/// - isDebug: Indicates if this is a debug log.
51+
/// - limitIdentifier: Optional key to rate-limit similar log messages.
52+
/// - limitInterval: Time interval (in seconds) to wait before logging the same type again.
53+
func log(category: Category, message: String, isDebug: Bool = false, limitIdentifier: String? = nil, limitInterval: TimeInterval = 300) {
4754
let timestamp = DateFormatter.localizedString(from: Date(), dateStyle: .none, timeStyle: .medium)
4855
let logMessage = "[\(timestamp)] [\(category.rawValue)] \(message)"
4956

5057
consoleQueue.async {
5158
print(logMessage)
5259
}
60+
61+
if let key = limitIdentifier, !Storage.shared.debugLogLevel.value {
62+
let shouldLog: Bool = rateLimitQueue.sync {
63+
if let lastLogged = lastLoggedTimestamps[key] {
64+
let interval = Date().timeIntervalSince(lastLogged)
65+
if interval < limitInterval {
66+
return false
67+
}
68+
}
69+
lastLoggedTimestamps[key] = Date()
70+
return true
71+
}
72+
if !shouldLog {
73+
return
74+
}
75+
}
5376

5477
if !isDebug || Storage.shared.debugLogLevel.value {
5578
let logFileURL = self.currentLogFileURL
@@ -60,7 +83,6 @@ class LogManager {
6083
func cleanupOldLogs() {
6184
let today = dateFormatter.string(from: Date())
6285
let yesterday = dateFormatter.string(from: Calendar.current.date(byAdding: .day, value: -1, to: Date())!)
63-
6486
do {
6587
let logFiles = try fileManager.contentsOfDirectory(at: logDirectory, includingPropertiesForKeys: nil)
6688
for logFile in logFiles {
@@ -93,7 +115,6 @@ class LogManager {
93115
if !fileManager.fileExists(atPath: fileURL.path) {
94116
fileManager.createFile(atPath: fileURL.path, contents: nil, attributes: nil)
95117
}
96-
97118
if let fileHandle = try? FileHandle(forWritingTo: fileURL) {
98119
defer { fileHandle.closeFile() }
99120
fileHandle.seekToEndOfFile()

0 commit comments

Comments
 (0)