Просмотр исходного кода

Add: Persistent and Predictive Lows

Jon Fawcett 5 лет назад
Родитель
Сommit
2c4a8e04b0

+ 28 - 6
LoopFollow/Controllers/Alarms.swift

@@ -113,9 +113,31 @@ extension MainViewController {
             }
             
             // Check Low
-            if UserDefaultsRepository.alertLowActive.value && !UserDefaultsRepository.alertUrgentLowIsSnoozed.value &&
-                Float(currentBG) <= UserDefaultsRepository.alertLowBG.value && !UserDefaultsRepository.alertLowIsSnoozed.value {
-                AlarmSound.whichAlarm = "Low Alert"
+            let persistentLowReadings = Int(UserDefaultsRepository.alertLowPersistent.value / 5)
+            let persistentLowBG = bgData[bgData.count - 1 - persistentLowReadings].sgv
+            let persistentLowTriggerImmediatelyBG = UserDefaultsRepository.alertLowBG.value - UserDefaultsRepository.alertLowPersistenceMax.value
+            let predictiveNumReadings = Int(UserDefaultsRepository.alertLowPredictiveMinutes.value / 5)
+            var predictiveTrigger = false
+            for i in 0..<predictiveNumReadings {
+                if Float(predictionData[i].sgv) <= persistentLowTriggerImmediatelyBG {
+                    predictiveTrigger = true
+                }
+            }
+            if UserDefaultsRepository.alertLowActive.value &&
+                !UserDefaultsRepository.alertUrgentLowIsSnoozed.value &&
+                !UserDefaultsRepository.alertLowIsSnoozed.value &&
+                (Float(currentBG) <= UserDefaultsRepository.alertLowBG.value &&
+                (Float(persistentLowBG) <= UserDefaultsRepository.alertLowBG.value || Float(currentBG) <= persistentLowTriggerImmediatelyBG)
+                || predictiveTrigger == true
+                )
+                 {
+                
+                if predictiveTrigger && Float(currentBG) > UserDefaultsRepository.alertLowBG.value {
+                    AlarmSound.whichAlarm = "Predictive Low Alert"
+                } else {
+                    AlarmSound.whichAlarm = "Low Alert"
+                }
+                
   
                 //determine if it is day or night and what should happen
                 if UserDefaultsRepository.nightTime.value {
@@ -155,12 +177,12 @@ extension MainViewController {
             }
             
             // Check High
-            let persistentReadings = Int(UserDefaultsRepository.alertHighPersistent.value / 5)
-            let persistentBG = bgData[bgData.count - 1 - persistentReadings].sgv
+            let persistentHighReadings = Int(UserDefaultsRepository.alertHighPersistent.value / 5)
+            let persistentHighBG = bgData[bgData.count - 1 - persistentHighReadings].sgv
             if UserDefaultsRepository.alertHighActive.value &&
                 !UserDefaultsRepository.alertHighIsSnoozed.value &&
                 Float(currentBG) >= UserDefaultsRepository.alertHighBG.value &&
-                Float(persistentBG) >= UserDefaultsRepository.alertHighBG.value &&
+                Float(persistentHighBG) >= UserDefaultsRepository.alertHighBG.value &&
                 !UserDefaultsRepository.alertHighIsSnoozed.value {
                 AlarmSound.whichAlarm = "High Alert"
                 //determine if it is day or night and what should happen

+ 44 - 1
LoopFollow/ViewControllers/AlarmViewController.swift

@@ -691,7 +691,7 @@ class AlarmViewController: FormViewController {
     
     func buildLow(){
         form
-            +++ Section(header: "Low Alert", footer: "Alerts when BG drops below value") { row in
+            +++ Section(header: "Low Alert", footer: "Alerts when BG drops below value. Persitent for minutes will allow the alert to be ignored within the Delta value to prevent alerts that Loop self-corrected the drop. Predictive minutes looks forward to Loop's prediction and will trigger an alert if a low is predicted within that time frame. Predictive uses the minimum persistence Delta value for the trigger.") { row in
                 row.hidden = "$bgAlerts != 'Low'"
             }
         <<< SwitchRow("alertLowActive"){ row in
@@ -715,6 +715,49 @@ class AlarmViewController: FormViewController {
                 guard let value = row.value else { return }
                 UserDefaultsRepository.alertLowBG.value = Float(value)
         }
+        <<< StepperRow("alertLowPersistent") { row in
+            row.title = "Persistent For (Minutes)"
+            row.cell.stepper.stepValue = 5
+            row.cell.stepper.minimumValue = 0
+            row.cell.stepper.maximumValue = 240
+            row.value = Double(UserDefaultsRepository.alertLowPersistent.value)
+            row.displayValueFor = { value in
+                guard let value = value else { return nil }
+                return "\(Int(value))"
+            }
+        }.onChange { [weak self] row in
+                guard let value = row.value else { return }
+                UserDefaultsRepository.alertLowPersistent.value = Int(value)
+        }
+            <<< StepperRow("alertLowPersistenceMax") { row in
+                row.title = "Ignore Persistence (-Delta)"
+                row.cell.stepper.stepValue = 1
+                row.cell.stepper.minimumValue = 0
+                row.cell.stepper.maximumValue = 20
+                row.value = Double(UserDefaultsRepository.alertLowPersistenceMax.value)
+                row.displayValueFor = { value in
+                    guard let value = value else { return nil }
+                    return bgUnits.toDisplayUnits(String(value))
+                }
+            }.onChange { [weak self] row in
+                    guard let value = row.value else { return }
+                    UserDefaultsRepository.alertLowPersistenceMax.value = Float(value)
+            }
+        
+            <<< StepperRow("alertLowPredictiveMinutes") { row in
+                row.title = "Predictive Low (Minutes)"
+                row.cell.stepper.stepValue = 5
+                row.cell.stepper.minimumValue = 0
+                row.cell.stepper.maximumValue = 60
+                row.value = Double(UserDefaultsRepository.alertLowPredictiveMinutes.value)
+                row.displayValueFor = { value in
+                    guard let value = value else { return nil }
+                    return "\(Int(value))"
+                }
+            }.onChange { [weak self] row in
+                    guard let value = row.value else { return }
+                    UserDefaultsRepository.alertLowPredictiveMinutes.value = Int(value)
+            }
         <<< StepperRow("alertLowSnooze") { row in
             row.title = "Snooze"
             row.cell.stepper.stepValue = 5

+ 6 - 0
LoopFollow/ViewControllers/SnoozeViewController.swift

@@ -141,6 +141,12 @@ class SnoozeViewController: UIViewController, UNUserNotificationCenterDelegate {
             guard let alarms = self.tabBarController!.viewControllers?[1] as? AlarmViewController else { return }
             alarms.reloadIsSnoozed(key: "alertLowIsSnoozed", value: true)
             alarms.reloadSnoozeTime(key: "alertLowSnoozedTime", setNil: false, value: Date().addingTimeInterval(TimeInterval(snoozeForMinuteStepper.value * 60)))
+        } else if AlarmSound.whichAlarm == "Predictive Low Alert" {
+            UserDefaultsRepository.alertLowIsSnoozed.value = true
+            UserDefaultsRepository.alertLowSnoozedTime.value = Date().addingTimeInterval(TimeInterval(snoozeForMinuteStepper.value * 60))
+            guard let alarms = self.tabBarController!.viewControllers?[1] as? AlarmViewController else { return }
+            alarms.reloadIsSnoozed(key: "alertLowIsSnoozed", value: true)
+            alarms.reloadSnoozeTime(key: "alertLowSnoozedTime", setNil: false, value: Date().addingTimeInterval(TimeInterval(snoozeForMinuteStepper.value * 60)))
         } else if AlarmSound.whichAlarm == "High Alert" {
             UserDefaultsRepository.alertHighIsSnoozed.value = true
             UserDefaultsRepository.alertHighSnoozedTime.value = Date().addingTimeInterval(TimeInterval(snoozeForMinuteStepper.value * 60))

+ 3 - 0
LoopFollow/repository/UserDefaults.swift

@@ -145,6 +145,9 @@ class UserDefaultsRepository {
     
     static let alertLowActive = UserDefaultsValue<Bool>(key: "alertLowActive", default: false)
     static let alertLowBG = UserDefaultsValue<Float>(key: "alertLowBG", default: 70.0)
+    static let alertLowPersistent = UserDefaultsValue<Int>(key: "alertLowPersistent", default: 0)
+    static let alertLowPersistenceMax = UserDefaultsValue<Float>(key: "alertLowPersistenceMax", default: 5.0)
+    static let alertLowPredictiveMinutes = UserDefaultsValue<Int>(key: "alertLowPredictiveMinutes", default: 0)
     static let alertLowSnooze = UserDefaultsValue<Int>(key: "alertLowSnooze", default: 5)
     static let alertLowSnoozedTime = UserDefaultsValue<Date?>(key: "alertLowSnoozedTime", default: nil)
     static let alertLowIsSnoozed = UserDefaultsValue<Bool>(key: "alertLowIsSnoozed", default: false)