Skip to content

Commit d995753

Browse files
authored
Merge pull request #228 from mddub/cob-to-nightscout
Upload carbs-on-board to Nightscout
2 parents 16cec2e + 558e674 commit d995753

File tree

5 files changed

+38
-10
lines changed

5 files changed

+38
-10
lines changed

Loop/Managers/LoopDataManager.swift

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ final class LoopDataManager {
7676
center.addObserver(forName: .CarbEntriesDidUpdate, object: nil, queue: nil) { (note) -> Void in
7777
self.dataAccessQueue.async {
7878
self.carbEffect = nil
79+
self.carbsOnBoardSeries = nil
7980
self.notify(forChange: .carbs)
8081
}
8182
}
@@ -165,6 +166,18 @@ final class LoopDataManager {
165166
}
166167
}
167168

169+
if carbsOnBoardSeries == nil, let carbStore = deviceDataManager.carbStore {
170+
updateGroup.enter()
171+
carbStore.getCarbsOnBoardValues { (values, error) in
172+
if let error = error {
173+
self.deviceDataManager.logger.addError(error, fromSource: "CarbStore")
174+
}
175+
176+
self.carbsOnBoardSeries = values
177+
updateGroup.leave()
178+
}
179+
}
180+
168181
if insulinEffect == nil {
169182
updateGroup.enter()
170183
updateInsulinEffect { (effects, error) in
@@ -229,9 +242,10 @@ final class LoopDataManager {
229242
- lastTempBasal: The last set temp basal
230243
- lastLoopCompleted: The last date at which a loop completed, from prediction to dose (if dosing is enabled)
231244
- insulinOnBoard Current insulin on board
245+
- carbsOnBoard Current carbs on board
232246
- error: An error in the current state of the loop, or one that happened during the last attempt to loop.
233247
*/
234-
func getLoopStatus(_ resultsHandler: @escaping (_ predictedGlucose: [GlucoseValue]?, _ retrospectivePredictedGlucose: [GlucoseValue]?, _ recommendedTempBasal: TempBasalRecommendation?, _ lastTempBasal: DoseEntry?, _ lastLoopCompleted: Date?, _ insulinOnBoard: InsulinValue?, _ error: Error?) -> Void) {
248+
func getLoopStatus(_ resultsHandler: @escaping (_ predictedGlucose: [GlucoseValue]?, _ retrospectivePredictedGlucose: [GlucoseValue]?, _ recommendedTempBasal: TempBasalRecommendation?, _ lastTempBasal: DoseEntry?, _ lastLoopCompleted: Date?, _ insulinOnBoard: InsulinValue?, _ carbsOnBoard: CarbValue?, _ error: Error?) -> Void) {
235249
dataAccessQueue.async {
236250
var error: Error?
237251

@@ -241,7 +255,9 @@ final class LoopDataManager {
241255
error = updateError
242256
}
243257

244-
resultsHandler(self.predictedGlucose, self.retrospectivePredictedGlucose, self.recommendedTempBasal, self.lastTempBasal, self.lastLoopCompleted, self.insulinOnBoard, error ?? self.lastLoopError)
258+
let currentCOB = self.carbsOnBoardSeries?.closestPriorToDate(Date())
259+
260+
resultsHandler(self.predictedGlucose, self.retrospectivePredictedGlucose, self.recommendedTempBasal, self.lastTempBasal, self.lastLoopCompleted, self.insulinOnBoard, currentCOB, error ?? self.lastLoopError)
245261
}
246262
}
247263

@@ -294,6 +310,7 @@ final class LoopDataManager {
294310
retrospectivePredictedGlucose = nil
295311
}
296312
}
313+
private var carbsOnBoardSeries: [CarbValue]?
297314
private var insulinEffect: [GlucoseEffect]? {
298315
didSet {
299316
if let bolusDate = lastBolus?.date, bolusDate.timeIntervalSinceNow < TimeInterval(minutes: -5) {
@@ -544,6 +561,7 @@ final class LoopDataManager {
544561
self.dataAccessQueue.async {
545562
if success {
546563
self.carbEffect = nil
564+
self.carbsOnBoardSeries = nil
547565

548566
do {
549567
try self.update()
@@ -673,7 +691,7 @@ extension LoopDataManager {
673691
///
674692
/// - parameter completionHandler: A closure called once the report has been generated. The closure takes a single argument of the report string.
675693
func generateDiagnosticReport(_ completionHandler: @escaping (_ report: String) -> Void) {
676-
getLoopStatus { (predictedGlucose, retrospectivePredictedGlucose, recommendedTempBasal, lastTempBasal, lastLoopCompleted, insulinOnBoard, error) in
694+
getLoopStatus { (predictedGlucose, retrospectivePredictedGlucose, recommendedTempBasal, lastTempBasal, lastLoopCompleted, insulinOnBoard, carbsOnBoard, error) in
677695
let report = [
678696
"## LoopDataManager",
679697
"predictedGlucose: \(predictedGlucose ?? [])",
@@ -682,6 +700,7 @@ extension LoopDataManager {
682700
"lastTempBasal: \(lastTempBasal)",
683701
"lastLoopCompleted: \(lastLoopCompleted ?? .distantPast)",
684702
"insulinOnBoard: \(insulinOnBoard)",
703+
"carbsOnBoard: \(carbsOnBoard)",
685704
"error: \(error)"
686705
]
687706
completionHandler(report.joined(separator: "\n"))

Loop/Managers/NightscoutDataManager.swift

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import Foundation
1010
import NightscoutUploadKit
11+
import CarbKit
1112
import HealthKit
1213
import InsulinKit
1314
import LoopKit
@@ -34,20 +35,20 @@ class NightscoutDataManager {
3435
return
3536
}
3637

37-
deviceDataManager.loopManager.getLoopStatus { (predictedGlucose, _, recommendedTempBasal, lastTempBasal, _, insulinOnBoard, loopError) in
38+
deviceDataManager.loopManager.getLoopStatus { (predictedGlucose, _, recommendedTempBasal, lastTempBasal, _, insulinOnBoard, carbsOnBoard, loopError) in
3839

3940
self.deviceDataManager.loopManager.getRecommendedBolus { (bolusUnits, getBolusError) in
4041
if let getBolusError = getBolusError {
4142
self.deviceDataManager.logger.addError(getBolusError, fromSource: "NightscoutDataManager")
4243
}
43-
self.uploadLoopStatus(insulinOnBoard, predictedGlucose: predictedGlucose, recommendedTempBasal: recommendedTempBasal, recommendedBolus: bolusUnits, lastTempBasal: lastTempBasal, loopError: loopError ?? getBolusError)
44+
self.uploadLoopStatus(insulinOnBoard, carbsOnBoard: carbsOnBoard, predictedGlucose: predictedGlucose, recommendedTempBasal: recommendedTempBasal, recommendedBolus: bolusUnits, lastTempBasal: lastTempBasal, loopError: loopError ?? getBolusError)
4445
}
4546
}
4647
}
4748

4849
private var lastTempBasalUploaded: DoseEntry?
4950

50-
func uploadLoopStatus(_ insulinOnBoard: InsulinValue? = nil, predictedGlucose: [GlucoseValue]? = nil, recommendedTempBasal: LoopDataManager.TempBasalRecommendation? = nil, recommendedBolus: Double? = nil, lastTempBasal: DoseEntry? = nil, loopError: Error? = nil) {
51+
func uploadLoopStatus(_ insulinOnBoard: InsulinValue? = nil, carbsOnBoard: CarbValue? = nil, predictedGlucose: [GlucoseValue]? = nil, recommendedTempBasal: LoopDataManager.TempBasalRecommendation? = nil, recommendedBolus: Double? = nil, lastTempBasal: DoseEntry? = nil, loopError: Error? = nil) {
5152

5253
guard deviceDataManager.remoteDataManager.nightscoutUploader != nil else {
5354
return
@@ -62,6 +63,14 @@ class NightscoutDataManager {
6263
} else {
6364
iob = nil
6465
}
66+
67+
let cob: COBStatus?
68+
69+
if let carbsOnBoard = carbsOnBoard {
70+
cob = COBStatus(cob: carbsOnBoard.quantity.doubleValue(for: HKUnit.gram()), timestamp: carbsOnBoard.startDate)
71+
} else {
72+
cob = nil
73+
}
6574

6675
let predicted: PredictedBG?
6776
if let predictedGlucose = predictedGlucose, let startDate = predictedGlucose.first?.startDate {
@@ -93,7 +102,7 @@ class NightscoutDataManager {
93102
let loopName = Bundle.main.bundleDisplayName
94103
let loopVersion = Bundle.main.shortVersionString
95104

96-
let loopStatus = LoopStatus(name: loopName, version: loopVersion, timestamp: statusTime, iob: iob, predicted: predicted, recommendedTempBasal: recommended, recommendedBolus: recommendedBolus, enacted: loopEnacted, failureReason: loopError)
105+
let loopStatus = LoopStatus(name: loopName, version: loopVersion, timestamp: statusTime, iob: iob, cob: cob, predicted: predicted, recommendedTempBasal: recommended, recommendedBolus: recommendedBolus, enacted: loopEnacted, failureReason: loopError)
97106

98107
uploadDeviceStatus(nil, loopStatus: loopStatus, includeUploaderStatus: false)
99108

Loop/Managers/WatchDataManager.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ final class WatchDataManager: NSObject, WCSessionDelegate {
105105
let reservoir = deviceDataManager.doseStore.lastReservoirValue
106106
let maxBolus = deviceDataManager.maximumBolus
107107

108-
deviceDataManager.loopManager.getLoopStatus { (predictedGlucose, _, recommendedTempBasal, lastTempBasal, lastLoopCompleted, _, error) in
108+
deviceDataManager.loopManager.getLoopStatus { (predictedGlucose, _, recommendedTempBasal, lastTempBasal, lastLoopCompleted, _, _, error) in
109109
let eventualGlucose = predictedGlucose?.last
110110

111111
self.deviceDataManager.loopManager.getRecommendedBolus { (units, error) in

Loop/View Controllers/PredictionTableViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ class PredictionTableViewController: UITableViewController, IdentifiableClass, U
151151
}
152152

153153
reloadGroup.enter()
154-
self.dataManager.loopManager.getLoopStatus { (predictedGlucose, retrospectivePredictedGlucose, _, _, _, _, error) in
154+
self.dataManager.loopManager.getLoopStatus { (predictedGlucose, retrospectivePredictedGlucose, _, _, _, _, _, error) in
155155
if error != nil {
156156
self.needsRefresh = true
157157
}

Loop/View Controllers/StatusTableViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize
170170
}
171171

172172
reloadGroup.enter()
173-
self.dataManager.loopManager.getLoopStatus { (predictedGlucose, _, recommendedTempBasal, lastTempBasal, lastLoopCompleted, _, error) -> Void in
173+
self.dataManager.loopManager.getLoopStatus { (predictedGlucose, _, recommendedTempBasal, lastTempBasal, lastLoopCompleted, _, _, error) -> Void in
174174
if error != nil {
175175
self.needsRefresh = true
176176
}

0 commit comments

Comments
 (0)