Skip to content

Commit 7062852

Browse files
authored
Merge branch 'katie' into pump-manager
2 parents 6b6e5a7 + 0fa6152 commit 7062852

34 files changed

+1709
-84
lines changed

Common/Extensions/NSUserDefaults.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ extension UserDefaults {
112112
maximumBasalRatePerHour: maximumBasalRatePerHour,
113113
maximumBolus: maximumBolus,
114114
suspendThreshold: suspendThreshold,
115-
retrospectiveCorrectionEnabled: bool(forKey: "com.loudnate.Loop.RetrospectiveCorrectionEnabled")
115+
retrospectiveCorrectionEnabled: bool(forKey: "com.loudnate.Loop.RetrospectiveCorrectionEnabled"),
116+
integralRetrospectiveCorrectionEnabled: bool(forKey: "com.loopkit.Loop.IntegralRetrospectiveCorrectionEnabled")
116117
)
117118
self.loopSettings = settings
118119

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//
2+
// GlucoseBackfillRequestUserInfo.swift
3+
// Loop
4+
//
5+
// Created by Bharat Mediratta on 6/21/18.
6+
// Copyright © 2018 LoopKit Authors. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
struct GlucoseBackfillRequestUserInfo {
12+
let version = 1
13+
let startDate: Date
14+
}
15+
16+
extension GlucoseBackfillRequestUserInfo: RawRepresentable {
17+
typealias RawValue = [String: Any]
18+
19+
static let name = "GlucoseBackfillRequestUserInfo"
20+
21+
init?(rawValue: RawValue) {
22+
guard
23+
rawValue["v"] as? Int == version,
24+
rawValue["name"] as? String == GlucoseBackfillRequestUserInfo.name,
25+
let startDate = rawValue["sd"] as? Date
26+
else {
27+
return nil
28+
}
29+
30+
self.startDate = startDate
31+
}
32+
33+
var rawValue: RawValue {
34+
return [
35+
"v": version,
36+
"name": GlucoseBackfillRequestUserInfo.name,
37+
"sd": startDate
38+
]
39+
}
40+
}

Common/Models/GlucoseRangeScheduleOverrideUserInfo.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ struct GlucoseRangeScheduleOverrideUserInfo {
1313
enum Context: Int {
1414
case workout
1515
case preMeal
16+
case remoteTempTarget
1617

1718
static var allContexts: [Context] {
18-
return [.workout, .preMeal]
19+
return [.workout, .preMeal, .remoteTempTarget]
1920
}
2021
}
2122

Common/Models/Insulin/ExponentialInsulinModelPreset.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,19 @@ extension ExponentialInsulinModelPreset {
3939
}
4040
}
4141

42+
var initialDelay: TimeInterval {
43+
switch self {
44+
case .humalogNovologAdult:
45+
return .minutes(20)
46+
case .humalogNovologChild:
47+
return .minutes(20)
48+
case .fiasp:
49+
return .minutes(10)
50+
}
51+
}
52+
4253
var model: InsulinModel {
43-
return ExponentialInsulinModel(actionDuration: actionDuration, peakActivityTime: peakActivity)
54+
return ExponentialInsulinModel(actionDuration: actionDuration, peakActivityTime: peakActivity, initialDelay: initialDelay)
4455
}
4556
}
4657

