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

Add IOB/COB Alerts, Move Predictive to Urgent Low

Jon Fawcett 4 лет назад
Родитель
Сommit
9036a207ec

+ 60 - 19
LoopFollow/Controllers/Alarms.swift

@@ -65,6 +65,42 @@ extension MainViewController {
             return
         }
         
+        // Check IOB
+        if UserDefaultsRepository.alertIOB.value && !UserDefaultsRepository.alertIOBIsSnoozed.value {
+            let alertAt = Double(UserDefaultsRepository.alertIOBAt.value)
+            if Double(latestIOB) ?? 0 >= alertAt {
+                AlarmSound.whichAlarm = "IOB Alert"
+                //determine if it is day or night and what should happen
+                if UserDefaultsRepository.nightTime.value {
+                    if UserDefaultsRepository.alertIOBNightTime.value { numLoops = -1 }
+                    if !UserDefaultsRepository.alertIOBNightTimeAudible.value { playSound = false }
+                } else {
+                    if UserDefaultsRepository.alertIOBDayTime.value { numLoops = -1 }
+                    if !UserDefaultsRepository.alertIOBDayTimeAudible.value { playSound = false }
+                }
+                triggerAlarm(sound: UserDefaultsRepository.alertIOBSound.value, snooozedBGReadingTime: nil, overrideVolume: UserDefaultsRepository.overrideSystemOutputVolume.value, numLoops: numLoops, snoozeTime: UserDefaultsRepository.alertIOBSnoozeHours.value, snoozeIncrement: 1, audio: playSound)
+                return
+            }
+        }
+        
+        // Check COB
+        if UserDefaultsRepository.alertCOB.value && !UserDefaultsRepository.alertCOBIsSnoozed.value {
+            let alertAt = Double(UserDefaultsRepository.alertCOBAt.value)
+            if Double(latestCOB) ?? 0 >= alertAt {
+                AlarmSound.whichAlarm = "COB Alert"
+                //determine if it is day or night and what should happen
+                if UserDefaultsRepository.nightTime.value {
+                    if UserDefaultsRepository.alertCOBNightTime.value { numLoops = -1 }
+                    if !UserDefaultsRepository.alertCOBNightTimeAudible.value { playSound = false }
+                } else {
+                    if UserDefaultsRepository.alertCOBDayTime.value { numLoops = -1 }
+                    if !UserDefaultsRepository.alertCOBDayTimeAudible.value { playSound = false }
+                }
+                triggerAlarm(sound: UserDefaultsRepository.alertCOBSound.value, snooozedBGReadingTime: nil, overrideVolume: UserDefaultsRepository.overrideSystemOutputVolume.value, numLoops: numLoops, snoozeTime: UserDefaultsRepository.alertCOBSnoozeHours.value, snoozeIncrement: 1, audio: playSound)
+                return
+            }
+        }
+        
         
         // BG Based Alarms
         // Check to make sure it is a current reading and has not already triggered alarm from this reading
@@ -92,11 +128,29 @@ extension MainViewController {
             }
             
             // Check Urgent Low
+            
+            let predictiveNumReadings = Int(UserDefaultsRepository.alertUrgentLowPredictiveMinutes.value / 5)
+            var predictiveTrigger = false
+            if  !predictionData.isEmpty {
+                for i in 0..<predictiveNumReadings {
+                    if predictionData.count > i {
+                        if Float(predictionData[i].sgv) <= UserDefaultsRepository.alertUrgentLowBG.value {
+                            predictiveTrigger = true
+                        }
+                    }
+                }
+            }
             if UserDefaultsRepository.alertUrgentLowActive.value && !UserDefaultsRepository.alertUrgentLowIsSnoozed.value &&
