Преглед изворни кода

prediction length, graph lower scale, override location

Jon Fawcett пре 6 година
родитељ
комит
12ba8746b4

+ 89 - 42
LoopFollow/Controllers/Graphs.swift

@@ -58,6 +58,29 @@ extension MainViewController {
         lineBG.setDrawHighlightIndicators(false)
         lineBG.setDrawHighlightIndicators(false)
         lineBG.valueFont.withSize(50)
         lineBG.valueFont.withSize(50)
         
         
+        // Setup Prediction line details
+        var predictionChartEntry = [ChartDataEntry]()
+        let linePrediction = LineChartDataSet(entries:predictionChartEntry, label: "")
+        linePrediction.circleRadius = 3
+        linePrediction.circleColors = [NSUIColor.systemPurple]
+        linePrediction.drawCircleHoleEnabled = false
+        linePrediction.axisDependency = YAxis.AxisDependency.right
+        linePrediction.highlightEnabled = true
+        linePrediction.drawValuesEnabled = false
+        
+        if UserDefaultsRepository.showLines.value {
+            linePrediction.lineWidth = 2
+        } else {
+            linePrediction.lineWidth = 0
+        }
+        if UserDefaultsRepository.showDots.value {
+            linePrediction.drawCirclesEnabled = true
+        } else {
+            linePrediction.drawCirclesEnabled = false
+        }
+        linePrediction.setDrawHighlightIndicators(false)
+        linePrediction.valueFont.withSize(50)
+        
         
         
 
 
         // create Basal graph data
         // create Basal graph data
@@ -135,11 +158,13 @@ extension MainViewController {
         // Setup the chart data of all lines
         // Setup the chart data of all lines
         let data = LineChartData()
         let data = LineChartData()
         data.addDataSet(lineBG) // Dataset 0
         data.addDataSet(lineBG) // Dataset 0
-        data.addDataSet(lineBasal) // Dataset 1
-        data.addDataSet(lineBolus) // Dataset 2
-        data.addDataSet(lineCarbs) // Dataset 3
-        data.addDataSet(lineBasalScheduled) // Dataset 4
-        data.addDataSet(lineOverride) // Dataset 5
+        data.addDataSet(linePrediction) // Dataset 1
+        data.addDataSet(lineBasal) // Dataset 2
+        data.addDataSet(lineBolus) // Dataset 3
+        data.addDataSet(lineCarbs) // Dataset 4
+        data.addDataSet(lineBasalScheduled) // Dataset 5
+        data.addDataSet(lineOverride) // Dataset 6
+        
         data.setValueFont(UIFont.systemFont(ofSize: 12))
         data.setValueFont(UIFont.systemFont(ofSize: 12))
         
         
         // Add marker popups for bolus and carbs
         // Add marker popups for bolus and carbs
@@ -176,7 +201,7 @@ extension MainViewController {
         
         
         BGChart.rightAxis.labelTextColor = NSUIColor.label
         BGChart.rightAxis.labelTextColor = NSUIColor.label
         BGChart.rightAxis.labelPosition = YAxis.LabelPosition.insideChart
         BGChart.rightAxis.labelPosition = YAxis.LabelPosition.insideChart
-        BGChart.rightAxis.axisMinimum = 40
+        BGChart.rightAxis.axisMinimum = Double(UserDefaultsRepository.minBGValue.value)
         BGChart.rightAxis.axisMaximum = Double(maxBG)
         BGChart.rightAxis.axisMaximum = Double(maxBG)
         BGChart.rightAxis.gridLineDashLengths = [5.0, 5.0]
         BGChart.rightAxis.gridLineDashLengths = [5.0, 5.0]
         BGChart.rightAxis.valueFormatter = ChartYMMOLValueFormatter()
         BGChart.rightAxis.valueFormatter = ChartYMMOLValueFormatter()
@@ -207,6 +232,8 @@ extension MainViewController {
                    lineBG.drawCirclesEnabled = false
                    lineBG.drawCirclesEnabled = false
                }
                }
         
         
+        BGChart.rightAxis.axisMinimum = Double(UserDefaultsRepository.minBGValue.value)
+        
         // Clear limit lines so they don't add multiples when changing the settings
         // Clear limit lines so they don't add multiples when changing the settings
         BGChart.rightAxis.removeAllLimitLines()
         BGChart.rightAxis.removeAllLimitLines()
         
         
@@ -258,32 +285,7 @@ extension MainViewController {
             }
             }
         }
         }
         
         