Common/Models/LoopSettings.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ struct LoopSettings {
2323

2424
var retrospectiveCorrectionEnabled = true
2525

26+
var integralRetrospectiveCorrectionEnabled = true
27+
2628
let retrospectiveCorrectionInterval = TimeInterval(minutes: 30)
2729

2830
/// The amount of time since a given date that data should be considered valid
@@ -67,13 +69,18 @@ extension LoopSettings: RawRepresentable {
6769
if let retrospectiveCorrectionEnabled = rawValue["retrospectiveCorrectionEnabled"] as? Bool {
6870
self.retrospectiveCorrectionEnabled = retrospectiveCorrectionEnabled
6971
}
72+
73+
if let integralRetrospectiveCorrectionEnabled = rawValue["integralRetrospectiveCorrectionEnabled"] as? Bool {
74+
self.integralRetrospectiveCorrectionEnabled = integralRetrospectiveCorrectionEnabled
75+
}
7076
}
7177

7278
var rawValue: RawValue {
7379
var raw: RawValue = [
7480
"version": LoopSettings.version,
7581
"dosingEnabled": dosingEnabled,
76-
"retrospectiveCorrectionEnabled": retrospectiveCorrectionEnabled
82+
"retrospectiveCorrectionEnabled": retrospectiveCorrectionEnabled,
83+
"integralRetrospectiveCorrectionEnabled": integralRetrospectiveCorrectionEnabled
7784
]
7885

7986
raw["glucoseTargetRangeSchedule"] = glucoseTargetRangeSchedule?.rawValue

Common/Models/WatchContext.swift

Lines changed: 147 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,132 @@
99
import Foundation
1010
import HealthKit
1111

12+
struct WatchDatedRangeContext {
13+
public let startDate: Date
14+
public let endDate: Date
15+
public let minValue: Double
16+
public let maxValue: Double
17+
18+
public init(startDate: Date, endDate: Date, minValue: Double, maxValue: Double) {
19+
self.startDate = startDate
20+
self.endDate = endDate
21+
self.minValue = minValue
22+
self.maxValue = maxValue
23+
}
24+
}
25+
26+
struct WatchGlucoseContext {
27+
let value: Double
28+
let unit: HKUnit
29+
let startDate: Date
30+
31+
var quantity: HKQuantity {
32+
return HKQuantity(unit: unit, doubleValue: value)
33+
}
34+
}
35+
36+
struct WatchPredictedGlucoseContext {
37+
let values: [Double]
38+
let unit: HKUnit
39+
let startDate: Date
40+
let interval: TimeInterval
41+
42+
var samples: [WatchGlucoseContext] {
43+
return values.enumerated().map { (i, v) in
44+
WatchGlucoseContext(value: v, unit: unit, startDate: startDate.addingTimeInterval(Double(i) * interval))
45+
}
46+
}
47+
}
48+
49+
extension WatchDatedRangeContext: RawRepresentable {
50+
typealias RawValue = [String: Any]
51+
52+
var rawValue: RawValue {
53+
return [
54+
"sd": startDate,
55+
"ed": endDate,
56+
"mi": minValue,
57+
"ma": maxValue
58+
]
59+
}
60+
61+
init?(rawValue: RawValue) {
62+
guard
63+
let startDate = rawValue["sd"] as? Date,
64+
let endDate = rawValue["ed"] as? Date,
65+
let minValue = rawValue["mi"] as? Double,
66+
let maxValue = rawValue["ma"] as? Double
67+
else {
68+
return nil
69+
}
70+
71+
self.startDate = startDate
72+
self.endDate = endDate
73+
self.minValue = minValue
74+
self.maxValue = maxValue
75+
}
76+
}
77+
78+
extension WatchGlucoseContext: RawRepresentable {
79+
typealias RawValue = [String: Any]
80+
81+
var rawValue: RawValue {
82+
return [
83+
"v": value,
84+
"u": unit.unitString,
85+
"sd": startDate
86+
]
87+
}
88+
89+
init?(rawValue: RawValue) {
90+
guard
91+
let value = rawValue["v"] as? Double,
92+
let unitString = rawValue["u"] as? String,
93+
let startDate = rawValue["sd"] as? Date
94+
else {
95+
return nil
96+
}
97+
98+
self.value = value
99+
self.unit = HKUnit(from: unitString)
100+
self.startDate = startDate
101+
}
102+
}
103+
104+
extension WatchPredictedGlucoseContext: RawRepresentable {
105+
typealias RawValue = [String: Any]
106+
107+
var rawValue: RawValue {
108+
return [
109+
"v": values,
110+
"u": unit.unitString,
111+
"sd": startDate,
112+
"i": interval
113+
]
114+
}
115+
116+
init?(rawValue: RawValue) {
117+
guard
118+
let values = rawValue["v"] as? [Double],
119+
let unitString = rawValue["u"] as? String,
120+
let startDate = rawValue["sd"] as? Date,
121+
let interval = rawValue["i"] as? TimeInterval
122+
else {
123+
return nil
124+
}
125+
126+
self.values = values
127+
self.unit = HKUnit(from: unitString)
128+
self.startDate = startDate
129+
self.interval = interval
130+
}
131+
}
132+
133+
12134
final class WatchContext: NSObject, RawRepresentable {
13135
typealias RawValue = [String: Any]
14136

15-
private let version = 3
137+
private let version = 4
16138

17139
var preferredGlucoseUnit: HKUnit?
18140
var maxBolus: Double?
@@ -22,6 +144,8 @@ final class WatchContext: NSObject, RawRepresentable {
22144
var eventualGlucose: HKQuantity?
23145
var glucoseDate: Date?
24146

147+
var targetRanges: [WatchDatedRangeContext]?
148+
var temporaryOverride: WatchDatedRangeContext?
25149
var glucoseRangeScheduleOverride: GlucoseRangeScheduleOverrideUserInfo?
26150
var configuredOverrideContexts: [GlucoseRangeScheduleOverrideUserInfo.Context] = []
27151

@@ -41,6 +165,7 @@ final class WatchContext: NSObject, RawRepresentable {
41165
var reservoir: Double?
42166
var reservoirPercentage: Double?
43167
var batteryPercentage: Double?
168+
var predictedGlucose: WatchPredictedGlucoseContext?
44169

45170
var cgm: CGM?
46171

@@ -56,16 +181,15 @@ final class WatchContext: NSObject, RawRepresentable {
56181
}
57182

58183
if let unitString = rawValue["gu"] as? String {
59-
let unit = HKUnit(from: unitString)
60-
preferredGlucoseUnit = unit
184+
preferredGlucoseUnit = HKUnit(from: unitString)
61185
}
62-
186+
let unit = preferredGlucoseUnit ?? .milligramsPerDeciliter
63187
if let glucoseValue = rawValue["gv"] as? Double {
64-
glucose = HKQuantity(unit: preferredGlucoseUnit ?? .milligramsPerDeciliter, doubleValue: glucoseValue)
188+
glucose = HKQuantity(unit: unit, doubleValue: glucoseValue)
65189
}
66190

67191
if let glucoseValue = rawValue["egv"] as? Double {
68-
eventualGlucose = HKQuantity(unit: preferredGlucoseUnit ?? .milligramsPerDeciliter, doubleValue: glucoseValue)
192+
eventualGlucose = HKQuantity(unit: unit, doubleValue: glucoseValue)
69193
}
70194

71195
glucoseTrendRawValue = rawValue["gt"] as? Int
@@ -93,6 +217,18 @@ final class WatchContext: NSObject, RawRepresentable {
93217
COB = rawValue["cob"] as? Double
94218
maxBolus = rawValue["mb"] as? Double
95219

220+
if let rawValue = rawValue["pg"] as? WatchPredictedGlucoseContext.RawValue {
221+
predictedGlucose = WatchPredictedGlucoseContext(rawValue: rawValue)
222+
}
223+
224+
if let rawValue = rawValue["tr"] as? [WatchDatedRangeContext.RawValue] {
225+
targetRanges = rawValue.compactMap({return WatchDatedRangeContext(rawValue: $0)})
226+
}
227+
228+
if let rawValue = rawValue["to"] as? WatchDatedRangeContext.RawValue {
229+
temporaryOverride = WatchDatedRangeContext(rawValue: rawValue)
230+
}
231+
96232
if let cgmRawValue = rawValue["cgm"] as? CGM.RawValue {
97233
cgm = CGM(rawValue: cgmRawValue)
98234
}
@@ -127,6 +263,11 @@ final class WatchContext: NSObject, RawRepresentable {
127263
raw["rbo"] = recommendedBolusDose
128264
raw["rp"] = reservoirPercentage
129265

266+
raw["pg"] = predictedGlucose?.rawValue
267+
268+
raw["tr"] = targetRanges?.map { $0.rawValue }
269+
raw["to"] = temporaryOverride?.rawValue
270+
130271
return raw
131272
}
132273
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//
2+
// WatchHistoricalGlucose.swift
3+
// Loop
4+
//
5+
// Created by Bharat Mediratta on 6/22/18.
6+
// Copyright © 2018 LoopKit Authors. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import HealthKit
11+
12+
struct WatchHistoricalGlucoseContext {
13+
let dates: [Date]
14+
let values: [Double]
15+
let unit: HKUnit
16+
17+
var samples: [WatchGlucoseContext] {
18+
return zip(dates, values).map {
19+
WatchGlucoseContext(value: $0.1, unit: unit, startDate: $0.0)
20+
}
21+
}
22+
}
23+
24+
extension WatchHistoricalGlucoseContext: RawRepresentable {
25+
typealias RawValue = [String: Any]
26+
27+
var rawValue: RawValue {
28+
return [
29+
"d": dates,
30+
"v": values,
31+
"u": unit.unitString,
32+
]
33+
}
34+
35+
init?(rawValue: RawValue) {
36+
guard
37+
let dates = rawValue["d"] as? [Date],
38+
let values = rawValue["v"] as? [Double],
39+
let unitString = rawValue["u"] as? String
40+
else {
41+
return nil
42+
}
43+
44+
self.dates = dates
45+
self.values = values
46+
self.unit = HKUnit(from: unitString)
47+
}
48+
}

Loop Status Extension/Base.lproj/MainInterface.storyboard

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="64E-I5-5c4">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="64E-I5-5c4">
33
<device id="retina5_5" orientation="portrait">
44
<adaptation id="fullscreen"/>
55
</device>
66
<dependencies>
77
<deployment identifier="iOS"/>
8-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
8+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
99
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
1010
</dependencies>
1111
<scenes>

Loop Status Extension/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<key>CFBundlePackageType</key>
2020
<string>XPC!</string>
2121
<key>CFBundleShortVersionString</key>
22-
<string>1.5.7dev</string>
22+
<string>1.5.7dev-delta</string>
2323
<key>CFBundleVersion</key>
2424
<string>$(CURRENT_PROJECT_VERSION)</string>
2525
<key>AppGroupIdentifier</key>

0 commit comments

Comments
 (0)