forked from LoopKit/Loop
-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathLoopSettings.swift
170 lines (136 loc) · 6.94 KB
/
LoopSettings.swift
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
//
// LoopSettings.swift
// Loop
//
// Copyright © 2017 LoopKit Authors. All rights reserved.
//
import LoopKit
import LoopAlgorithm
public extension AutomaticDosingStrategy {
var title: String {
switch self {
case .tempBasalOnly:
return LocalizedString("Temp Basal Only", comment: "Title string for temp basal only dosing strategy")
case .automaticBolus:
return LocalizedString("Automatic Bolus", comment: "Title string for automatic bolus dosing strategy")
}
}
}
public struct LoopSettings: Equatable {
public var dosingEnabled = false
public var glucoseTargetRangeSchedule: GlucoseRangeSchedule?
public var insulinSensitivitySchedule: InsulinSensitivitySchedule?
public var basalRateSchedule: BasalRateSchedule?
public var carbRatioSchedule: CarbRatioSchedule?
public var preMealTargetRange: ClosedRange<LoopQuantity>?
public var legacyWorkoutTargetRange: ClosedRange<LoopQuantity>?
public var legacyWorkoutDuration: TemporaryScheduleOverride.Duration?
public var overridePresets: [TemporaryPreset] = []
public var maximumBasalRatePerHour: Double?
public var maximumBolus: Double?
public var suspendThreshold: GlucoseThreshold? = nil
public var automaticDosingStrategy: AutomaticDosingStrategy = .tempBasalOnly
public var defaultRapidActingModel: ExponentialInsulinModelPreset?
public var glucoseUnit: LoopUnit? {
return glucoseTargetRangeSchedule?.unit
}
public init(
dosingEnabled: Bool = false,
glucoseTargetRangeSchedule: GlucoseRangeSchedule? = nil,
insulinSensitivitySchedule: InsulinSensitivitySchedule? = nil,
basalRateSchedule: BasalRateSchedule? = nil,
carbRatioSchedule: CarbRatioSchedule? = nil,
preMealTargetRange: ClosedRange<LoopQuantity>? = nil,
legacyWorkoutTargetRange: ClosedRange<LoopQuantity>? = nil,
legacyWorkoutDuration: TemporaryScheduleOverride.Duration = .indefinite,
overridePresets: [TemporaryPreset]? = nil,
maximumBasalRatePerHour: Double? = nil,
maximumBolus: Double? = nil,
suspendThreshold: GlucoseThreshold? = nil,
automaticDosingStrategy: AutomaticDosingStrategy = .tempBasalOnly,
defaultRapidActingModel: ExponentialInsulinModelPreset? = nil
) {
self.dosingEnabled = dosingEnabled
self.glucoseTargetRangeSchedule = glucoseTargetRangeSchedule
self.insulinSensitivitySchedule = insulinSensitivitySchedule
self.basalRateSchedule = basalRateSchedule
self.carbRatioSchedule = carbRatioSchedule
self.preMealTargetRange = preMealTargetRange
self.legacyWorkoutTargetRange = legacyWorkoutTargetRange
self.legacyWorkoutDuration = legacyWorkoutDuration
self.overridePresets = overridePresets ?? []
self.maximumBasalRatePerHour = maximumBasalRatePerHour
self.maximumBolus = maximumBolus
self.suspendThreshold = suspendThreshold
self.automaticDosingStrategy = automaticDosingStrategy
self.defaultRapidActingModel = defaultRapidActingModel
}
}
extension LoopSettings: RawRepresentable {
public typealias RawValue = [String: Any]
private static let version = 1
fileprivate static let codingGlucoseUnit = LoopUnit.milligramsPerDeciliter
public init?(rawValue: RawValue) {
guard
let version = rawValue["version"] as? Int,
version == LoopSettings.version
else {
return nil
}
if let dosingEnabled = rawValue["dosingEnabled"] as? Bool {
self.dosingEnabled = dosingEnabled
}
if let glucoseRangeScheduleRawValue = rawValue["glucoseTargetRangeSchedule"] as? GlucoseRangeSchedule.RawValue {
self.glucoseTargetRangeSchedule = GlucoseRangeSchedule(rawValue: glucoseRangeScheduleRawValue)
// Migrate the glucose range schedule override targets
if let overrideRangesRawValue = glucoseRangeScheduleRawValue["overrideRanges"] as? [String: DoubleRange.RawValue] {
if let preMealTargetRawValue = overrideRangesRawValue["preMeal"] {
self.preMealTargetRange = DoubleRange(rawValue: preMealTargetRawValue)?.quantityRange(for: LoopSettings.codingGlucoseUnit)
}
if let legacyWorkoutTargetRawValue = overrideRangesRawValue["workout"] {
self.legacyWorkoutTargetRange = DoubleRange(rawValue: legacyWorkoutTargetRawValue)?.quantityRange(for: LoopSettings.codingGlucoseUnit)
}
}
}
if let rawPreMealTargetRange = rawValue["preMealTargetRange"] as? DoubleRange.RawValue {
self.preMealTargetRange = DoubleRange(rawValue: rawPreMealTargetRange)?.quantityRange(for: LoopSettings.codingGlucoseUnit)
}
if let rawLegacyWorkoutTargetRange = rawValue["legacyWorkoutTargetRange"] as? DoubleRange.RawValue {
self.legacyWorkoutTargetRange = DoubleRange(rawValue: rawLegacyWorkoutTargetRange)?.quantityRange(for: LoopSettings.codingGlucoseUnit)
}
if let rawLegacyWorkoutDuration = rawValue["legacyWorkoutDuration"] as? Double {
self.legacyWorkoutDuration = .finite(rawLegacyWorkoutDuration)
}
if let rawPresets = rawValue["overridePresets"] as? [TemporaryPreset.RawValue] {
self.overridePresets = rawPresets.compactMap(TemporaryPreset.init(rawValue:))
}
self.maximumBasalRatePerHour = rawValue["maximumBasalRatePerHour"] as? Double
self.maximumBolus = rawValue["maximumBolus"] as? Double
if let rawThreshold = rawValue["minimumBGGuard"] as? GlucoseThreshold.RawValue {
self.suspendThreshold = GlucoseThreshold(rawValue: rawThreshold)
}
if let rawDosingStrategy = rawValue["dosingStrategy"] as? AutomaticDosingStrategy.RawValue,
let automaticDosingStrategy = AutomaticDosingStrategy(rawValue: rawDosingStrategy)
{
self.automaticDosingStrategy = automaticDosingStrategy
}
}
public var rawValue: RawValue {
var raw: RawValue = [
"version": LoopSettings.version,
"dosingEnabled": dosingEnabled,
"overridePresets": overridePresets.map { $0.rawValue }
]
raw["glucoseTargetRangeSchedule"] = glucoseTargetRangeSchedule?.rawValue
raw["preMealTargetRange"] = preMealTargetRange?.doubleRange(for: LoopSettings.codingGlucoseUnit).rawValue
raw["legacyWorkoutTargetRange"] = legacyWorkoutTargetRange?.doubleRange(for: LoopSettings.codingGlucoseUnit).rawValue
if case .finite(let duration) = legacyWorkoutDuration {
raw["legacyWorkoutDuration"] = duration
}
raw["maximumBasalRatePerHour"] = maximumBasalRatePerHour
raw["maximumBolus"] = maximumBolus
raw["minimumBGGuard"] = suspendThreshold?.rawValue
raw["dosingStrategy"] = automaticDosingStrategy.rawValue
return raw
}
}