-                Float(currentBG) <= UserDefaultsRepository.alertUrgentLowBG.value {
+                (Float(currentBG) <= UserDefaultsRepository.alertUrgentLowBG.value || predictiveTrigger) {
                 // Separating this makes it so the low or drop alerts won't trigger if they already snoozed the urgent low
                 if !UserDefaultsRepository.alertUrgentLowIsSnoozed.value {
-                    AlarmSound.whichAlarm = "Urgent Low Alert"
+                    
+                    if predictiveTrigger {
+                        AlarmSound.whichAlarm = "Predicted Urgent Low Alert"
+                    } else {
+                        AlarmSound.whichAlarm = "Urgent Low Alert"
+                    }
+                    
                     //determine if it is day or night and what should happen
                     if UserDefaultsRepository.nightTime.value {
                         if UserDefaultsRepository.alertUrgentLowNightTime.value { numLoops = -1 }
@@ -116,31 +170,18 @@ extension MainViewController {
             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
-            if  !predictionData.isEmpty {
-                for i in 0..<predictiveNumReadings {
-                    if predictionData.count > i {
-                        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
+                 (Float(persistentLowBG) <= UserDefaultsRepository.alertLowBG.value || Float(currentBG) <= persistentLowTriggerImmediatelyBG)
                 )
                  {
                 
-                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

+ 344 - 14
LoopFollow/ViewControllers/AlarmViewController.swift

@@ -264,6 +264,9 @@ class AlarmViewController: FormViewController {
             let otherRow3 = self?.form.rowBy(tag: "otherAlerts2") as! SegmentedRow<String>
             otherRow3.value = nil
             otherRow3.reload()
+            let otherRow4 = self?.form.rowBy(tag: "otherAlerts3") as! SegmentedRow<String>
+            otherRow4.value = nil
+            otherRow4.reload()
             row.value = value
         }
             <<< SegmentedRow<String>("bgExtraAlerts"){ row in
@@ -281,6 +284,9 @@ class AlarmViewController: FormViewController {
             let otherRow3 = self?.form.rowBy(tag: "otherAlerts2") as! SegmentedRow<String>
             otherRow3.value = nil
             otherRow3.reload()
+            let otherRow4 = self?.form.rowBy(tag: "otherAlerts3") as! SegmentedRow<String>
+            otherRow4.value = nil
+            otherRow4.reload()
             row.value = value
         }
             <<< SegmentedRow<String>("otherAlerts"){ row in
@@ -302,6 +308,9 @@ class AlarmViewController: FormViewController {
             let otherRow3 = self?.form.rowBy(tag: "otherAlerts2") as! SegmentedRow<String>
             otherRow3.value = nil
             otherRow3.reload()
+            let otherRow4 = self?.form.rowBy(tag: "otherAlerts3") as! SegmentedRow<String>
+            otherRow4.value = nil
+            otherRow4.reload()
             row.value = value
         }
         <<< SegmentedRow<String>("otherAlerts2"){ row in
@@ -322,6 +331,33 @@ class AlarmViewController: FormViewController {
             let otherRow3 = self?.form.rowBy(tag: "otherAlerts") as! SegmentedRow<String>
             otherRow3.value = nil
             otherRow3.reload()
+            let otherRow4 = self?.form.rowBy(tag: "otherAlerts3") as! SegmentedRow<String>
+            otherRow4.value = nil
+            otherRow4.reload()
+            row.value = value
+        }
+        
+        <<< SegmentedRow<String>("otherAlerts3"){ row in
+                row.title = ""
+                row.options = ["IOB", "COB"]
+                if UserDefaultsRepository.url.value == "" {
+                    row.hidden = true
+                }
+                //row.value = "Not Looping"
+        }.onChange { [weak self] row in
+             guard let value = row.value else { return }
+            let otherRow = self?.form.rowBy(tag: "bgExtraAlerts") as! SegmentedRow<String>
+           otherRow.value = nil
+           otherRow.reload()
+           let otherRow2 = self?.form.rowBy(tag: "bgAlerts") as! SegmentedRow<String>
+           otherRow2.value = nil
+           otherRow2.reload()
+            let otherRow3 = self?.form.rowBy(tag: "otherAlerts") as! SegmentedRow<String>
+            otherRow3.value = nil
+            otherRow3.reload()
+            let otherRow4 = self?.form.rowBy(tag: "otherAlerts2") as! SegmentedRow<String>
+            otherRow4.value = nil
+            otherRow4.reload()
             row.value = value
         }
         
@@ -351,6 +387,9 @@ class AlarmViewController: FormViewController {
         buildOverrideEnd()
         buildPump()
         
+        buildIOB()
+        buildCOB()
+        
         buildSnoozeAll()
         buildAppInactive()
         buildAlarmSettings()
@@ -569,6 +608,20 @@ class AlarmViewController: FormViewController {
                 guard let value = row.value else { return }
                 UserDefaultsRepository.alertUrgentLowBG.value = Float(value)
         }
+        <<< StepperRow("alertUrgentLowPredictiveMinutes") { row in
+            row.title = "Predictive (Minutes)"
+            row.cell.stepper.stepValue = 5
+            row.cell.stepper.minimumValue = 0
+            row.cell.stepper.maximumValue = 60
+            row.value = Double(UserDefaultsRepository.alertUrgentLowPredictiveMinutes.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.alertUrgentLowPredictiveMinutes.value = Int(value)
+        }
         <<< StepperRow("alertUrgentLowSnooze") { row in
             row.title = "Default Snooze"
             row.cell.stepper.stepValue = 5
@@ -744,20 +797,7 @@ class AlarmViewController: FormViewController {
                     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
@@ -2795,6 +2835,296 @@ class AlarmViewController: FormViewController {
                 }
         }
     }
+    
+    func buildIOB() {
+        form
+            +++ Section(header: "IOB", footer: "Alert will trigger when IOB is above value") { row in
+                row.hidden = "$otherAlerts3 != 'IOB'"
+            }
+            <<< SwitchRow("alertIOB"){ row in
+                row.title = "Active"
+                row.value = UserDefaultsRepository.alertIOB.value
+            }.onChange { [weak self] row in
+                guard let value = row.value else { return }
+                UserDefaultsRepository.alertIOB.value = value
+            }
+            
+            <<< StepperRow("alertIOBAt") { row in
+                row.title = "IOB >="
+                row.cell.stepper.stepValue = 1
+                row.cell.stepper.minimumValue = 1
+                row.cell.stepper.maximumValue = 50
+                row.value = Double(UserDefaultsRepository.alertIOBAt.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.alertIOBAt.value = Int(value)
+            }
+            
+            <<< StepperRow("alertIOBSnoozeHours") { row in
+                row.title = "Snooze Hours"
+                row.cell.stepper.stepValue = 1
+                row.cell.stepper.minimumValue = 1
+                row.cell.stepper.maximumValue = 6
+                row.value = Double(UserDefaultsRepository.alertIOBSnoozeHours.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.alertIOBSnoozeHours.value = Int(value)
+            }
+            <<< PickerInputRow<String>("alertIOBSound") { row in
+                row.title = "Sound"
+                row.options = soundFiles
+                row.value = UserDefaultsRepository.alertIOBSound.value
+                row.displayValueFor = { value in
+                    guard let value = value else { return nil }
+                    return "\(String(value.replacingOccurrences(of: "_", with: " ")))"
+                }
+            }.onChange { [weak self] row in
+                guard let value = row.value else { return }
+                UserDefaultsRepository.alertIOBSound.value = value
+                AlarmSound.setSoundFile(str: value)
+                AlarmSound.stop()
+                AlarmSound.playTest()
+        }
+            <<< PickerInputRow<String>("alertIOBPlaySound") { row in
+                row.title = "Play Sound"
+                row.options = alertPlaySoundOptions
+                row.value = UserDefaultsRepository.alertIOBAudible.value
+                row.displayValueFor = { value in
+                guard let value = value else { return nil }
+                    return "\(String(value.replacingOccurrences(of: "_", with: " ")))"
+                }
+            }.onChange { [weak self] row in
+                    guard let value = row.value else { return }
+                    UserDefaultsRepository.alertIOBAudible.value = value
+                    let alertVol = self!.timeBasedSettings(pickerValue: value)
+                    UserDefaultsRepository.alertIOBDayTimeAudible.value = alertVol.dayTime
+                    UserDefaultsRepository.alertIOBNightTimeAudible.value = alertVol.nightTime
+            }
+            <<< PickerInputRow<String>("alertIOBRepeat") { row in
+                row.title = "Repeat Sound"
+                row.options = alertRepeatOptions
+                row.value = UserDefaultsRepository.alertIOBRepeat.value
+                row.displayValueFor = { value in
+                guard let value = value else { return nil }
+                    return "\(String(value.replacingOccurrences(of: "_", with: " ")))"
+                }
+            }.onChange { [weak self] row in
+                    guard let value = row.value else { return }
+                    UserDefaultsRepository.alertIOBRepeat.value = value
+                    let alertTimes = self!.timeBasedSettings(pickerValue: value)
+                    UserDefaultsRepository.alertIOBDayTime.value = alertTimes.dayTime
+                    UserDefaultsRepository.alertIOBNightTime.value = alertTimes.nightTime
+            }
+            <<< PickerInputRow<String>("alertIOBAutoSnooze") { row in
+                row.title = "Pre-Snooze"
+                row.options = alertAutosnoozeOptions
+                row.value = UserDefaultsRepository.alertIOBAutosnooze.value
+                row.displayValueFor = { value in
+                guard let value = value else { return nil }
+                    return "\(String(value.replacingOccurrences(of: "_", with: " ")))"
+                }
+            }.onChange { [weak self] row in
+                    guard let value = row.value else { return }
+                    UserDefaultsRepository.alertIOBAutosnooze.value = value
+                let alertTimes = self!.timeBasedSettings(pickerValue: value)
+                UserDefaultsRepository.alertIOBAutosnoozeDay.value = alertTimes.dayTime
+                UserDefaultsRepository.alertIOBAutosnoozeNight.value = alertTimes.nightTime
+            }
+            <<< DateTimeInlineRow("alertIOBSnoozedTime") { row in
+                row.title = "Snoozed Until"
+                if (UserDefaultsRepository.alertIOBSnoozedTime.value != nil) {
+                    row.value = UserDefaultsRepository.alertIOBSnoozedTime.value
+                }
+                row.minuteInterval = 5
+                row.noValueDisplayText = "Not Snoozed"
+            }
+            .onChange { [weak self] row in
+                guard let value = row.value else { return }
+                UserDefaultsRepository.alertIOBSnoozedTime.value = value
+                UserDefaultsRepository.alertIOBIsSnoozed.value = true
+                let otherRow = self?.form.rowBy(tag: "alertIOBIsSnoozed") as! SwitchRow
+                otherRow.value = true
+                otherRow.reload()
+            }
+            .onExpandInlineRow { [weak self] cell, row, inlineRow in
+                inlineRow.cellUpdate() { cell, row in
+                    cell.datePicker.datePickerMode = .dateAndTime
+                    cell.datePicker.preferredDatePickerStyle = .wheels
+                }
+                let color = cell.detailTextLabel?.textColor
+                row.onCollapseInlineRow { cell, _, _ in
+                    cell.detailTextLabel?.textColor = color
+                }
+                cell.detailTextLabel?.textColor = cell.tintColor
+            }
+            <<< SwitchRow("alertIOBIsSnoozed"){ row in
+                row.title = "Is Snoozed"
+                row.value = UserDefaultsRepository.alertIOBIsSnoozed.value
+                row.hidden = "$alertIOBSnoozedTime == nil"
+            }.onChange { [weak self] row in
+                guard let value = row.value else { return }
+                UserDefaultsRepository.alertIOBIsSnoozed.value = value
+                if !value {
+                    UserDefaultsRepository.alertIOBSnoozedTime.setNil(key: "alertIOBSnoozedTime")
+                    let otherRow = self?.form.rowBy(tag: "alertIOBSnoozedTime") as! DateTimeInlineRow
+                    otherRow.value = nil
+                    otherRow.reload()
+                }
+        }
+    }
+    
+    func buildCOB() {
+        form
+            +++ Section(header: "COB", footer: "Alert will trigger when COB is above value") { row in
+                row.hidden = "$otherAlerts3 != 'COB'"
+            }
+            <<< SwitchRow("alertCOB"){ row in
+                row.title = "Active"
+                row.value = UserDefaultsRepository.alertCOB.value
+            }.onChange { [weak self] row in
+                guard let value = row.value else { return }
+                UserDefaultsRepository.alertCOB.value = value
+            }
+            
+            <<< StepperRow("alertCOBAt") { row in
+                row.title = "COB >="
+                row.cell.stepper.stepValue = 1
+                row.cell.stepper.minimumValue = 1
+                row.cell.stepper.maximumValue = 200
+                row.value = Double(UserDefaultsRepository.alertCOBAt.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.alertCOBAt.value = Int(value)
+            }
+            
+            <<< StepperRow("alertCOBSnoozeHours") { row in
+                row.title = "Snooze Hours"
+                row.cell.stepper.stepValue = 1
+                row.cell.stepper.minimumValue = 1
+                row.cell.stepper.maximumValue = 6
+                row.value = Double(UserDefaultsRepository.alertCOBSnoozeHours.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.alertCOBSnoozeHours.value = Int(value)
+            }
+            <<< PickerInputRow<String>("alertCOBSound") { row in
+                row.title = "Sound"
+                row.options = soundFiles
+                row.value = UserDefaultsRepository.alertCOBSound.value
+                row.displayValueFor = { value in
+                    guard let value = value else { return nil }
+                    return "\(String(value.replacingOccurrences(of: "_", with: " ")))"
+                }
+            }.onChange { [weak self] row in
+                guard let value = row.value else { return }
+                UserDefaultsRepository.alertCOBSound.value = value
+                AlarmSound.setSoundFile(str: value)
+                AlarmSound.stop()
+                AlarmSound.playTest()
+        }
+            <<< PickerInputRow<String>("alertCOBPlaySound") { row in
+                row.title = "Play Sound"
+                row.options = alertPlaySoundOptions
+                row.value = UserDefaultsRepository.alertCOBAudible.value
+                row.displayValueFor = { value in
+                guard let value = value else { return nil }
+                    return "\(String(value.replacingOccurrences(of: "_", with: " ")))"
+                }
+            }.onChange { [weak self] row in
+                    guard let value = row.value else { return }
+                    UserDefaultsRepository.alertCOBAudible.value = value
+                    let alertVol = self!.timeBasedSettings(pickerValue: value)
+                    UserDefaultsRepository.alertCOBDayTimeAudible.value = alertVol.dayTime
+                    UserDefaultsRepository.alertCOBNightTimeAudible.value = alertVol.nightTime
+            }
+            <<< PickerInputRow<String>("alertCOBRepeat") { row in
+                row.title = "Repeat Sound"
+                row.options = alertRepeatOptions
+                row.value = UserDefaultsRepository.alertCOBRepeat.value
+                row.displayValueFor = { value in
+                guard let value = value else { return nil }
+                    return "\(String(value.replacingOccurrences(of: "_", with: " ")))"
+                }
+            }.onChange { [weak self] row in
+                    guard let value = row.value else { return }
+                    UserDefaultsRepository.alertCOBRepeat.value = value
+                    let alertTimes = self!.timeBasedSettings(pickerValue: value)
+                    UserDefaultsRepository.alertCOBDayTime.value = alertTimes.dayTime
+                    UserDefaultsRepository.alertCOBNightTime.value = alertTimes.nightTime
+            }
+            <<< PickerInputRow<String>("alertCOBAutoSnooze") { row in
+                row.title = "Pre-Snooze"
+                row.options = alertAutosnoozeOptions
+                row.value = UserDefaultsRepository.alertCOBAutosnooze.value
+                row.displayValueFor = { value in
+                guard let value = value else { return nil }
+                    return "\(String(value.replacingOccurrences(of: "_", with: " ")))"
+                }
+            }.onChange { [weak self] row in
+                    guard let value = row.value else { return }
+                    UserDefaultsRepository.alertCOBAutosnooze.value = value
+                let alertTimes = self!.timeBasedSettings(pickerValue: value)
+                UserDefaultsRepository.alertCOBAutosnoozeDay.value = alertTimes.dayTime
+                UserDefaultsRepository.alertCOBAutosnoozeNight.value = alertTimes.nightTime
+            }
+            <<< DateTimeInlineRow("alertCOBSnoozedTime") { row in
+                row.title = "Snoozed Until"
+                if (UserDefaultsRepository.alertCOBSnoozedTime.value != nil) {
+                    row.value = UserDefaultsRepository.alertCOBSnoozedTime.value
+                }
+                row.minuteInterval = 5
+                row.noValueDisplayText = "Not Snoozed"
+            }
+            .onChange { [weak self] row in
+                guard let value = row.value else { return }
+                UserDefaultsRepository.alertCOBSnoozedTime.value = value
+                UserDefaultsRepository.alertCOBIsSnoozed.value = true
+                let otherRow = self?.form.rowBy(tag: "alertCOBIsSnoozed") as! SwitchRow
+                otherRow.value = true
+                otherRow.reload()
+            }
+            .onExpandInlineRow { [weak self] cell, row, inlineRow in
+                inlineRow.cellUpdate() { cell, row in
+                    cell.datePicker.datePickerMode = .dateAndTime
+                    cell.datePicker.preferredDatePickerStyle = .wheels
+                }
+                let color = cell.detailTextLabel?.textColor
+                row.onCollapseInlineRow { cell, _, _ in
+                    cell.detailTextLabel?.textColor = color
+                }
+                cell.detailTextLabel?.textColor = cell.tintColor
+            }
+            <<< SwitchRow("alertCOBIsSnoozed"){ row in
+                row.title = "Is Snoozed"
+                row.value = UserDefaultsRepository.alertCOBIsSnoozed.value
+                row.hidden = "$alertCOBSnoozedTime == nil"
+            }.onChange { [weak self] row in
+                guard let value = row.value else { return }
+                UserDefaultsRepository.alertCOBIsSnoozed.value = value
+                if !value {
+                    UserDefaultsRepository.alertCOBSnoozedTime.setNil(key: "alertCOBSnoozedTime")
+                    let otherRow = self?.form.rowBy(tag: "alertCOBSnoozedTime") as! DateTimeInlineRow
+                    otherRow.value = nil
+                    otherRow.reload()
+                }
+        }
+    }
 
     func buildAlarmSettings() {
            form

+ 17 - 5
LoopFollow/ViewControllers/SnoozeViewController.swift

@@ -141,12 +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))
+        } else if AlarmSound.whichAlarm == "Predicted Urgent Low Alert" {
+            UserDefaultsRepository.alertUrgentLowIsSnoozed.value = true
+            UserDefaultsRepository.alertUrgentLowSnoozedTime.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)))
+            alarms.reloadIsSnoozed(key: "alertUrgentLowIsSnoozed", value: true)
+            alarms.reloadSnoozeTime(key: "alertUrgentLowSnoozedTime", 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))
@@ -207,6 +207,18 @@ class SnoozeViewController: UIViewController, UNUserNotificationCenterDelegate {
         guard let alarms = self.tabBarController!.viewControllers?[1] as? AlarmViewController else { return }
         alarms.reloadIsSnoozed(key: "alertPumpIsSnoozed", value: true)
         alarms.reloadSnoozeTime(key: "alertPumpSnoozedTime", setNil: false, value: Date().addingTimeInterval(TimeInterval(snoozeForMinuteStepper.value * 60 * 60)))
+       } else if AlarmSound.whichAlarm == "IOB Alert" {
+        UserDefaultsRepository.alertIOBIsSnoozed.value = true
+        UserDefaultsRepository.alertIOBSnoozedTime.value = Date().addingTimeInterval(TimeInterval(snoozeForMinuteStepper.value * 60 * 60))
+        guard let alarms = self.tabBarController!.viewControllers?[1] as? AlarmViewController else { return }
+        alarms.reloadIsSnoozed(key: "alertIOBIsSnoozed", value: true)
+        alarms.reloadSnoozeTime(key: "alertIOBSnoozedTime", setNil: false, value: Date().addingTimeInterval(TimeInterval(snoozeForMinuteStepper.value * 60 * 60)))
+       } else if AlarmSound.whichAlarm == "COB Alert" {
+        UserDefaultsRepository.alertCOBIsSnoozed.value = true
+        UserDefaultsRepository.alertCOBSnoozedTime.value = Date().addingTimeInterval(TimeInterval(snoozeForMinuteStepper.value * 60 * 60))
+        guard let alarms = self.tabBarController!.viewControllers?[1] as? AlarmViewController else { return }
+        alarms.reloadIsSnoozed(key: "alertCOBIsSnoozed", value: true)
+        alarms.reloadSnoozeTime(key: "alertCOBSnoozedTime", setNil: false, value: Date().addingTimeInterval(TimeInterval(snoozeForMinuteStepper.value * 60 * 60)))
        }
     }
     

+ 34 - 1
LoopFollow/repository/UserDefaults.swift

@@ -129,6 +129,7 @@ class UserDefaultsRepository {
     
     static let alertUrgentLowActive = UserDefaultsValue<Bool>(key: "alertUrgentLowActive", default: false)
     static let alertUrgentLowBG = UserDefaultsValue<Float>(key: "alertUrgentLowBG", default: 55.0)
+    static let alertUrgentLowPredictiveMinutes = UserDefaultsValue<Int>(key: "alertUrgentLowPredictiveMinutes", default: 0)
     static let alertUrgentLowSnooze = UserDefaultsValue<Int>(key: "alertUrgentLowSnooze", default: 5)
     static let alertUrgentLowSnoozedTime = UserDefaultsValue<Date?>(key: "alertUrgentLowSnoozedTime", default: nil)
     static let alertUrgentLowIsSnoozed = UserDefaultsValue<Bool>(key: "alertUrgentLowIsSnoozed", default: false)
@@ -147,7 +148,6 @@ class UserDefaultsRepository {
     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)
@@ -382,4 +382,37 @@ class UserDefaultsRepository {
     static let alertPumpAutosnoozeDay = UserDefaultsValue<Bool>(key: "alertPumpAutosnoozeDay", default: false)
     static let alertPumpAutosnoozeNight = UserDefaultsValue<Bool>(key: "alertPumpAutosnoozeNight", default: false)
     
+    static let alertIOB = UserDefaultsValue<Bool>(key: "alertIOB", default: false)
+    static let alertIOBAt = UserDefaultsValue<Int>(key: "alertIOBAt", default: 10) //Units
+    static let alertIOBQuiet = UserDefaultsValue<Bool>(key: "alertIOBQuiet", default: false)
+    static let alertIOBRepeat = UserDefaultsValue<String>(key: "alertIOBRepeat", default: "Always")
+    static let alertIOBDayTime = UserDefaultsValue<Bool>(key: "alertIOBDayTime", default: true)
+    static let alertIOBNightTime = UserDefaultsValue<Bool>(key: "alertIOBNightTime", default: true)
+    static let alertIOBAudible = UserDefaultsValue<String>(key: "alertIOBAudible", default: "Always")
+    static let alertIOBDayTimeAudible = UserDefaultsValue<Bool>(key: "alertIOBDayTimeAudible", default: true)
+    static let alertIOBNightTimeAudible = UserDefaultsValue<Bool>(key: "alertIOBNightTimeAudible", default: true)
+    static let alertIOBSound = UserDefaultsValue<String>(key: "alertIOBSound", default: "Alert_Tone_Ringtone_1")
+    static let alertIOBSnoozeHours = UserDefaultsValue<Int>(key: "alertIOBSnoozeHours", default: 1) //Hours
+    static let alertIOBIsSnoozed = UserDefaultsValue<Bool>(key: "alertIOBIsSnoozed", default: false)
+    static let alertIOBSnoozedTime = UserDefaultsValue<Date?>(key: "alertIOBSnoozedTime", default: nil)
+    static let alertIOBAutosnooze = UserDefaultsValue<String>(key: "alertIOBAutosnooze", default: "Never")
+    static let alertIOBAutosnoozeDay = UserDefaultsValue<Bool>(key: "alertIOBAutosnoozeDay", default: false)
+    static let alertIOBAutosnoozeNight = UserDefaultsValue<Bool>(key: "alertIOBAutosnoozeNight", default: false)
+    
+    static let alertCOB = UserDefaultsValue<Bool>(key: "alertCOB", default: false)
+    static let alertCOBAt = UserDefaultsValue<Int>(key: "alertCOBAt", default: 50) //Units
+    static let alertCOBQuiet = UserDefaultsValue<Bool>(key: "alertCOBQuiet", default: false)
+    static let alertCOBRepeat = UserDefaultsValue<String>(key: "alertCOBRepeat", default: "Always")
+    static let alertCOBDayTime = UserDefaultsValue<Bool>(key: "alertCOBDayTime", default: true)
+    static let alertCOBNightTime = UserDefaultsValue<Bool>(key: "alertCOBNightTime", default: true)
+    static let alertCOBAudible = UserDefaultsValue<String>(key: "alertCOBAudible", default: "Always")
+    static let alertCOBDayTimeAudible = UserDefaultsValue<Bool>(key: "alertCOBDayTimeAudible", default: true)
+    static let alertCOBNightTimeAudible = UserDefaultsValue<Bool>(key: "alertCOBNightTimeAudible", default: true)
+    static let alertCOBSound = UserDefaultsValue<String>(key: "alertCOBSound", default: "Alert_Tone_Ringtone_2")
+    static let alertCOBSnoozeHours = UserDefaultsValue<Int>(key: "alertCOBSnoozeHours", default: 1) //Hours
+    static let alertCOBIsSnoozed = UserDefaultsValue<Bool>(key: "alertCOBIsSnoozed", default: false)
+    static let alertCOBSnoozedTime = UserDefaultsValue<Date?>(key: "alertCOBSnoozedTime", default: nil)
+    static let alertCOBAutosnooze = UserDefaultsValue<String>(key: "alertCOBAutosnooze", default: "Never")
+    static let alertCOBAutosnoozeDay = UserDefaultsValue<Bool>(key: "alertCOBAutosnoozeDay", default: false)
+    static let alertCOBAutosnoozeNight = UserDefaultsValue<Bool>(key: "alertCOBAutosnoozeNight", default: false)
 }