Skip to content

Commit e5170b9

Browse files
committed
Adding retrospection info to the prediction view, removing it from status.
Also removing Bolus IOB to avoid further confusion. Fixes #155
1 parent 835c767 commit e5170b9

File tree

6 files changed

+58
-72
lines changed

6 files changed

+58
-72
lines changed

Loop.xcodeproj/project.pbxproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
4354003A1C9FB81100D5819C /* UIColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43DE92501C541832001FFDE1 /* UIColor.swift */; };
5353
43649A631C7A347F00523D7F /* CollectionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43649A621C7A347F00523D7F /* CollectionType.swift */; };
5454
436A0DA51D236A2A00104B24 /* LoopError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 436A0DA41D236A2A00104B24 /* LoopError.swift */; };
55+
436A0E7B1D7DE13400D6475D /* NSNumberFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 436A0E7A1D7DE13400D6475D /* NSNumberFormatter.swift */; };
5556
436FACEE1D0BA636004E2427 /* InsulinDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 436FACED1D0BA636004E2427 /* InsulinDataSource.swift */; };
5657
43776F901B8022E90074EA36 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43776F8F1B8022E90074EA36 /* AppDelegate.swift */; };
5758
43776F971B8022E90074EA36 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 43776F951B8022E90074EA36 /* Main.storyboard */; };
@@ -274,6 +275,7 @@
274275
435400331C9F878D00D5819C /* SetBolusUserInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetBolusUserInfo.swift; sourceTree = "<group>"; };
275276
43649A621C7A347F00523D7F /* CollectionType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionType.swift; sourceTree = "<group>"; };
276277
436A0DA41D236A2A00104B24 /* LoopError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoopError.swift; sourceTree = "<group>"; };
278+
436A0E7A1D7DE13400D6475D /* NSNumberFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSNumberFormatter.swift; sourceTree = "<group>"; };
277279
436FACED1D0BA636004E2427 /* InsulinDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InsulinDataSource.swift; sourceTree = "<group>"; };
278280
43776F8C1B8022E90074EA36 /* Loop.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Loop.app; sourceTree = BUILT_PRODUCTS_DIR; };
279281
43776F8F1B8022E90074EA36 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = AppDelegate.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
@@ -606,6 +608,7 @@
606608
43E344A01B9E144300C85C07 /* Extensions */ = {
607609
isa = PBXGroup;
608610
children = (
611+
C17884621D51A7A400405663 /* BatteryIndicator.swift */,
609612
4331E0771C85302200FBE832 /* CGPoint.swift */,
610613
4346D1F51C78501000ABAFE3 /* ChartPoint.swift */,
611614
43649A621C7A347F00523D7F /* CollectionType.swift */,
@@ -616,13 +619,13 @@
616619
4302F4DA1D4D6E9F00F0FCAF /* NSData.swift */,
617620
43CE7CDD1CA8B63E003CC1B0 /* NSDate.swift */,
618621
4398973A1CD2FC2000223065 /* NSDateFormatter.swift */,
622+
436A0E7A1D7DE13400D6475D /* NSNumberFormatter.swift */,
619623
439897341CD2F7DE00223065 /* NSTimeInterval.swift */,
620624
43E344A31B9E1B1C00C85C07 /* NSUserDefaults.swift */,
621625
43F41C361D3BF32400C11ED6 /* UIAlertController.swift */,
622626
43DE92501C541832001FFDE1 /* UIColor.swift */,
623627
437CEEE31CDE5C0A003C8C80 /* UIImage.swift */,
624628
434FF1ED1CF27EEF000DB779 /* UITableViewCell.swift */,
625-
C17884621D51A7A400405663 /* BatteryIndicator.swift */,
626629
);
627630
path = Extensions;
628631
sourceTree = "<group>";
@@ -1043,6 +1046,7 @@
10431046
437D9BA31D7BC977007245E8 /* PredictionTableViewController.swift in Sources */,
10441047
43F41C371D3BF32400C11ED6 /* UIAlertController.swift in Sources */,
10451048
437CEEBC1CD6DE6A003C8C80 /* HUDView.swift in Sources */,
1049+
436A0E7B1D7DE13400D6475D /* NSNumberFormatter.swift in Sources */,
10461050
434F545F1D288345002A9274 /* ShareService.swift in Sources */,
10471051
43FBEDD81D73843700B21F22 /* LevelMaskView.swift in Sources */,
10481052
4354003A1C9FB81100D5819C /* UIColor.swift in Sources */,
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//
2+
// NSNumberFormatter.swift
3+
// Loop
4+
//
5+
// Created by Nate Racklyeft on 9/5/16.
6+
// Copyright © 2016 Nathan Racklyeft. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import HealthKit
11+
12+
13+
extension NSNumberFormatter {
14+
static func glucoseFormatter(for unit: HKUnit) -> NSNumberFormatter {
15+
let numberFormatter = NSNumberFormatter()
16+
numberFormatter.numberStyle = .DecimalStyle
17+
numberFormatter.minimumFractionDigits = unit.preferredMinimumFractionDigits
18+
numberFormatter.maximumSignificantDigits = 3
19+
numberFormatter.usesSignificantDigits = true
20+
21+
return numberFormatter
22+
}
23+
}

Loop/Managers/LoopDataManager.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -228,14 +228,14 @@ final class LoopDataManager {
228228

229229
- parameter resultsHandler: A closure called once the values have been retrieved. The closure takes the following arguments:
230230
- predictedGlucose: The calculated timeline of predicted glucose values
231-
- reflectedGlucose: The retrospective prediction over a recent period of glucose samples
231+
- retrospectivePredictedGlucose: The retrospective prediction over a recent period of glucose samples
232232
- recommendedTempBasal: The recommended temp basal based on predicted glucose
233233
- lastTempBasal: The last set temp basal
234234
- lastLoopCompleted: The last date at which a loop completed, from prediction to dose (if dosing is enabled)
235235
- insulinOnBoard Current insulin on board
236236
- error: An error in the current state of the loop, or one that happened during the last attempt to loop.
237237
*/
238-
func getLoopStatus(resultsHandler: (predictedGlucose: [GlucoseValue]?, reflectedGlucose: [GlucoseValue]?, recommendedTempBasal: TempBasalRecommendation?, lastTempBasal: DoseEntry?, lastLoopCompleted: NSDate?, insulinOnBoard: InsulinValue?, error: ErrorType?) -> Void) {
238+
func getLoopStatus(resultsHandler: (predictedGlucose: [GlucoseValue]?, retrospectivePredictedGlucose: [GlucoseValue]?, recommendedTempBasal: TempBasalRecommendation?, lastTempBasal: DoseEntry?, lastLoopCompleted: NSDate?, insulinOnBoard: InsulinValue?, error: ErrorType?) -> Void) {
239239
dispatch_async(dataAccessQueue) {
240240
var error: ErrorType?
241241

@@ -245,7 +245,7 @@ final class LoopDataManager {
245245
error = updateError
246246
}
247247

248-
resultsHandler(predictedGlucose: self.predictedGlucose, reflectedGlucose: self.retrospectivePredictedGlucose, recommendedTempBasal: self.recommendedTempBasal, lastTempBasal: self.lastTempBasal, lastLoopCompleted: self.lastLoopCompleted, insulinOnBoard: self.insulinOnBoard, error: error ?? self.lastLoopError)
248+
resultsHandler(predictedGlucose: self.predictedGlucose, retrospectivePredictedGlucose: self.retrospectivePredictedGlucose, recommendedTempBasal: self.recommendedTempBasal, lastTempBasal: self.lastTempBasal, lastLoopCompleted: self.lastLoopCompleted, insulinOnBoard: self.insulinOnBoard, error: error ?? self.lastLoopError)
249249
}
250250
}
251251

@@ -294,7 +294,7 @@ final class LoopDataManager {
294294
didSet {
295295
predictedGlucose = nil
296296

297-
// Carb data may be back-dated, so re-calculate the reflected glucose.
297+
// Carb data may be back-dated, so re-calculate the retrospective glucose.
298298
retrospectivePredictedGlucose = nil
299299
}
300300
}
@@ -512,7 +512,7 @@ final class LoopDataManager {
512512
)
513513
}
514514

515-
self.predictedGlucose = predictionWithRetrospectiveEffect
515+
self.predictedGlucose = retrospectiveCorrectionEnabled ? predictionWithRetrospectiveEffect : prediction
516516

517517
guard let
518518
maxBasal = deviceDataManager.maximumBasalRatePerHour,

Loop/Managers/NightscoutDataManager.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,15 @@ class NightscoutDataManager {
3434
return
3535
}
3636

37-
deviceDataManager.loopManager.getLoopStatus { (predictedGlucose, _, recommendedTempBasal, lastTempBasal, lastLoopCompleted, insulinOnBoard, loopError) in
37+
deviceDataManager.loopManager.getLoopStatus { (predictedGlucose, _, recommendedTempBasal, lastTempBasal, _, insulinOnBoard, loopError) in
3838

3939
self.deviceDataManager.loopManager.getRecommendedBolus { (bolusUnits, getBolusError) in
40-
if getBolusError != nil {
41-
self.deviceDataManager.logger.addError(getBolusError!, fromSource: "NightscoutDataManager")
40+
if let getBolusError = getBolusError {
41+
self.deviceDataManager.logger.addError(getBolusError, fromSource: "NightscoutDataManager")
4242
}
4343
self.uploadLoopStatus(insulinOnBoard, predictedGlucose: predictedGlucose, recommendedTempBasal: recommendedTempBasal, recommendedBolus: bolusUnits, lastTempBasal: lastTempBasal, loopError: loopError ?? getBolusError)
4444
}
4545
}
46-
47-
4846
}
4947

5048
private var lastTempBasalUploaded: DoseEntry?

Loop/Models/PredictionInputEffect.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ enum PredictionInputEffect {
3636
case .insulin:
3737
return String(format: NSLocalizedString("Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)", comment: "Description of the prediction input effect for insulin"), unit.glucoseUnitDisplayString)
3838
case .momentum:
39-
return NSLocalizedString("15-min Glucose Regression Coefficient (b₁), continued with decay over 30min", comment: "Description of the prediction input effect for glucose momentum")
39+
return NSLocalizedString("15 min glucose regression coefficient (b₁), continued with decay over 30 min", comment: "Description of the prediction input effect for glucose momentum")
4040
case .retrospection:
41-
return NSLocalizedString("30-min Retrospective Correction of Glucose Prediction vs Actual, continued with decay over 60min", comment: "Description of the prediction input effect for retrospective correction")
41+
return NSLocalizedString("30 mim comparison of glucose prediction vs actual, continued with decay over 60 min", comment: "Description of the prediction input effect for retrospective correction")
4242
}
4343
}
4444
}

Loop/View Controllers/StatusTableViewController.swift

Lines changed: 20 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize
136136
needsRefresh = false
137137
reloading = true
138138

139-
tableView.reloadSections(NSIndexSet(indexesInRange: NSMakeRange(Section.Pump.rawValue, Section.count - Section.Pump.rawValue)
139+
tableView.reloadSections(NSIndexSet(indexesInRange: NSMakeRange(Section.Sensor.rawValue, Section.count - Section.Sensor.rawValue)
140140
), withRowAnimation: visible ? .Automatic : .None)
141141

142142
let calendar = NSCalendar.currentCalendar()
@@ -171,14 +171,13 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize
171171
}
172172

173173
dispatch_group_enter(reloadGroup)
174-
dataManager.loopManager.getLoopStatus { (predictedGlucose, reflectedGlucose, recommendedTempBasal, lastTempBasal, lastLoopCompleted, insulinOnBoard, error) -> Void in
174+
dataManager.loopManager.getLoopStatus { (predictedGlucose, _, recommendedTempBasal, lastTempBasal, lastLoopCompleted, _, error) -> Void in
175175
if error != nil {
176176
self.needsRefresh = true
177177
}
178178

179179
self.charts.predictedGlucoseValues = predictedGlucose ?? []
180180
self.recommendedTempBasal = recommendedTempBasal
181-
self.reflectedGlucose = reflectedGlucose
182181
self.lastTempBasal = lastTempBasal
183182
self.lastLoopCompleted = lastLoopCompleted
184183

@@ -266,10 +265,9 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize
266265
private enum Section: Int {
267266
case Charts = 0
268267
case Status
269-
case Pump
270268
case Sensor
271269

272-
static let count = 4
270+
static let count = 3
273271
}
274272

275273
// MARK: - Chart Section Data
@@ -289,15 +287,12 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize
289287

290288
private enum StatusRow: Int {
291289
case RecommendedBasal = 0
292-
case ReflectedGlucose
293290

294-
static let count = 2
291+
static let count = 1
295292
}
296293

297294
private var recommendedTempBasal: LoopDataManager.TempBasalRecommendation?
298295

299-
private var reflectedGlucose: [GlucoseValue]?
300-
301296
private var lastTempBasal: DoseEntry? {
302297
didSet {
303298
guard let scheduledBasal = dataManager.basalRateSchedule?.between(NSDate(), NSDate()).first else {
@@ -372,12 +367,6 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize
372367

373368
// MARK: - Pump/Sensor Section Data
374369

375-
private enum PumpRow: Int {
376-
case InsulinOnBoard = 0
377-
378-
static let count = 1
379-
}
380-
381370
private enum SensorRow: Int {
382371
case State
383372

@@ -424,8 +413,6 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize
424413
return ChartRow.count
425414
case .Status:
426415
return StatusRow.count
427-
case .Pump:
428-
return PumpRow.count
429416
case .Sensor:
430417
return SensorRow.count
431418
}
@@ -494,35 +481,6 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize
494481
} else {
495482
cell.accessoryView = nil
496483
}
497-
case .ReflectedGlucose:
498-
cell.textLabel?.text = "Predicted 30m ago"
499-
500-
if let startGlucose = reflectedGlucose?.first, let endGlucose = reflectedGlucose?.last, let currentGlucose = self.dataManager.glucoseStore?.latestGlucose {
501-
let startValue = Int(startGlucose.quantity.doubleValueForUnit(charts.glucoseUnit))
502-
let predictedValue = Int(endGlucose.quantity.doubleValueForUnit(charts.glucoseUnit))
503-
let currentValue = Int(currentGlucose.quantity.doubleValueForUnit(charts.glucoseUnit))
504-
505-
cell.detailTextLabel?.text = "\(startValue)\(predictedValue) @ \(timeFormatter.stringFromDate(endGlucose.startDate)) \(currentValue - predictedValue)"
506-
} else {
507-
cell.detailTextLabel?.text = emptyValueString
508-
}
509-
}
510-
511-
return cell
512-
case .Pump:
513-
let cell = tableView.dequeueReusableCellWithIdentifier(UITableViewCell.className, forIndexPath: indexPath)
514-
cell.selectionStyle = .None
515-
516-
switch PumpRow(rawValue: indexPath.row)! {
517-
case .InsulinOnBoard:
518-
cell.textLabel?.text = NSLocalizedString("Bolus Insulin on Board", comment: "The title of the cell containing the estimated amount of active bolus insulin in the body")
519-
520-
if let iob = dataManager.latestPumpStatusFromMySentry?.iob {
521-
let numberValue = NSNumber(double: iob).descriptionWithLocale(locale)
522-
cell.detailTextLabel?.text = "\(numberValue) Units"
523-
} else {
524-
cell.detailTextLabel?.text = emptyValueString
525-
}
526484
}
527485

528486
return cell
@@ -552,7 +510,7 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize
552510
case .IOB, .Dose, .COB:
553511
return 85
554512
}
555-
case .Status, .Pump, .Sensor:
513+
case .Status, .Sensor:
556514
return UITableViewAutomaticDimension
557515
}
558516
}
@@ -562,13 +520,6 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize
562520
case .Charts:
563521
switch ChartRow(rawValue: indexPath.row)! {
564522
case .Glucose:
565-
// if let URL = NSURL(string: "dexcomcgm://") where UIApplication.sharedApplication().canOpenURL(URL) {
566-
// UIApplication.sharedApplication().openURL(URL)
567-
// }
568-
// else if let URL = NSURL(string: "dexcomshare://") where UIApplication.sharedApplication().canOpenURL(URL) {
569-
// UIApplication.sharedApplication().openURL(URL)
570-
// }
571-
572523
performSegueWithIdentifier(PredictionTableViewController.className, sender: indexPath)
573524
case .IOB, .Dose:
574525
performSegueWithIdentifier(InsulinDeliveryTableViewController.className, sender: indexPath)
@@ -596,15 +547,11 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize
596547
}
597548
}
598549
}
599-
case .ReflectedGlucose:
600-
break
601550
}
602551
case .Sensor:
603552
if let URL = NSURL(string: "dexcomcgm://") {
604553
UIApplication.sharedApplication().openURL(URL)
605554
}
606-
case .Pump:
607-
break
608555
}
609556
}
610557

@@ -744,7 +691,21 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize
744691

745692
@IBOutlet var loopCompletionHUD: LoopCompletionHUDView!
746693

747-
@IBOutlet var glucoseHUD: GlucoseHUDView!
694+
@IBOutlet var glucoseHUD: GlucoseHUDView! {
695+
didSet {
696+
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(openCGMApp(_:)))
697+
glucoseHUD.addGestureRecognizer(tapGestureRecognizer)
698+
}
699+
}
700+
701+
@objc private func openCGMApp(_: AnyObject) {
702+
if let URL = NSURL(string: "dexcomcgm://") where UIApplication.sharedApplication().canOpenURL(URL) {
703+
UIApplication.sharedApplication().openURL(URL)
704+
}
705+
else if let URL = NSURL(string: "dexcomshare://") where UIApplication.sharedApplication().canOpenURL(URL) {
706+
UIApplication.sharedApplication().openURL(URL)
707+
}
708+
}
748709

749710
@IBOutlet var basalRateHUD: BasalRateHUDView!
750711

0 commit comments

Comments
 (0)