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

- Split fast rise/drop to separate alerts
- added alarm timer to prevent alarm from triggering again within 1 minute before the snooze data can be stored.
- finished alarms for temp, urgent low/high, low, high, fast drop/rise, missed readings

Jon Fawcett 6 лет назад
Родитель
Сommit
73a9369bd8

+ 0 - 18
LoopFollow.xcworkspace/xcuserdata/jon.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -3,22 +3,4 @@
    uuid = "35B1BDC7-1374-42B0-9D79-1E7D694F0434"
    type = "0"
    version = "2.0">
-   <Breakpoints>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "8FB92D8C-6AEC-42E9-8DA7-864449B1F6DA"
-            shouldBeEnabled = "Yes"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "LoopFollow/Controllers/MainViewController.swift"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "729"
-            endingLineNumber = "729"
-            landmarkName = "clearOldSnoozes()"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-   </Breakpoints>
 </Bucket>

+ 155 - 46
LoopFollow/Controllers/AlarmViewController.swift

@@ -49,7 +49,8 @@ class AlarmViewController: FormViewController {
         buildLow()
         buildHigh()
         buildUrgentHigh()
-        buildFastAlert()
+        buildFastDropAlert()
+        buildFastRiseAlert()
         buildMissedReadings()
         buildNotLooping()
         buildMissedBolus()
@@ -448,113 +449,221 @@ class AlarmViewController: FormViewController {
         }
     }
     
