-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expand file tree
/
Copy pathWatchContext.swift
More file actions
175 lines (143 loc) · 5.69 KB
/
WatchContext.swift
File metadata and controls
175 lines (143 loc) · 5.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
//
// WatchContext.swift
// Naterade
//
// Created by Nathan Racklyeft on 11/25/15.
// Copyright © 2015 Nathan Racklyeft. All rights reserved.
//
import Foundation
import HealthKit
import LoopKit
import LoopAlgorithm
final class WatchContext: RawRepresentable {
typealias RawValue = [String: Any]
private let version = 5
var creationDate = Date()
var displayGlucoseUnit: HKUnit?
var glucose: HKQuantity?
var glucoseCondition: GlucoseCondition?
var glucoseTrend: GlucoseTrend?
var glucoseTrendRate: HKQuantity?
var glucoseDate: Date?
var glucoseIsDisplayOnly: Bool?
var glucoseWasUserEntered: Bool?
var glucoseSyncIdentifier: String?
var predictedGlucose: WatchPredictedGlucose?
var eventualGlucose: HKQuantity? {
return predictedGlucose?.values.last?.quantity
}
var loopLastRunDate: Date?
var lastNetTempBasalDose: Double?
var lastNetTempBasalDate: Date?
var recommendedBolusDose: Double?
var potentialCarbEntry: NewCarbEntry?
var cob: Double?
var iob: Double?
var reservoir: Double?
var reservoirPercentage: Double?
var batteryPercentage: Double?
var cgmManagerState: CGMManager.RawStateValue?
var isClosedLoop: Bool?
init() {}
required init?(rawValue: RawValue) {
guard rawValue["v"] as? Int == version, let creationDate = rawValue["cd"] as? Date else {
return nil
}
self.creationDate = creationDate
isClosedLoop = rawValue["cl"] as? Bool
if let unitString = rawValue["gu"] as? String {
displayGlucoseUnit = HKUnit(from: unitString)
}
let unit = displayGlucoseUnit ?? .milligramsPerDeciliter
if let glucoseValue = rawValue["gv"] as? Double {
glucose = HKQuantity(unit: unit, doubleValue: glucoseValue)
}
if let rawGlucoseCondition = rawValue["gc"] as? GlucoseCondition.RawValue {
glucoseCondition = GlucoseCondition(rawValue: rawGlucoseCondition)
}
if let rawGlucoseTrend = rawValue["gt"] as? GlucoseTrend.RawValue {
glucoseTrend = GlucoseTrend(rawValue: rawGlucoseTrend)
}
if let glucoseTrendRateValue = rawValue["gtrv"] as? Double {
glucoseTrendRate = HKQuantity(unit: .milligramsPerDeciliterPerMinute, doubleValue: glucoseTrendRateValue)
}
glucoseDate = rawValue["gd"] as? Date
glucoseIsDisplayOnly = rawValue["gdo"] as? Bool
glucoseWasUserEntered = rawValue["gue"] as? Bool
glucoseSyncIdentifier = rawValue["gs"] as? String
iob = rawValue["iob"] as? Double
reservoir = rawValue["r"] as? Double
reservoirPercentage = rawValue["rp"] as? Double
batteryPercentage = rawValue["bp"] as? Double
loopLastRunDate = rawValue["ld"] as? Date
lastNetTempBasalDose = rawValue["ba"] as? Double
lastNetTempBasalDate = rawValue["bad"] as? Date
recommendedBolusDose = rawValue["rbo"] as? Double
if let rawPotentialCarbEntry = rawValue["pce"] as? NewCarbEntry.RawValue {
potentialCarbEntry = NewCarbEntry(rawValue: rawPotentialCarbEntry)
}
cob = rawValue["cob"] as? Double
cgmManagerState = rawValue["cgmManagerState"] as? CGMManager.RawStateValue
if let rawValue = rawValue["pg"] as? WatchPredictedGlucose.RawValue {
predictedGlucose = WatchPredictedGlucose(rawValue: rawValue)
}
}
var rawValue: RawValue {
var raw: [String: Any] = [
"v": version,
"cd": creationDate
]
raw["ba"] = lastNetTempBasalDose
raw["bad"] = lastNetTempBasalDate
raw["bp"] = batteryPercentage
raw["cl"] = isClosedLoop
raw["cgmManagerState"] = cgmManagerState
raw["cob"] = cob
let unit = displayGlucoseUnit ?? .milligramsPerDeciliter
raw["gu"] = displayGlucoseUnit?.unitString
raw["gv"] = glucose?.doubleValue(for: unit)
raw["gc"] = glucoseCondition?.rawValue
raw["gt"] = glucoseTrend?.rawValue
if let glucoseTrendRate = glucoseTrendRate {
let unitPerMinute = unit.unitDivided(by: .minute())
raw["gtru"] = unitPerMinute.unitString
raw["gtrv"] = glucoseTrendRate.doubleValue(for: unitPerMinute)
}
raw["gd"] = glucoseDate
raw["gdo"] = glucoseIsDisplayOnly
raw["gue"] = glucoseWasUserEntered
raw["gs"] = glucoseSyncIdentifier
raw["iob"] = iob
raw["ld"] = loopLastRunDate
raw["r"] = reservoir
raw["rbo"] = recommendedBolusDose
raw["pce"] = potentialCarbEntry?.rawValue
raw["rp"] = reservoirPercentage
raw["pg"] = predictedGlucose?.rawValue
return raw
}
}
extension WatchContext {
func shouldReplace(_ other: WatchContext) -> Bool {
if let date = self.glucoseDate, let otherDate = other.glucoseDate {
return date >= otherDate
} else {
return true
}
}
}
extension WatchContext {
var newGlucoseSample: NewGlucoseSample? {
if let quantity = glucose, let date = glucoseDate, let syncIdentifier = glucoseSyncIdentifier {
return NewGlucoseSample(date: date,
quantity: quantity,
condition: glucoseCondition,
trend: glucoseTrend,
trendRate: glucoseTrendRate,
isDisplayOnly: glucoseIsDisplayOnly ?? false,
wasUserEntered: glucoseWasUserEntered ?? false,
syncIdentifier: syncIdentifier, syncVersion: 0)
}
return nil
}
}