-        // Add Prediction Data
-        if predictionData.count > 0 && bgData.count > 0 && UserDefaultsRepository.graphPrediction.value {
-            if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Graph: print prediction") }
-            var startingTime = entries[entries.count - 1].date + 300
-            if latestLoopTime < dateTimeUtils.getNowTimeIntervalUTC() - 300 {
-               startingTime = latestLoopTime + 300
-            }
-            var i = 0
-            // Add 1 hour of predictions
-            while i < 12 {
-                var predictionVal = Double(predictionData[i])
-                // Below can be turned on to prevent out of range on the graph if desired.
-                // It currently just drops them out of view
-                if predictionVal > 400 {
-               //     predictionVal = 400
-                } else if predictionVal < 0 {
-                //    predictionVal = 0
-                }
-                let value = ChartDataEntry(x: startingTime + 5, y: predictionVal)
-                mainChart.addEntry(value)
-                smallChart.addEntry(value)
-                colors.append(NSUIColor.systemPurple)
-                startingTime += 300
-                i += 1
-            }
-        }
+        
         
         
         // Set Colors
         // Set Colors
         let lineBG = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
         let lineBG = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
@@ -323,8 +325,38 @@ extension MainViewController {
         }
         }
     }
     }
     
     
+    func updatePredictionGraph() {
+        let dataIndex = 1
+        var mainChart = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
+        var smallChart = BGChartFull.lineData!.dataSets[dataIndex] as! LineChartDataSet
+        mainChart.clear()
+        smallChart.clear()
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Graph: print prediction") }
+
+        for i in 0..<predictionData.count {
+            let predictionVal = Double(predictionData[i].sgv)
+            // Below can be turned on to prevent out of range on the graph if desired.
+            // It currently just drops them out of view
+            if predictionVal > 400 {
+                //     predictionVal = 400
+            } else if predictionVal < 0 {
+                //    predictionVal = 0
+            }
+            let value = ChartDataEntry(x: predictionData[i].date, y: predictionVal)
+            mainChart.addEntry(value)
+            smallChart.addEntry(value)
+        }
+
+        BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
+        BGChart.data?.notifyDataChanged()
+        BGChart.notifyDataSetChanged()
+        BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
+        BGChartFull.data?.notifyDataChanged()
+        BGChartFull.notifyDataSetChanged()
+    }
+    
     func updateBasalGraph() {
     func updateBasalGraph() {
-        var dataIndex = 1
+        var dataIndex = 2
         BGChart.lineData?.dataSets[dataIndex].clear()
         BGChart.lineData?.dataSets[dataIndex].clear()
         var maxBasal = UserDefaultsRepository.minBasalScale.value
         var maxBasal = UserDefaultsRepository.minBasalScale.value
         for i in 0..<basalData.count{
         for i in 0..<basalData.count{
@@ -343,7 +375,7 @@ extension MainViewController {
     }
     }
     
     
     func updateBasalScheduledGraph() {
     func updateBasalScheduledGraph() {
-        var dataIndex = 4
+        var dataIndex = 5
         BGChart.lineData?.dataSets[dataIndex].clear()
         BGChart.lineData?.dataSets[dataIndex].clear()
         for i in 0..<basalScheduleData.count{
         for i in 0..<basalScheduleData.count{
             let value = ChartDataEntry(x: Double(basalScheduleData[i].date), y: Double(basalScheduleData[i].basalRate))
             let value = ChartDataEntry(x: Double(basalScheduleData[i].date), y: Double(basalScheduleData[i].basalRate))
@@ -356,7 +388,7 @@ extension MainViewController {
     }
     }
     
     
     func updateBolusGraph() {
     func updateBolusGraph() {
-        var dataIndex = 2
+        var dataIndex = 3
         BGChart.lineData?.dataSets[dataIndex].clear()
         BGChart.lineData?.dataSets[dataIndex].clear()
         for i in 0..<bolusData.count{
         for i in 0..<bolusData.count{
             let formatter = NumberFormatter()
             let formatter = NumberFormatter()
@@ -378,7 +410,7 @@ extension MainViewController {
     }
     }
     
     
     func updateCarbGraph() {
     func updateCarbGraph() {
-        var dataIndex = 3
+        var dataIndex = 4
         BGChart.lineData?.dataSets[dataIndex].clear()
         BGChart.lineData?.dataSets[dataIndex].clear()
         for i in 0..<carbData.count{
         for i in 0..<carbData.count{
             let formatter = NumberFormatter()
             let formatter = NumberFormatter()
@@ -417,9 +449,24 @@ extension MainViewController {
         lineBG.highlightColor = NSUIColor.label
         lineBG.highlightColor = NSUIColor.label
         lineBG.drawValuesEnabled = false
         lineBG.drawValuesEnabled = false
         lineBG.lineWidth = 2
         lineBG.lineWidth = 2
+        
+        // Setup Prediction line details
+        var predictionChartEntry = [ChartDataEntry]()
+        let linePrediction = LineChartDataSet(entries:predictionChartEntry, label: "")
+        linePrediction.drawCirclesEnabled = false
+        //line2.setDrawHighlightIndicators(false)
+        linePrediction.setColor(NSUIColor.systemPurple)
+        linePrediction.highlightEnabled = true
+        linePrediction.drawHorizontalHighlightIndicatorEnabled = false
+        linePrediction.drawVerticalHighlightIndicatorEnabled = false
+        linePrediction.highlightColor = NSUIColor.label
+        linePrediction.drawValuesEnabled = false
+        linePrediction.lineWidth = 2
+        
 
 
-        let data2 = LineChartData()
-        data2.addDataSet(lineBG)
+        let data = LineChartData()
+        data.addDataSet(lineBG)
+        data.addDataSet(linePrediction)
         BGChartFull.highlightPerDragEnabled = true
         BGChartFull.highlightPerDragEnabled = true
         BGChartFull.leftAxis.enabled = false
         BGChartFull.leftAxis.enabled = false
         BGChartFull.rightAxis.enabled = false
         BGChartFull.rightAxis.enabled = false
@@ -428,12 +475,12 @@ extension MainViewController {
         BGChartFull.scaleYEnabled = false
         BGChartFull.scaleYEnabled = false
         BGChartFull.scaleXEnabled = false
         BGChartFull.scaleXEnabled = false
         BGChartFull.drawGridBackgroundEnabled = false
         BGChartFull.drawGridBackgroundEnabled = false
-        BGChartFull.data = data2
+        BGChartFull.data = data
     }
     }
     
     
     
     
     func updateOverrideGraph() {
     func updateOverrideGraph() {
-        var dataIndex = 5
+        var dataIndex = 6
         var chart = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
         var chart = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
         chart.clear()
         chart.clear()
         
         
@@ -443,9 +490,9 @@ extension MainViewController {
             BGChart.data?.dataSets[dataIndex].addEntry(value)
             BGChart.data?.dataSets[dataIndex].addEntry(value)
             
             
             if Double(overrideData[i].value) == 1.0 {
             if Double(overrideData[i].value) == 1.0 {
-                colors.append(NSUIColor.systemTeal.withAlphaComponent(0.0))
+                colors.append(NSUIColor.systemGray.withAlphaComponent(0.0))
             } else {
             } else {
-                colors.append(NSUIColor.systemTeal)
+                colors.append(NSUIColor.systemGray.withAlphaComponent(0.5))
             }
             }
         }
         }
         
         

+ 15 - 8
LoopFollow/Controllers/NightScout.swift

@@ -341,7 +341,6 @@ extension MainViewController {
         if let lastLoopRecord = lastDeviceStatus?["loop"] as! [String : AnyObject]? {
         if let lastLoopRecord = lastDeviceStatus?["loop"] as! [String : AnyObject]? {
             if let lastLoopTime = formatter.date(from: (lastLoopRecord["timestamp"] as! String))?.timeIntervalSince1970  {
             if let lastLoopTime = formatter.date(from: (lastLoopRecord["timestamp"] as! String))?.timeIntervalSince1970  {
                 UserDefaultsRepository.alertLastLoopTime.value = lastLoopTime
                 UserDefaultsRepository.alertLastLoopTime.value = lastLoopTime
-                latestLoopTime = lastLoopTime
                 if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "lastLoopTime: " + String(lastLoopTime)) }
                 if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "lastLoopTime: " + String(lastLoopTime)) }
                 if let failure = lastLoopRecord["failureReason"] {
                 if let failure = lastLoopRecord["failureReason"] {
                     LoopStatusLabel.text = "X"
                     LoopStatusLabel.text = "X"
@@ -365,17 +364,24 @@ extension MainViewController {
                         latestCOB = String(format:"%.0f", cobdata["cob"] as! Double)
                         latestCOB = String(format:"%.0f", cobdata["cob"] as! Double)
                     }
                     }
                     if let predictdata = lastLoopRecord["predicted"] as? [String:AnyObject] {
                     if let predictdata = lastLoopRecord["predicted"] as? [String:AnyObject] {
-                        let prediction = predictdata["values"] as! [Double]
+                        let prediction = predictdata["values"] as! [Int]
                         PredictionLabel.text = bgUnits.toDisplayUnits(String(Int(prediction.last!)))
                         PredictionLabel.text = bgUnits.toDisplayUnits(String(Int(prediction.last!)))
                         PredictionLabel.textColor = UIColor.systemPurple
                         PredictionLabel.textColor = UIColor.systemPurple
-                        predictionData.removeAll()
-                        if UserDefaultsRepository.downloadPrediction.value {
+                        if UserDefaultsRepository.downloadPrediction.value && latestLoopTime < lastLoopTime {
+                            predictionData.removeAll()
+                            var predictionTime = lastLoopTime + 300
+                            let toLoad = Int(UserDefaultsRepository.predictionToLoad.value * 12)
                             var i = 1
                             var i = 1
-                            while i <= 12 {
-                                predictionData.append(prediction[i])
+                            while i <= toLoad {
+                                let prediction = DataStructs.sgvData(sgv: prediction[i], date: predictionTime, direction: "flat")
+                                predictionData.append(prediction)
+                                predictionTime += 300
                                 i += 1
                                 i += 1
                             }
                             }
                         }
                         }
+                        if UserDefaultsRepository.graphPrediction.value {
+                            updatePredictionGraph()
+                        }
                     }
                     }
                     if let loopStatus = lastLoopRecord["recommendedTempBasal"] as? [String:AnyObject] {
                     if let loopStatus = lastLoopRecord["recommendedTempBasal"] as? [String:AnyObject] {
                         if let tempBasalTime = formatter.date(from: (loopStatus["timestamp"] as! String))?.timeIntervalSince1970 {
                         if let tempBasalTime = formatter.date(from: (loopStatus["timestamp"] as! String))?.timeIntervalSince1970 {
@@ -408,6 +414,7 @@ extension MainViewController {
                     LoopStatusLabel.text = "⚠"
                     LoopStatusLabel.text = "⚠"
                     latestLoopStatusString = "⚠"
                     latestLoopStatusString = "⚠"
                 }
                 }
+                latestLoopTime = lastLoopTime
             } // end lastLoopTime
             } // end lastLoopTime
         } // end lastLoop Record
         } // end lastLoop Record
         
         
@@ -454,13 +461,13 @@ extension MainViewController {
                         if let isActive = override["active"] as? Bool {
                         if let isActive = override["active"] as? Bool {
                             if isActive {
                             if isActive {
                                 if let multiplier = override["multiplier"] as? Double {
                                 if let multiplier = override["multiplier"] as? Double {
-                                    let override = DataStructs.overrideGraphStruct(value: multiplier, date: timestamp, sgv: 40)
+                                    let override = DataStructs.overrideGraphStruct(value: multiplier, date: timestamp, sgv: Int(UserDefaultsRepository.overrideDisplayLocation.value))
                                     overrideData.append(override)
                                     overrideData.append(override)
                                 }
                                 }
                                 
                                 
                             } else {
                             } else {
                                 let multiplier = 1.0 as Double
                                 let multiplier = 1.0 as Double
-                                let override = DataStructs.overrideGraphStruct(value: multiplier, date: timestamp, sgv: 40)
+                                let override = DataStructs.overrideGraphStruct(value: multiplier, date: timestamp, sgv: Int(UserDefaultsRepository.overrideDisplayLocation.value))
                                 overrideData.append(override)
                                 overrideData.append(override)
                             }
                             }
                         }
                         }

+ 1 - 1
LoopFollow/ViewControllers/MainViewController.swift

@@ -93,7 +93,7 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
     var bolusData: [bolusCarbGraphStruct] = []
     var bolusData: [bolusCarbGraphStruct] = []
     var carbData: [bolusCarbGraphStruct] = []
     var carbData: [bolusCarbGraphStruct] = []
     var overrideData: [DataStructs.overrideGraphStruct] = []
     var overrideData: [DataStructs.overrideGraphStruct] = []
-    var predictionData: [Double] = []
+    var predictionData: [DataStructs.sgvData] = []
     var chartData = LineChartData()
     var chartData = LineChartData()
     var newBGPulled = false
     var newBGPulled = false
     var lastCalDate: Double = 0
     var lastCalDate: Double = 0

+ 42 - 1
LoopFollow/ViewControllers/SettingsViewController.swift

@@ -233,6 +233,16 @@ class SettingsViewController: FormViewController {
                         UserDefaultsRepository.offsetCarbsBolus.value = value
                         UserDefaultsRepository.offsetCarbsBolus.value = value
                         
                         
             }
             }
+            <<< StepperRow("predictionToLoad") { row in
+                row.title = "Hours of Prediction"
+                row.cell.stepper.stepValue = 0.25
+                row.cell.stepper.minimumValue = 0.0
+                row.cell.stepper.maximumValue = 6.0
+                row.value = Double(UserDefaultsRepository.predictionToLoad.value)
+            }.onChange { [weak self] row in
+                    guard let value = row.value else { return }
+                    UserDefaultsRepository.predictionToLoad.value = value
+            }
         <<< StepperRow("minBGScale") { row in
         <<< StepperRow("minBGScale") { row in
             row.title = "Min BG Scale"
             row.title = "Min BG Scale"
             row.cell.stepper.stepValue = 1
             row.cell.stepper.stepValue = 1
@@ -246,7 +256,24 @@ class SettingsViewController: FormViewController {
         }.onChange { [weak self] row in
         }.onChange { [weak self] row in
                 guard let value = row.value else { return }
                 guard let value = row.value else { return }
                 UserDefaultsRepository.minBGScale.value = Float(value)
                 UserDefaultsRepository.minBGScale.value = Float(value)
-        }
+            }
+            <<< StepperRow("minBGValue") { row in
+                row.title = "Min BG Display"
+                row.cell.stepper.stepValue = 1
+                row.cell.stepper.minimumValue = -40
+                row.cell.stepper.maximumValue = 40
+                row.value = Double(UserDefaultsRepository.minBGValue.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.minBGValue.value = Float(value)
+                // Force main screen update
+                guard let mainScreen = self?.tabBarController!.viewControllers?[0] as? MainViewController else { return }
+                mainScreen.updateBGGraphSettings()
+            }
         <<< StepperRow("minBasalScale") { row in
         <<< StepperRow("minBasalScale") { row in
             row.title = "Min Basal Scale"
             row.title = "Min Basal Scale"
             row.cell.stepper.stepValue = 0.5
             row.cell.stepper.stepValue = 0.5
@@ -291,6 +318,20 @@ class SettingsViewController: FormViewController {
             guard let mainScreen = self?.tabBarController!.viewControllers?[0] as? MainViewController else { return }
             guard let mainScreen = self?.tabBarController!.viewControllers?[0] as? MainViewController else { return }
             mainScreen.updateBGGraphSettings()
             mainScreen.updateBGGraphSettings()
         }
         }
+        <<< StepperRow("overrideDisplayLocation") { row in
+            row.title = "Override BG Location"
+            row.cell.stepper.stepValue = 1
+            row.cell.stepper.minimumValue = Double(UserDefaultsRepository.minBGValue.value)
+            row.cell.stepper.maximumValue = Double(UserDefaultsRepository.minBGScale.value)
+            row.value = Double(UserDefaultsRepository.overrideDisplayLocation.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.overrideDisplayLocation.value = Float(value)
+            }
     }
     }
     
     
     func buildWatchSettings(){
     func buildWatchSettings(){

+ 3 - 0
LoopFollow/repository/UserDefaults.swift

@@ -21,8 +21,11 @@ class UserDefaultsRepository {
     static let showLines = UserDefaultsValue<Bool>(key: "showLines", default: true)
     static let showLines = UserDefaultsValue<Bool>(key: "showLines", default: true)
     static let offsetCarbsBolus = UserDefaultsValue<Bool>(key: "offsetCarbsBolus", default: true)
     static let offsetCarbsBolus = UserDefaultsValue<Bool>(key: "offsetCarbsBolus", default: true)
     static let hoursToLoad = UserDefaultsValue<Int>(key: "hoursToLoad", default: 24)
     static let hoursToLoad = UserDefaultsValue<Int>(key: "hoursToLoad", default: 24)
+    static let predictionToLoad = UserDefaultsValue<Double>(key: "predictionToLoad", default: 1)
     static let minBasalScale = UserDefaultsValue<Double>(key: "minBasalScale", default: 5.0)
     static let minBasalScale = UserDefaultsValue<Double>(key: "minBasalScale", default: 5.0)
     static let minBGScale = UserDefaultsValue<Float>(key: "minBGScale", default: 250.0)
     static let minBGScale = UserDefaultsValue<Float>(key: "minBGScale", default: 250.0)
+    static let minBGValue = UserDefaultsValue<Float>(key: "minBGValue", default: 40.0)
+    static let overrideDisplayLocation = UserDefaultsValue<Float>(key: "overrideDisplayLocation", default: 40.0)
     static let lowLine = UserDefaultsValue<Float>(key: "lowLine", default: 70.0)
     static let lowLine = UserDefaultsValue<Float>(key: "lowLine", default: 70.0)
     static let highLine = UserDefaultsValue<Float>(key: "highLine", default: 180.0)
     static let highLine = UserDefaultsValue<Float>(key: "highLine", default: 180.0)