Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Loop.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,11 @@
7D70765E1FE06EE3004AC8EA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D7076601FE06EE3004AC8EA /* Localizable.strings */; };
7D7076631FE06EE4004AC8EA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D7076651FE06EE4004AC8EA /* Localizable.strings */; };
7D7076681FE0702F004AC8EA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D70766A1FE0702F004AC8EA /* InfoPlist.strings */; };
7DB5706C203E4595004322F7 /* BasalProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DB5706B203E4595004322F7 /* BasalProfile.swift */; };
7DB5706D203E4636004322F7 /* BasalProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DB5706B203E4595004322F7 /* BasalProfile.swift */; };
7DB5706E203E4638004322F7 /* BasalProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DB5706B203E4595004322F7 /* BasalProfile.swift */; };
7DB5706F203E4639004322F7 /* BasalProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DB5706B203E4595004322F7 /* BasalProfile.swift */; };
7DB57070203E4639004322F7 /* BasalProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DB5706B203E4595004322F7 /* BasalProfile.swift */; };
894B91CD1FF9F45900DA65F5 /* GlucoseRangeScheduleOverrideUserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 894B91CC1FF9F45900DA65F5 /* GlucoseRangeScheduleOverrideUserInfo.swift */; };
894B91CE1FF9F45900DA65F5 /* GlucoseRangeScheduleOverrideUserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 894B91CC1FF9F45900DA65F5 /* GlucoseRangeScheduleOverrideUserInfo.swift */; };
894F71E21FFEC4D8007D365C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 894F71E11FFEC4D8007D365C /* Assets.xcassets */; };
Expand Down Expand Up @@ -622,6 +627,7 @@
7D70765F1FE06EE3004AC8EA /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
7D7076641FE06EE4004AC8EA /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
7D7076691FE0702F004AC8EA /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
7DB5706B203E4595004322F7 /* BasalProfile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasalProfile.swift; sourceTree = "<group>"; };
7DD382761F8DBFC60071272B /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/LaunchScreen.strings; sourceTree = "<group>"; };
7DD382771F8DBFC60071272B /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Main.strings; sourceTree = "<group>"; };
7DD382781F8DBFC60071272B /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/MainInterface.strings; sourceTree = "<group>"; };
Expand Down Expand Up @@ -759,6 +765,7 @@
43880F961D9D8052009061A8 /* ServiceAuthentication */,
43DE92601C555C26001FFDE1 /* AbsorptionTimeType+CarbKit.swift */,
C17824A41E1AD4D100D9D25C /* BolusRecommendation.swift */,
7DB5706B203E4595004322F7 /* BasalProfile.swift */,
4309786D1E73DAD100BEBC82 /* CGM.swift */,
540DED961E14C75F002B2491 /* EnliteSensorDisplayable.swift */,
43E397A21D56B9E40028E321 /* Glucose.swift */,
Expand Down Expand Up @@ -1596,6 +1603,7 @@
439BED2E1E760BC600B0AED5 /* EnliteCGMManager.swift in Sources */,
4341F4EB1EDB92AC001C936B /* LogglyService.swift in Sources */,
43CE7CDE1CA8B63E003CC1B0 /* Data.swift in Sources */,
7DB5706C203E4595004322F7 /* BasalProfile.swift in Sources */,
43BFF0CB1E466C0900FF19A9 /* StateColorPalette.swift in Sources */,
43F5C2DB1B92A5E1003EB13D /* SettingsTableViewController.swift in Sources */,
C11C87DD1E21E53500BB71D3 /* GlucoseThreshold.swift in Sources */,
Expand Down Expand Up @@ -1734,6 +1742,7 @@
43E2D8DB1D20C03B004DA55F /* NSTimeInterval.swift in Sources */,
43E2D8D41D20BF42004DA55F /* DoseMathTests.swift in Sources */,
C11C87DE1E21EAAD00BB71D3 /* HKUnit.swift in Sources */,
7DB5706F203E4639004322F7 /* BasalProfile.swift in Sources */,
C13BAD941E8009B000050CB5 /* NumberFormatter.swift in Sources */,
C17824A61E1AF91F00D9D25C /* BolusRecommendation.swift in Sources */,
);
Expand All @@ -1744,6 +1753,7 @@
buildActionMask = 2147483647;
files = (
43E2D9151D20C5A2004DA55F /* KeychainManagerTests.swift in Sources */,
7DB57070203E4639004322F7 /* BasalProfile.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -1752,6 +1762,7 @@
buildActionMask = 2147483647;
files = (
4FAC02541E22F6B20087A773 /* NSTimeInterval.swift in Sources */,
7DB5706D203E4636004322F7 /* BasalProfile.swift in Sources */,
4FB76FBA1E8C42CE00B39636 /* UIColor.swift in Sources */,
4F2C15831E0757E600E160D4 /* HKUnit.swift in Sources */,
43E93FB51E4675E800EAB8DB /* NumberFormatter.swift in Sources */,
Expand All @@ -1775,6 +1786,7 @@
4FF4D0F91E17268800846527 /* IdentifiableClass.swift in Sources */,
436961911F19D11E00447E89 /* ChartPointsContextFillLayer.swift in Sources */,
4FF4D0F81E1725B000846527 /* NibLoadable.swift in Sources */,
7DB5706E203E4638004322F7 /* BasalProfile.swift in Sources */,
4326BA641F3A44D9007CCAD4 /* ChartLineModel.swift in Sources */,
4F7528AA1DFE215100C322D6 /* HKUnit.swift in Sources */,
4F7528A91DFE212600C322D6 /* GlucoseTrend.swift in Sources */,
Expand Down
68 changes: 67 additions & 1 deletion Loop/Extensions/NSUserDefaults.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ import HealthKit
extension UserDefaults {

private enum Key: String {
case activeBasalProfile = "com.loudnate.Naterade.activeBasalProfile"
case basalRateSchedule = "com.loudnate.Naterade.BasalRateSchedule"
case basalRateScheduleA = "com.loudnate.Naterade.BasalRateScheduleA"
case basalRateScheduleB = "com.loudnate.Naterade.BasalRateScheduleB"
case basalRateScheduleStandard = "com.loudnate.Naterade.BasalRateScheduleStandard"
case batteryChemistry = "com.loopkit.Loop.BatteryChemistry"
case cgmSettings = "com.loopkit.Loop.cgmSettings"
case carbRatioSchedule = "com.loudnate.Naterade.CarbRatioSchedule"
Expand Down Expand Up @@ -43,6 +47,60 @@ extension UserDefaults {
set(newValue?.rawValue, forKey: Key.basalRateSchedule.rawValue)
}
}

var basalRateScheduleA: BasalRateSchedule? {
get {
if let rawValue = dictionary(forKey: Key.basalRateScheduleA.rawValue) {
return BasalRateSchedule(rawValue: rawValue)
} else {
return nil
}
}
set {
set(newValue?.rawValue, forKey: Key.basalRateScheduleA.rawValue)
}
}

var basalRateScheduleB: BasalRateSchedule? {
get {
if let rawValue = dictionary(forKey: Key.basalRateScheduleB.rawValue) {
return BasalRateSchedule(rawValue: rawValue)
} else {
return nil
}
}
set {
set(newValue?.rawValue, forKey: Key.basalRateScheduleB.rawValue)
}
}

var basalRateScheduleStandard: BasalRateSchedule? {
get {
if let rawValue = dictionary(forKey: Key.basalRateScheduleStandard.rawValue) {
return BasalRateSchedule(rawValue: rawValue)
} else {
return nil
}
}
set {
set(newValue?.rawValue, forKey: Key.basalRateScheduleStandard.rawValue)
}
}

var activeBasalProfile: BasalProfile? {
get {
let rawValue = Key.activeBasalProfile.rawValue
return BasalProfile(rawValue: integer(forKey: rawValue))

}
set {
if let activeBasalProfile = newValue {
set(activeBasalProfile.rawValue, forKey: Key.activeBasalProfile.rawValue)
} else {
removeObject(forKey: Key.activeBasalProfile.rawValue)
}
}
}

var carbRatioSchedule: CarbRatioSchedule? {
get {
Expand Down Expand Up @@ -110,11 +168,15 @@ extension UserDefaults {
// Migrate the version 0 case
defer {
removeObject(forKey: "com.loudnate.Naterade.DosingEnabled")
removeObject(forKey: "com.loudnate.Naterade.activeBasalProfile")
removeObject(forKey: "com.loudnate.Naterade.GlucoseTargetRangeSchedule")
removeObject(forKey: "com.loudnate.Naterade.MaximumBasalRatePerHour")
removeObject(forKey: "com.loudnate.Naterade.MaximumBolus")
removeObject(forKey: "com.loopkit.Loop.MinimumBGGuard")
removeObject(forKey: "com.loudnate.Loop.RetrospectiveCorrectionEnabled")
removeObject(forKey: "com.loudnate.Naterade.BasalRateScheduleA")
removeObject(forKey: "com.loudnate.Naterade.BasalRateScheduleB")
removeObject(forKey: "com.loudnate.Naterade.BasalRateScheduleStandard")
}

let glucoseTargetRangeSchedule: GlucoseRangeSchedule?
Expand Down Expand Up @@ -147,7 +209,11 @@ extension UserDefaults {
maximumBasalRatePerHour: maximumBasalRatePerHour,
maximumBolus: maximumBolus,
suspendThreshold: suspendThreshold,
retrospectiveCorrectionEnabled: bool(forKey: "com.loudnate.Loop.RetrospectiveCorrectionEnabled")
retrospectiveCorrectionEnabled: bool(forKey: "com.loudnate.Loop.RetrospectiveCorrectionEnabled"),
basalProfileStandard: basalRateScheduleStandard,
basalProfileA: basalRateScheduleA,
basalProfileB: basalRateScheduleB,
activeBasalProfile: activeBasalProfile
)
self.loopSettings = settings

Expand Down
16 changes: 16 additions & 0 deletions Loop/Managers/LoopDataManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ final class LoopDataManager {
lastLoopCompleted: Date?,
lastTempBasal: DoseEntry?,
basalRateSchedule: BasalRateSchedule? = UserDefaults.standard.basalRateSchedule,
basalRateScheduleStandard: BasalRateSchedule? = UserDefaults.standard.basalRateScheduleStandard,
basalRateScheduleA: BasalRateSchedule? = UserDefaults.standard.basalRateScheduleA,
basalRateScheduleB: BasalRateSchedule? = UserDefaults.standard.basalRateScheduleB,
activeBasalprofile: BasalProfile? = UserDefaults.standard.activeBasalProfile,
carbRatioSchedule: CarbRatioSchedule? = UserDefaults.standard.carbRatioSchedule,
insulinModelSettings: InsulinModelSettings? = UserDefaults.standard.insulinModelSettings,
insulinCounteractionEffects: [GlucoseEffectVelocity]? = UserDefaults.standard.insulinCounteractionEffects,
Expand Down Expand Up @@ -427,6 +431,18 @@ final class LoopDataManager {
try self.update()

if self.settings.dosingEnabled {

// print(self.settings.glucoseTargetRangeSchedule)
// print(self.settings.glucoseTargetRangeSchedule?.rawValue)
// self.settings.glucoseTargetRangeSchedule = GlucoseRangeSchedule(unit: <#T##HKUnit#>, dailyItems: <#T##[RepeatingScheduleValue<DoubleRange>]#>, overrideRanges: <#T##[GlucoseRangeSchedule.Override.Context : DoubleRange]#>)
// self.settings.glucoseTargetRangeSchedule = GlucoseRangeSchedule(rawValue:["items": [["startTime": 0.0, "value": [150.0, 151.0]]], "timeZone": -18000, "overrideRanges": [:], "unit": "mg/dL"])
// self.settings.glucoseTargetRangeSchedule? = GlucoseRangeSchedule(rawValue: <#T##GlucoseRangeSchedule.RawValue#>)
// self.settings.glucoseTargetRangeSchedule = GlucoseRangeSchedule(rawValue: ["200":"201"])
// self.settings.glucoseTargetRangeSchedule = GlucoseRangeSchedule(unit: self.unit, dailyItems: self.scheduleItems, timeZone: self.timeZone, overrideRanges: self.overrideRanges, override: self.settings.glucoseTargetRangeSchedule?.override)
// self.settings.glucoseTargetRangeSchedule = GlucoseRangeSchedule(unit: self.unit, dailyItems: self.scheduleItems, timeZone: self.timeZone, overrideRanges: self.overrideRanges, override: self.settings.glucoseTargetRangeSchedule?.override)
// AnalyticsManager.shared.didChangeGlucoseTargetRangeSchedule()
// self.settings.glucoseTargetRangeSchedule?.setOverride(.preMeal, until: Date(timeIntervalSinceNow: .hours(6)))

self.setRecommendedTempBasal { (error) -> Void in
self.lastLoopError = error

Expand Down
31 changes: 31 additions & 0 deletions Loop/Models/BasalProfile.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// BasalProfile.swift
// Loop
//
// Created by Kenneth Stack on 2/14/18.
// Copyright © 2018 LoopKit Authors. All rights reserved.
//
import Foundation
import UIKit

enum BasalProfile: Int, CustomStringConvertible {
case notSet = 0
case standard
case patternA
case patternB

var description: String {
switch self {
case .notSet:
return NSLocalizedString("Not Set", comment: "Describing the not set condition")
case .standard:
return NSLocalizedString("Standard", comment: "Describing the standard basal pattern")
case .patternA:
return NSLocalizedString("Pattern A", comment: "Describing basal pattern A")
case .patternB:
return NSLocalizedString("Pattern B", comment: "Describing basal pattern B")
// case .notSet:
// return NSLocalizedString("Pattern Not Set", comment: "Describing basal pattern not set")
}
}
}
24 changes: 24 additions & 0 deletions Loop/Models/LoopSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ struct LoopSettings {
var suspendThreshold: GlucoseThreshold? = nil

var retrospectiveCorrectionEnabled = true
var basalProfileStandard: BasalRateSchedule?
var basalProfileA: BasalRateSchedule?
var basalProfileB: BasalRateSchedule?
var activeBasalProfile: BasalProfile?
}


Expand Down Expand Up @@ -55,6 +59,22 @@ extension LoopSettings: RawRepresentable {
if let rawValue = rawValue["glucoseTargetRangeSchedule"] as? GlucoseRangeSchedule.RawValue {
self.glucoseTargetRangeSchedule = GlucoseRangeSchedule(rawValue: rawValue)
}

if let rawValue = rawValue["basalProfileB"] as? BasalRateSchedule.RawValue {
self.basalProfileB = BasalRateSchedule(rawValue: rawValue)
}

if let rawValue = rawValue["basalProfileA"] as? BasalRateSchedule.RawValue {
self.basalProfileA = BasalRateSchedule(rawValue: rawValue)
}

if let rawValue = rawValue["basalProfileStandard"] as? BasalRateSchedule.RawValue {
self.basalProfileStandard = BasalRateSchedule(rawValue: rawValue)
}

if let rawValue = rawValue["activeBasalProfile"] as? BasalProfile.RawValue {
self.activeBasalProfile = BasalProfile(rawValue: rawValue)
}

self.maximumBasalRatePerHour = rawValue["maximumBasalRatePerHour"] as? Double

Expand All @@ -80,6 +100,10 @@ extension LoopSettings: RawRepresentable {
raw["maximumBasalRatePerHour"] = maximumBasalRatePerHour
raw["maximumBolus"] = maximumBolus
raw["minimumBGGuard"] = suspendThreshold?.rawValue
raw["basalProfileB"] = basalProfileB?.rawValue
raw["basalProfileA"] = basalProfileA?.rawValue
raw["basalProfileStandard"] = basalProfileStandard?.rawValue
raw["activeBasalProfile"] = activeBasalProfile?.rawValue

return raw
}
Expand Down
13 changes: 13 additions & 0 deletions Loop/View Controllers/RadioSelectionTableViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,19 @@ extension RadioSelectionTableViewController {

return vc
}

static func activeBasalProfileSource(_ value: BasalProfile) -> T {
//row 0 is the notSet row
let vc = T()
// - 1 to account for missing row
if value.rawValue != 0 {
vc.selectedIndex = value.rawValue - 1
}
vc.options = (1..<4).flatMap({ BasalProfile(rawValue: $0) }).map { String(describing: $0) }
vc.contextHelp = NSLocalizedString("Choose Your Active Profile Amongst Standard, A and B", comment: "Instructions on selecting an active basal profile data source")

return vc
}

static func batteryChemistryType(_ value: BatteryChemistryType) -> T {
let vc = T()
Expand Down
Loading