-    func buildFastAlert(){
+    func buildFastDropAlert(){
         form
-        +++ Section(header: "Fast Rise/Drop Alert", footer: "Alert when BG is changing fast over consecutive readings. Optional: only alert when Dropping and below a specific BG or Rising and above a specific BG")
-        <<< SwitchRow("alertFastActive"){ row in
+        +++ Section(header: "Fast Drop Alert", footer: "Alert when BG is dropping fast over consecutive readings. Optional: only alert when dropping below a specific BG")
+        <<< SwitchRow("alertFastDropActive"){ row in
                 row.title = "Active"
-                row.value = UserDefaultsRepository.alertFastActive.value
+                row.value = UserDefaultsRepository.alertFastDropActive.value
                 }.onChange { [weak self] row in
                         guard let value = row.value else { return }
-                        UserDefaultsRepository.alertFastActive.value = value
+                        UserDefaultsRepository.alertFastDropActive.value = value
                 }
-        <<< StepperRow("alertFastDelta") { row in
+        <<< StepperRow("alertFastDropDelta") { row in
             row.title = "Delta"
             row.cell.stepper.stepValue = 1
             row.cell.stepper.minimumValue = 3
             row.cell.stepper.maximumValue = 20
-            row.value = Double(UserDefaultsRepository.alertFastDelta.value)
-            row.hidden = "$alertFastActive == false"
+            row.value = Double(UserDefaultsRepository.alertFastDropDelta.value)
+            row.hidden = "$alertFastDropActive == false"
             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.alertFastDelta.value = Int(value)
+                UserDefaultsRepository.alertFastDropDelta.value = Int(value)
         }
-        <<< StepperRow("alertFastReadings") { row in
+        <<< StepperRow("alertFastDropReadings") { row in
             row.title = "# Readings"
             row.cell.stepper.stepValue = 1
             row.cell.stepper.minimumValue = 2
             row.cell.stepper.maximumValue = 4
-            row.value = Double(UserDefaultsRepository.alertFastReadings.value)
-            row.hidden = "$alertFastActive == false"
+            row.value = Double(UserDefaultsRepository.alertFastDropReadings.value)
+            row.hidden = "$alertFastDropActive == false"
             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.alertFastReadings.value = Int(value)
+                UserDefaultsRepository.alertFastDropReadings.value = Int(value)
         }
-        <<< SwitchRow("alertFastUseLimits"){ row in
-        row.title = "Use BG Limits"
-        row.hidden = "$alertFastActive == false"
-        row.value = UserDefaultsRepository.alertFastUseLimits.value
+        <<< SwitchRow("alertFastDropUseLimit"){ row in
+        row.title = "Use BG Limit"
+        row.hidden = "$alertFastDropActive == false"
+        row.value = UserDefaultsRepository.alertFastDropUseLimit.value
         }.onChange { [weak self] row in
                 guard let value = row.value else { return }
-                UserDefaultsRepository.alertFastUseLimits.value = value
+                UserDefaultsRepository.alertFastDropUseLimit.value = value
         }
-        <<< StepperRow("alertFastLowerLimit") { row in
+    
+        <<< StepperRow("alertFastDropBelowBG") { row in
             row.title = "Dropping Below BG"
             row.cell.stepper.stepValue = 1
-            row.cell.stepper.minimumValue = 50
-            row.cell.stepper.maximumValue = 200
-            row.value = Double(UserDefaultsRepository.alertFastLowerLimit.value)
-            row.hidden = "$alertFastActive == false || $alertFastUseLimits == false"
+            row.cell.stepper.minimumValue = 100
+            row.cell.stepper.maximumValue = 300
+            row.value = Double(UserDefaultsRepository.alertFastDropBelowBG.value)
+            row.hidden = "$alertFastDropActive == false || $alertFastDropUseLimit == false"
+            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.alertFastDropBelowBG.value = Int(value)
+        }
+        <<< StepperRow("alertFastDropSnooze") { row in
+            row.title = "Snooze"
+            row.cell.stepper.stepValue = 5
+            row.cell.stepper.minimumValue = 5
+            row.cell.stepper.maximumValue = 60
+            row.value = Double(UserDefaultsRepository.alertFastDropSnooze.value)
+            row.hidden = "$alertFastDropActive == false"
             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.alertFastLowerLimit.value = Int(value)
+                UserDefaultsRepository.alertFastDropSnooze.value = Int(value)
+        }
+        <<< DateTimeInlineRow("alertFastDropSnoozedTime") { row in
+            row.title = "Snoozed Until"
+            row.hidden = "$alertFastDropActive == false"
+           if (UserDefaultsRepository.alertFastDropSnoozedTime.value != nil) {
+                row.value = UserDefaultsRepository.alertFastDropSnoozedTime.value
+            }
+            row.minuteInterval = 5
+            row.noValueDisplayText = "Not Snoozed"
+            }
+            .onChange { [weak self] row in
+                guard let value = row.value else { return }
+                UserDefaultsRepository.alertFastDropSnoozedTime.value = value
+                UserDefaultsRepository.alertFastDropIsSnoozed.value = true
+                let otherRow = self?.form.rowBy(tag: "alertFastDropIsSnoozed") as! SwitchRow
+                otherRow.value = true
+                otherRow.reload()
+            }
+            .onExpandInlineRow { [weak self] cell, row, inlineRow in
+                inlineRow.cellUpdate() { cell, row in
+                    cell.datePicker.datePickerMode = .dateAndTime
+                }
+                let color = cell.detailTextLabel?.textColor
+                row.onCollapseInlineRow { cell, _, _ in
+                    cell.detailTextLabel?.textColor = color
+                }
+                cell.detailTextLabel?.textColor = cell.tintColor
+        }
+        <<< SwitchRow("alertFastDropIsSnoozed"){ row in
+            row.title = "Is Snoozed"
+            row.value = UserDefaultsRepository.alertFastDropIsSnoozed.value
+            row.hidden = "$alertFastDropActive == false || $alertFastDropSnoozedTime == nil"
+        }.onChange { [weak self] row in
+                guard let value = row.value else { return }
+                UserDefaultsRepository.alertFastDropIsSnoozed.value = value
+                if !value {
+                    UserDefaultsRepository.alertFastDropSnoozedTime.setNil(key: "alertFastDropSnoozedTime")
+                    let otherRow = self?.form.rowBy(tag: "alertFastDropSnoozedTime") as! DateTimeInlineRow
+                   otherRow.value = nil
+                   otherRow.reload()
+                }
+        }
+    }
+    
+    func buildFastRiseAlert(){
+        form
+        +++ Section(header: "Fast Rise Alert", footer: "Alert when BG is rising fast over consecutive readings. Optional: only alert when rising above a specific BG")
+        <<< SwitchRow("alertFastRiseActive"){ row in
+                row.title = "Active"
+                row.value = UserDefaultsRepository.alertFastRiseActive.value
+                }.onChange { [weak self] row in
+                        guard let value = row.value else { return }
+                        UserDefaultsRepository.alertFastRiseActive.value = value
+                }
+        <<< StepperRow("alertFastRiseDelta") { row in
+            row.title = "Delta"
+            row.cell.stepper.stepValue = 1
+            row.cell.stepper.minimumValue = 3
+            row.cell.stepper.maximumValue = 20
+            row.value = Double(UserDefaultsRepository.alertFastRiseDelta.value)
+            row.hidden = "$alertFastRiseActive == false"
+            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.alertFastRiseDelta.value = Int(value)
         }
-        <<< StepperRow("alertFastUpperLimit") { row in
+        <<< StepperRow("alertFastRiseReadings") { row in
+            row.title = "# Readings"
+            row.cell.stepper.stepValue = 1
+            row.cell.stepper.minimumValue = 2
+            row.cell.stepper.maximumValue = 4
+            row.value = Double(UserDefaultsRepository.alertFastRiseReadings.value)
+            row.hidden = "$alertFastRiseActive == false"
+            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.alertFastRiseReadings.value = Int(value)
+        }
+        <<< SwitchRow("alertFastRiseUseLimit"){ row in
+        row.title = "Use BG Limit"
+        row.hidden = "$alertFastRiseActive == false"
+        row.value = UserDefaultsRepository.alertFastRiseUseLimit.value
+        }.onChange { [weak self] row in
+                guard let value = row.value else { return }
+                UserDefaultsRepository.alertFastRiseUseLimit.value = value
+        }
+    
+        <<< StepperRow("alertFastRiseAboveBG") { row in
             row.title = "Rising Above BG"
             row.cell.stepper.stepValue = 1
             row.cell.stepper.minimumValue = 100
             row.cell.stepper.maximumValue = 300
-            row.value = Double(UserDefaultsRepository.alertFastUpperLimit.value)
-            row.hidden = "$alertFastActive == false || $alertFastUseLimits == false"
+            row.value = Double(UserDefaultsRepository.alertFastRiseAboveBG.value)
+            row.hidden = "$alertFastRiseActive == false || $alertFastRiseUseLimit == false"
             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.alertFastUpperLimit.value = Int(value)
+                UserDefaultsRepository.alertFastRiseAboveBG.value = Int(value)
         }
-        <<< StepperRow("alertFastSnooze") { row in
+        <<< StepperRow("alertFastRiseSnooze") { row in
             row.title = "Snooze"
             row.cell.stepper.stepValue = 5
             row.cell.stepper.minimumValue = 5
             row.cell.stepper.maximumValue = 60
-            row.value = Double(UserDefaultsRepository.alertFastSnooze.value)
-            row.hidden = "$alertFastActive == false"
+            row.value = Double(UserDefaultsRepository.alertFastRiseSnooze.value)
+            row.hidden = "$alertFastRiseActive == false"
             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.alertFastSnooze.value = Int(value)
+                UserDefaultsRepository.alertFastRiseSnooze.value = Int(value)
         }
-        <<< DateTimeInlineRow("alertFastSnoozedTime") { row in
+        <<< DateTimeInlineRow("alertFastRiseSnoozedTime") { row in
             row.title = "Snoozed Until"
-            row.hidden = "$alertFastActive == false"
-           if (UserDefaultsRepository.alertFastSnoozedTime.value != nil) {
-                row.value = UserDefaultsRepository.alertFastSnoozedTime.value
+            row.hidden = "$alertFastRiseActive == false"
+           if (UserDefaultsRepository.alertFastRiseSnoozedTime.value != nil) {
+                row.value = UserDefaultsRepository.alertFastRiseSnoozedTime.value
             }
             row.minuteInterval = 5
             row.noValueDisplayText = "Not Snoozed"
             }
             .onChange { [weak self] row in
                 guard let value = row.value else { return }
-                UserDefaultsRepository.alertFastSnoozedTime.value = value
-                UserDefaultsRepository.alertFastIsSnoozed.value = true
-                let otherRow = self?.form.rowBy(tag: "alertFastIsSnoozed") as! SwitchRow
+                UserDefaultsRepository.alertFastRiseSnoozedTime.value = value
+                UserDefaultsRepository.alertFastRiseIsSnoozed.value = true
+                let otherRow = self?.form.rowBy(tag: "alertFastRiseIsSnoozed") as! SwitchRow
                 otherRow.value = true
                 otherRow.reload()
             }
@@ -568,16 +677,16 @@ class AlarmViewController: FormViewController {
                 }
                 cell.detailTextLabel?.textColor = cell.tintColor
         }
-        <<< SwitchRow("alertFastIsSnoozed"){ row in
+        <<< SwitchRow("alertFastRiseIsSnoozed"){ row in
             row.title = "Is Snoozed"
-            row.value = UserDefaultsRepository.alertFastIsSnoozed.value
-            row.hidden = "$alertFastActive == false || $alertFastSnoozedTime == nil"
+            row.value = UserDefaultsRepository.alertFastRiseIsSnoozed.value
+            row.hidden = "$alertFastRiseActive == false || $alertFastRiseSnoozedTime == nil"
         }.onChange { [weak self] row in
                 guard let value = row.value else { return }
-                UserDefaultsRepository.alertFastIsSnoozed.value = value
+                UserDefaultsRepository.alertFastRiseIsSnoozed.value = value
                 if !value {
-                    UserDefaultsRepository.alertFastSnoozedTime.setNil(key: "alertFastSnoozedTime")
-                    let otherRow = self?.form.rowBy(tag: "alertFastSnoozedTime") as! DateTimeInlineRow
+                    UserDefaultsRepository.alertFastRiseSnoozedTime.setNil(key: "alertFastRiseSnoozedTime")
+                    let otherRow = self?.form.rowBy(tag: "alertFastRiseSnoozedTime") as! DateTimeInlineRow
                    otherRow.value = nil
                    otherRow.reload()
                 }

+ 135 - 14
LoopFollow/Controllers/MainViewController.swift

@@ -58,6 +58,11 @@ class MainViewController: UIViewController, UITableViewDataSource {
     // check every 30 Seconds whether new bgvalues should be retrieved
     let timeInterval: TimeInterval = 30.0
     
+    // Check Alarms Timer
+    // Don't check within 1 minute of alarm triggering to give the snoozer time to save data
+    var checkAlarmTimer = Timer()
+    var checkAlarmInterval: TimeInterval = 60.0
+    
     // Info Table Setup
     var tableData = [
         infoData(name: "IOB", value: ""), //0
@@ -129,6 +134,20 @@ class MainViewController: UIViewController, UITableViewDataSource {
                                      repeats: true)
     }
     
+    // Timer
+    func startCheckAlarmTimer(time: TimeInterval) {
+        checkAlarmTimer = Timer.scheduledTimer(timeInterval: time,
+                                     target: self,
+                                     selector: #selector(MainViewController.checkAlarmTimerDidEnd(_:)),
+                                     userInfo: nil,
+                                     repeats: false)
+    }
+    
+    // check whether new Values should be retrieved
+    @objc func checkAlarmTimerDidEnd(_ timer:Timer) {
+        print("check alarm timer ended")
+    }
+    
     @objc func appMovedToBackground() {
         tabBarController?.selectedIndex = 0
         timer.invalidate()
@@ -175,7 +194,7 @@ class MainViewController: UIViewController, UITableViewDataSource {
             loadBGData(urlUser: urlUser, onlyPullLastRecord: onlyPullLastRecord)
             clearLastInfoData()
             loadDeviceStatus(urlUser: urlUser)
-            loadTempBasals(urlUser: urlUser)
+           // loadTempBasals(urlUser: urlUser)
         } else {
             updateMinAgo()
             clearOldSnoozes()
@@ -212,7 +231,6 @@ class MainViewController: UIViewController, UITableViewDataSource {
 
     // Main NS Data Pull
     func loadBGData(urlUser: String, onlyPullLastRecord: Bool = false) {
-        
         var points = "1"
         if !onlyPullLastRecord {
              points = String(self.graphHours * 12 + 1)
@@ -258,7 +276,6 @@ class MainViewController: UIViewController, UITableViewDataSource {
         getBGTask.resume()
     }
     
-   
     
     //Clear the info data before next pull
     func clearLastInfoData(){
@@ -362,6 +379,49 @@ class MainViewController: UIViewController, UITableViewDataSource {
         basalTask.resume()
     }
     
+    func loadBoluses(urlUser: String){
+        
+        var searchString = "find[eventType]=Meal%20Bolus&find[created_at][$gte]=2020-06-08T00:00:00"
+        var urlBGDataPath: String = urlUser + "/api/v1/treatments.json?"
+        if token == "" {
+            urlBGDataPath = urlBGDataPath + searchString
+        }
+        else
+        {
+            urlBGDataPath = urlBGDataPath + "token=" + token + searchString
+        }
+        guard let urlBGData = URL(string: urlBGDataPath) else {
+            return
+        }
+        var request = URLRequest(url: urlBGData)
+        request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringLocalCacheData
+        
+        let getTask = URLSession.shared.dataTask(with: request) { data, response, error in
+            if self.consoleLogging == true {print("start meal bolus url")}
+            guard error == nil else {
+                return
+            }
+            guard let data = data else {
+                return
+            }
+            
+            let decoder = JSONDecoder()
+            let entriesResponse = try? decoder.decode([sgvData].self, from: data)
+            if let entriesResponse = entriesResponse {
+                DispatchQueue.main.async {
+                   // self.ProcessNSData(data: entriesResponse, onlyPullLastRecord: onlyPullLastRecord)
+                }
+            }
+            else
+            {
+                
+                return
+            }
+        }
+        getTask.resume()
+    }
+    
+    
     // Parse Device Status Data
     func updateDeviceStatusDisplay(jsonDeviceStatus: [[String:AnyObject]]) {
         if consoleLogging == true {print("in updatePump")}
@@ -565,7 +625,6 @@ class MainViewController: UIViewController, UITableViewDataSource {
       
     }
     
-    
     func updateBadge(entries: [sgvData]) {
         if entries.count > 0 && UserDefaultsRepository.appBadge.value {
             let latestBG = entries[entries.count - 1].sgv
@@ -642,9 +701,19 @@ class MainViewController: UIViewController, UITableViewDataSource {
     }
     
     func checkAlarms(bgs: [sgvData]) {
+        
+        // Don't check or fire alarms within 1 minute of prior alarm
+        if checkAlarmTimer.isValid {  return }
+        
         let date = Date()
         let now = date.timeIntervalSince1970
         let currentBG = bgs[bgs.count - 1].sgv
+        let lastBG = bgs[bgs.count - 2].sgv
+        guard let deltas: [Int] = [
+            bgs[bgs.count - 1].sgv - bgs[bgs.count - 2].sgv,
+            bgs[bgs.count - 2].sgv - bgs[bgs.count - 3].sgv,
+            bgs[bgs.count - 3].sgv - bgs[bgs.count - 4].sgv
+            ] else {}
         let currentBGTime = bgs[bgs.count - 1].date
         var alarmTriggered = false
         
@@ -675,7 +744,7 @@ class MainViewController: UIViewController, UITableViewDataSource {
             }
             
             // Check Urgent Low
-            if UserDefaultsRepository.alertUrgentLowActive.value &&
+            if UserDefaultsRepository.alertUrgentLowActive.value && !UserDefaultsRepository.alertUrgentLowIsSnoozed.value &&
             currentBG <= UserDefaultsRepository.alertUrgentLowBG.value && !UserDefaultsRepository.alertUrgentLowIsSnoozed.value {
                 AlarmSound.whichAlarm = "Urgent Low Alert"
                 triggerAlarm()
@@ -683,7 +752,7 @@ class MainViewController: UIViewController, UITableViewDataSource {
             }
             
             // Check Low
-            if UserDefaultsRepository.alertLowActive.value &&
+            if UserDefaultsRepository.alertLowActive.value && !UserDefaultsRepository.alertUrgentLowIsSnoozed.value &&
             currentBG <= UserDefaultsRepository.alertLowBG.value && !UserDefaultsRepository.alertLowIsSnoozed.value {
                 AlarmSound.whichAlarm = "Low Alert"
                 triggerAlarm()
@@ -691,7 +760,7 @@ class MainViewController: UIViewController, UITableViewDataSource {
             }
             
             // Check High
-            if UserDefaultsRepository.alertHighActive.value &&
+            if UserDefaultsRepository.alertHighActive.value && !UserDefaultsRepository.alertHighIsSnoozed.value &&
             currentBG >= UserDefaultsRepository.alertHighBG.value && !UserDefaultsRepository.alertHighIsSnoozed.value {
                 AlarmSound.whichAlarm = "High Alert"
                 triggerAlarm()
@@ -699,12 +768,57 @@ class MainViewController: UIViewController, UITableViewDataSource {
             }
             
             // Check Urgent High
-            if UserDefaultsRepository.alertUrgentHighActive.value &&
+            if UserDefaultsRepository.alertUrgentHighActive.value && !UserDefaultsRepository.alertUrgentHighIsSnoozed.value &&
             currentBG >= UserDefaultsRepository.alertUrgentHighBG.value && !UserDefaultsRepository.alertUrgentHighIsSnoozed.value {
                 AlarmSound.whichAlarm = "Urgent High Alert"
                 triggerAlarm()
                 return
             }
+            
+            // Check Fast Drop
+            if UserDefaultsRepository.alertFastDropActive.value && !UserDefaultsRepository.alertFastDropIsSnoozed.value {
+                // make sure limit is off or BG is below value
+                if (!UserDefaultsRepository.alertFastDropUseLimit.value) || (UserDefaultsRepository.alertFastDropUseLimit.value && currentBG < UserDefaultsRepository.alertFastDropBelowBG.value) {
+                    let compare = 0 - UserDefaultsRepository.alertFastDropDelta.value
+                    
+                    //check last 2/3/4 readings
+                    if (UserDefaultsRepository.alertFastDropReadings.value == 2 && deltas[0] <= compare)
+                    || (UserDefaultsRepository.alertFastDropReadings.value == 3 && deltas[0] <= compare && deltas[1] <= compare)
+                    || (UserDefaultsRepository.alertFastDropReadings.value == 4 && deltas[0] <= compare && deltas[1] <= compare && deltas[2] <= compare) {
+                        AlarmSound.whichAlarm = "Fast Drop Alert"
+                        triggerAlarm()
+                        return
+                    }
+                }
+            }
+            
+            // Check Fast Rise
+            if UserDefaultsRepository.alertFastRiseActive.value && !UserDefaultsRepository.alertFastRiseIsSnoozed.value {
+                // make sure limit is off or BG is above value
+                if (!UserDefaultsRepository.alertFastRiseUseLimit.value) || (UserDefaultsRepository.alertFastRiseUseLimit.value && currentBG < UserDefaultsRepository.alertFastRiseAboveBG.value) {
+                    let compare = UserDefaultsRepository.alertFastDropDelta.value
+                    
+                    //check last 2/3/4 readings
+                    if (UserDefaultsRepository.alertFastRiseReadings.value == 2 && deltas[0] >= compare)
+                    || (UserDefaultsRepository.alertFastRiseReadings.value == 3 && deltas[0] >= compare && deltas[1] >= compare)
+                    || (UserDefaultsRepository.alertFastRiseReadings.value == 4 && deltas[0] >= compare && deltas[1] >= compare && deltas[2] >= compare) {
+                        AlarmSound.whichAlarm = "Fast Rise Alert"
+                        triggerAlarm()
+                        return
+                    }
+                }
+            }
+            
+
+            
+        } else {
+            //check for missed reading alert
+            
+            if UserDefaultsRepository.alertMissedBolusActive.value && !UserDefaultsRepository.alertMissedReadingIsSnoozed.value && (Double(now - currentBGTime) >= Double(UserDefaultsRepository.alertMissedReading.value * 60)) {
+                AlarmSound.whichAlarm = "Missed Reading Alert"
+                    triggerAlarm()
+                    return
+                }
         }
         
         
@@ -712,7 +826,7 @@ class MainViewController: UIViewController, UITableViewDataSource {
     
     func triggerAlarm()
     {
-        guard let snoozer = self.tabBarController!.viewControllers?[1] as? SnoozeViewController else { return }
+        guard let snoozer = self.tabBarController!.viewControllers?[2] as? SnoozeViewController else { return }
         snoozer.updateDisplayWhenTriggered(bgVal: BGText.text ?? "", directionVal: DirectionText.text ?? "", deltaVal: DeltaText.text ?? "", minAgoVal: MinAgoText.text ?? "", alertLabelVal: AlarmSound.whichAlarm)
         snoozeTabItem.isEnabled = true;
         tabBarController?.selectedIndex = 2
@@ -753,11 +867,18 @@ class MainViewController: UIViewController, UITableViewDataSource {
             alarms.reloadIsSnoozed(key: "alertUrgentHighIsSnoozed", value: false)
           
         }
-        if date > UserDefaultsRepository.alertFastSnoozedTime.value ?? date {
-            UserDefaultsRepository.alertFastSnoozedTime.setNil(key: "alertFastSnoozedTime")
-            UserDefaultsRepository.alertFastIsSnoozed.value = false
-            alarms.reloadSnoozeTime(key: "alertFastSnoozedTime", setNil: true)
-            alarms.reloadIsSnoozed(key: "alertFastIsSnoozed", value: false)
+        if date > UserDefaultsRepository.alertFastDropSnoozedTime.value ?? date {
+            UserDefaultsRepository.alertFastDropSnoozedTime.setNil(key: "alertFastDropSnoozedTime")
+            UserDefaultsRepository.alertFastDropIsSnoozed.value = false
+            alarms.reloadSnoozeTime(key: "alertFastDropSnoozedTime", setNil: true)
+            alarms.reloadIsSnoozed(key: "alertFastDropIsSnoozed", value: false)
+           
+        }
+        if date > UserDefaultsRepository.alertFastRiseSnoozedTime.value ?? date {
+            UserDefaultsRepository.alertFastRiseSnoozedTime.setNil(key: "alertFastRiseSnoozedTime")
+            UserDefaultsRepository.alertFastRiseIsSnoozed.value = false
+            alarms.reloadSnoozeTime(key: "alertFastRiseSnoozedTime", setNil: true)
+            alarms.reloadIsSnoozed(key: "alertFastRiseIsSnoozed", value: false)
            
         }
         if date > UserDefaultsRepository.alertMissedReadingSnoozedTime.value ?? date {

+ 32 - 4
LoopFollow/Controllers/SnoozeViewController.swift

@@ -13,6 +13,7 @@ import UIKit
 class SnoozeViewController: UIViewController {
 
     var snoozeTabItem: UITabBarItem = UITabBarItem()
+    var mainTabItem: UITabBarItem = UITabBarItem()
     
     @IBOutlet weak var SnoozeButton: UIButton!
 
@@ -24,17 +25,26 @@ class SnoozeViewController: UIViewController {
     
     @IBAction func SnoozeButton(_ sender: UIButton) {
         AlarmSound.stop()
-        setSnoozeTime()
-        tabBarController?.selectedIndex = 0
+        
+        guard let mainVC = self.tabBarController!.viewControllers?[0] as? MainViewController else { return }
+        mainVC.startCheckAlarmTimer(time: mainVC.checkAlarmInterval)
+        
         let tabBarControllerItems = self.tabBarController?.tabBar.items
         if let arrayOfTabBarItems = tabBarControllerItems as! AnyObject as? NSArray{
             snoozeTabItem = arrayOfTabBarItems[2] as! UITabBarItem
+            
         }
+        
+        
+        setSnoozeTime()
+        tabBarController?.selectedIndex = 0
+        
         snoozeTabItem.isEnabled = false;
         
     }
     
     func updateDisplayWhenTriggered(bgVal: String, directionVal: String, deltaVal: String, minAgoVal: String, alertLabelVal: String){
+        loadViewIfNeeded()
         BGLabel.text = bgVal
         DirectionLabel.text = directionVal
         DeltaLabel.text = deltaVal
@@ -71,8 +81,26 @@ class SnoozeViewController: UIViewController {
             UserDefaultsRepository.alertUrgentHighSnoozedTime.value = Date().addingTimeInterval(TimeInterval(UserDefaultsRepository.alertUrgentHighSnooze.value * 60))
             guard let alarms = self.tabBarController!.viewControllers?[1] as? AlarmViewController else { return }
             alarms.reloadIsSnoozed(key: "alertUrgentHighIsSnoozed", value: true)
-            alarms.reloadSnoozeTime(key: "alertUrgentHighIsSnoozed", setNil: false, value: Date().addingTimeInterval(TimeInterval(UserDefaultsRepository.alertUrgentHighSnooze.value * 60)))
-        }
+            alarms.reloadSnoozeTime(key: "alertUrgentHighSnoozedTime", setNil: false, value: Date().addingTimeInterval(TimeInterval(UserDefaultsRepository.alertUrgentHighSnooze.value * 60)))
+        } else if AlarmSound.whichAlarm == "Fast Drop Alert" {
+            UserDefaultsRepository.alertFastDropIsSnoozed.value = false
+            UserDefaultsRepository.alertFastDropSnoozedTime.value = Date().addingTimeInterval(TimeInterval(UserDefaultsRepository.alertFastDropSnooze.value * 60))
+            guard let alarms = self.tabBarController!.viewControllers?[1] as? AlarmViewController else { return }
+            alarms.reloadIsSnoozed(key: "alertFastDropIsSnoozed", value: true)
+            alarms.reloadSnoozeTime(key: "alertFastDropSnoozedTime", setNil: false, value: Date().addingTimeInterval(TimeInterval(UserDefaultsRepository.alertFastDropSnooze.value * 60)))
+        } else if AlarmSound.whichAlarm == "Fast Rise Alert" {
+            UserDefaultsRepository.alertFastRiseIsSnoozed.value = false
+            UserDefaultsRepository.alertFastRiseSnoozedTime.value = Date().addingTimeInterval(TimeInterval(UserDefaultsRepository.alertFastRiseSnooze.value * 60))
+            guard let alarms = self.tabBarController!.viewControllers?[1] as? AlarmViewController else { return }
+            alarms.reloadIsSnoozed(key: "alertFastRiseIsSnoozed", value: true)
+            alarms.reloadSnoozeTime(key: "alertFastRiseSnoozedTime", setNil: false, value: Date().addingTimeInterval(TimeInterval(UserDefaultsRepository.alertFastRiseSnooze.value * 60)))
+        }  else if AlarmSound.whichAlarm == "Missed Reading Alert" {
+           UserDefaultsRepository.alertMissedReadingIsSnoozed.value = false
+           UserDefaultsRepository.alertMissedReadingSnoozedTime.value = Date().addingTimeInterval(TimeInterval(UserDefaultsRepository.alertMissedReadingSnooze.value * 60))
+           guard let alarms = self.tabBarController!.viewControllers?[1] as? AlarmViewController else { return }
+           alarms.reloadIsSnoozed(key: "alertMissedReadingIsSnoozed", value: true)
+           alarms.reloadSnoozeTime(key: "alertMissedReadingSnoozedTime", setNil: false, value: Date().addingTimeInterval(TimeInterval(UserDefaultsRepository.alertMissedReadingSnooze.value * 60)))
+       }
     }
     
     override func viewDidLoad() {

+ 19 - 9
LoopFollow/repository/UserDefaults.swift

@@ -51,16 +51,26 @@ class UserDefaultsRepository {
     static let alertUrgentHighSnooze = UserDefaultsValue<Int>(key: "alertUrgentHighSnooze", default: 30)
     static let alertUrgentHighSnoozedTime = UserDefaultsValue<Date?>(key: "alertUrgentHighSnoozedTime", default: nil)
     static let alertUrgentHighIsSnoozed = UserDefaultsValue<Bool>(key: "alertUrgentHighIsSnoozed", default: false)
+
+    
+    static let alertFastDropActive = UserDefaultsValue<Bool>(key: "alertFastDropDeltaActive", default: true)
+    static let alertFastDropSnooze = UserDefaultsValue<Int>(key: "alertFastDropDeltaSnooze", default: 10)
+    static let alertFastDropDelta = UserDefaultsValue<Int>(key: "alertFastDropDelta", default: 10)
+    static let alertFastDropReadings = UserDefaultsValue<Int>(key: "alertFastDropReadings", default: 3)
+    static let alertFastDropUseLimit = UserDefaultsValue<Bool>(key: "alertFastDropUseLimit", default: true)
+    static let alertFastDropBelowBG = UserDefaultsValue<Int>(key: "alertFastDropBelowBG", default: 120)
+    static let alertFastDropSnoozedTime = UserDefaultsValue<Date?>(key: "alertFastDropSnoozedTime", default: nil)
+    static let alertFastDropIsSnoozed = UserDefaultsValue<Bool>(key: "alertFastDropIsSnoozed", default: false)
+    
+    static let alertFastRiseActive = UserDefaultsValue<Bool>(key: "alertFastRiseDeltaActive", default: true)
+    static let alertFastRiseSnooze = UserDefaultsValue<Int>(key: "alertFastRiseDeltaSnooze", default: 10)
+    static let alertFastRiseDelta = UserDefaultsValue<Int>(key: "alertFastRiseDelta", default: 10)
+    static let alertFastRiseReadings = UserDefaultsValue<Int>(key: "alertFastRiseReadings", default: 3)
+    static let alertFastRiseUseLimit = UserDefaultsValue<Bool>(key: "alertFastRiseUseLimit", default: true)
+    static let alertFastRiseAboveBG = UserDefaultsValue<Int>(key: "alertFastRiseAboveBG", default: 200)
+    static let alertFastRiseSnoozedTime = UserDefaultsValue<Date?>(key: "alertFastRiseSnoozedTime", default: nil)
+    static let alertFastRiseIsSnoozed = UserDefaultsValue<Bool>(key: "alertFastRiseIsSnoozed", default: false)
     
-    static let alertFastActive = UserDefaultsValue<Bool>(key: "alertFastDeltaActive", default: true)
-    static let alertFastSnooze = UserDefaultsValue<Int>(key: "alertFastDeltaSnooze", default: 10)
-    static let alertFastDelta = UserDefaultsValue<Int>(key: "alertFastDelta", default: 10)
-    static let alertFastReadings = UserDefaultsValue<Int>(key: "alertFastReadings", default: 3)
-    static let alertFastUseLimits = UserDefaultsValue<Bool>(key: "alertFastUseLimits", default: true)
-    static let alertFastLowerLimit = UserDefaultsValue<Int>(key: "alertFastBelowBG", default: 110)
-    static let alertFastUpperLimit = UserDefaultsValue<Int>(key: "alertFastAboveBG", default: 200)
-    static let alertFastSnoozedTime = UserDefaultsValue<Date?>(key: "alertFastSnoozedTime", default: nil)
-    static let alertFastIsSnoozed = UserDefaultsValue<Bool>(key: "alertFastIsSnoozed", default: false)
     
     static let alertMissedReadingActive = UserDefaultsValue<Bool>(key: "alertMissedReadingActive", default: true)
     static let alertMissedReading = UserDefaultsValue<Int>(key: "alertMissedReading", default: 30)