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
2 changes: 1 addition & 1 deletion Cartfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
github "loudnate/LoopKit" ~> 0.4.0
github "loudnate/xDripG5" ~> 0.5.0
github "loudnate/xDripG5" ~> 0.6.0
github "loudnate/SwiftCharts" "loudnate/naterade"
github "mddub/dexcom-share-client-swift" ~> 0.1
github "mddub/G4ShareSpy" ~> 0.2.1
Expand Down
2 changes: 1 addition & 1 deletion Cartfile.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ github "mddub/G4ShareSpy" "v0.2.1"
github "loudnate/LoopKit" "v0.4.0"
github "loudnate/SwiftCharts" "8671287afb29640f9cffced6521b1098b7aac085"
github "mddub/dexcom-share-client-swift" "v0.1.3"
github "loudnate/xDripG5" "0.5.0"
github "loudnate/xDripG5" "v0.6.0"
github "ps2/rileylink_ios" "v0.8.0"
5 changes: 5 additions & 0 deletions Carthage/Build/iOS/xDripG5.framework/Headers/xDripG5-Swift.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 2 additions & 9 deletions Carthage/Build/iOS/xDripG5.framework/Headers/xDripG5.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified Carthage/Build/iOS/xDripG5.framework/Info.plist
Binary file not shown.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified Carthage/Build/iOS/xDripG5.framework/xDripG5
Binary file not shown.
12 changes: 4 additions & 8 deletions Loop.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@
4346D1E71C77F5FE00ABAFE3 /* ChartTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4346D1E61C77F5FE00ABAFE3 /* ChartTableViewCell.swift */; };
4346D1F01C781BEA00ABAFE3 /* SwiftCharts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4346D1EF1C781BEA00ABAFE3 /* SwiftCharts.framework */; };
4346D1F61C78501000ABAFE3 /* ChartPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4346D1F51C78501000ABAFE3 /* ChartPoint.swift */; };
434F24C91CFCA8940004498F /* TransmitterGlucose.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434F24C81CFCA8940004498F /* TransmitterGlucose.swift */; };
434F24CB1CFCB7AB0004498F /* GlucoseRxMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434F24CA1CFCB7AB0004498F /* GlucoseRxMessage.swift */; };
434F54571D287FDB002A9274 /* NibLoadable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434F54561D287FDB002A9274 /* NibLoadable.swift */; };
434F54591D28805E002A9274 /* ButtonTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 434F54581D28805E002A9274 /* ButtonTableViewCell.xib */; };
434F545B1D2880D4002A9274 /* AuthenticationTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 434F545A1D2880D4002A9274 /* AuthenticationTableViewCell.xib */; };
Expand Down Expand Up @@ -124,6 +122,7 @@
43E2D9191D222759004DA55F /* LoopKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43F78D4B1C914197002152D1 /* LoopKit.framework */; };
43E3449F1B9D68E900C85C07 /* StatusTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43E3449E1B9D68E900C85C07 /* StatusTableViewController.swift */; };
43E344A41B9E1B1C00C85C07 /* NSUserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43E344A31B9E1B1C00C85C07 /* NSUserDefaults.swift */; };
43E397A31D56B9E40028E321 /* Glucose.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43E397A21D56B9E40028E321 /* Glucose.swift */; };
43EA285F1D50ED3D001BC233 /* GlucoseTrend.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EA285E1D50ED3D001BC233 /* GlucoseTrend.swift */; };
43EA28601D50ED4D001BC233 /* GlucoseTrend.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EA285E1D50ED3D001BC233 /* GlucoseTrend.swift */; };
43EA28621D517E42001BC233 /* SensorDisplayable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EA28611D517E42001BC233 /* SensorDisplayable.swift */; };
Expand Down Expand Up @@ -254,8 +253,6 @@
4346D1EF1C781BEA00ABAFE3 /* SwiftCharts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftCharts.framework; path = Carthage/Build/iOS/SwiftCharts.framework; sourceTree = "<group>"; };
4346D1F51C78501000ABAFE3 /* ChartPoint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChartPoint.swift; sourceTree = "<group>"; };
434AB0B11CBB4C3300422F4A /* RileyLinkBLEKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RileyLinkBLEKit.framework; path = Carthage/Build/iOS/RileyLinkBLEKit.framework; sourceTree = "<group>"; };
434F24C81CFCA8940004498F /* TransmitterGlucose.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransmitterGlucose.swift; sourceTree = "<group>"; };
434F24CA1CFCB7AB0004498F /* GlucoseRxMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlucoseRxMessage.swift; sourceTree = "<group>"; };
434F54561D287FDB002A9274 /* NibLoadable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NibLoadable.swift; sourceTree = "<group>"; };
434F54581D28805E002A9274 /* ButtonTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ButtonTableViewCell.xib; sourceTree = "<group>"; };
434F545A1D2880D4002A9274 /* AuthenticationTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AuthenticationTableViewCell.xib; sourceTree = "<group>"; };
Expand Down Expand Up @@ -342,6 +339,7 @@
43E2D90F1D20C581004DA55F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
43E3449E1B9D68E900C85C07 /* StatusTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = StatusTableViewController.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
43E344A31B9E1B1C00C85C07 /* NSUserDefaults.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSUserDefaults.swift; sourceTree = "<group>"; };
43E397A21D56B9E40028E321 /* Glucose.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Glucose.swift; sourceTree = "<group>"; };
43EA285E1D50ED3D001BC233 /* GlucoseTrend.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlucoseTrend.swift; sourceTree = "<group>"; };
43EA28611D517E42001BC233 /* SensorDisplayable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SensorDisplayable.swift; sourceTree = "<group>"; };
43EB40851C82646A00472A8C /* StatusChartManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusChartManager.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -455,8 +453,8 @@
438849EB1D29EC34003B3F23 /* AmplitudeService.swift */,
4331E0791C85650D00FBE832 /* ChartAxisValueDoubleLog.swift */,
43F41C321D3A17AA00C11ED6 /* ChartAxisValueDoubleUnit.swift */,
43E397A21D56B9E40028E321 /* Glucose.swift */,
4D5B7A4A1D457CCA00796CA9 /* GlucoseG4.swift */,
434F24CA1CFCB7AB0004498F /* GlucoseRxMessage.swift */,
436FACED1D0BA636004E2427 /* InsulinDataSource.swift */,
436A0DA41D236A2A00104B24 /* LoopError.swift */,
438849ED1D2A1EBB003B3F23 /* MLabService.swift */,
Expand All @@ -467,7 +465,6 @@
434F54601D28859B002A9274 /* ServiceCredential.swift */,
43C418B41CE0575200405B6A /* ShareGlucose+GlucoseKit.swift */,
434F545E1D288345002A9274 /* ShareService.swift */,
434F24C81CFCA8940004498F /* TransmitterGlucose.swift */,
4328E0311CFC068900E199AA /* WatchContext+LoopKit.swift */,
);
path = Models;
Expand Down Expand Up @@ -978,8 +975,6 @@
4315D28A1CA5F45E00589052 /* DiagnosticLogger+LoopKit.swift in Sources */,
43C418B51CE0575200405B6A /* ShareGlucose+GlucoseKit.swift in Sources */,
430DA58E1D4AEC230097D1CA /* NSBundle.swift in Sources */,
434F24C91CFCA8940004498F /* TransmitterGlucose.swift in Sources */,
434F24CB1CFCB7AB0004498F /* GlucoseRxMessage.swift in Sources */,
43776F901B8022E90074EA36 /* AppDelegate.swift in Sources */,
437CCADA1D284ADF0075D2C3 /* AuthenticationTableViewCell.swift in Sources */,
43CE7CDE1CA8B63E003CC1B0 /* NSDate.swift in Sources */,
Expand All @@ -990,6 +985,7 @@
437CCADE1D2858FD0075D2C3 /* AuthenticationViewController.swift in Sources */,
43A5676B1C96155700334FAC /* SwitchTableViewCell.swift in Sources */,
43A567691C94880B00334FAC /* LoopDataManager.swift in Sources */,
43E397A31D56B9E40028E321 /* Glucose.swift in Sources */,
4302F4E11D4E9C8900F0FCAF /* TextFieldTableViewController.swift in Sources */,
43E344A41B9E1B1C00C85C07 /* NSUserDefaults.swift in Sources */,
43649A631C7A347F00523D7F /* CollectionType.swift in Sources */,
Expand Down
16 changes: 0 additions & 16 deletions Loop/Extensions/NSUserDefaults.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ extension NSUserDefaults {
case InsulinSensitivitySchedule = "com.loudnate.Naterade.InsulinSensitivitySchedule"
case G4ReceiverEnabled = "com.loudnate.Loop.G4ReceiverEnabled"
case G5TransmitterID = "com.loudnate.Naterade.TransmitterID"
case G5TransmitterStartTime = "com.loudnate.Naterade.TransmitterStartTime"
case GlucoseTargetRangeSchedule = "com.loudnate.Naterade.GlucoseTargetRangeSchedule"
case MaximumBasalRatePerHour = "com.loudnate.Naterade.MaximumBasalRatePerHour"
case MaximumBolus = "com.loudnate.Naterade.MaximumBolus"
Expand Down Expand Up @@ -202,21 +201,6 @@ extension NSUserDefaults {
}
}

var transmitterStartTime: NSTimeInterval? {
get {
let value = doubleForKey(Key.G5TransmitterStartTime.rawValue)

return value > 0 ? value : nil
}
set {
if let value = newValue {
setDouble(value, forKey: Key.G5TransmitterStartTime.rawValue)
} else {
removeObjectForKey(Key.G5TransmitterStartTime.rawValue)
}
}
}

var transmitterID: String? {
get {
return stringForKey(Key.G5TransmitterID.rawValue)
Expand Down
115 changes: 42 additions & 73 deletions Loop/Managers/DeviceDataManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ import RileyLinkKit
import ShareClient
import xDripG5

private enum State<T> {
case NeedsConfiguration
case Ready(T)
}


class DeviceDataManager: CarbStoreDelegate, TransmitterDelegate, ReceiverDelegate {
/// Notification posted by the instance when new glucose data was processed
Expand All @@ -48,32 +43,24 @@ class DeviceDataManager: CarbStoreDelegate, TransmitterDelegate, ReceiverDelegat
// Timestamp of last event we've retrieved from pump
var observingPumpEventsSince = NSDate(timeIntervalSinceNow: NSTimeInterval(hours: -24))

/// The G5 transmitter object
var transmitter: Transmitter? {
switch transmitterState {
case .Ready(let transmitter):
return transmitter
case .NeedsConfiguration:
return nil
}
}

// The Dexcom Share receiver object
var receiver: Receiver?

var receiverEnabled: Bool = false {
private var receiver: Receiver? {
didSet {
if (receiverEnabled) {
receiver = Receiver()
receiver!.delegate = self
} else {
receiver = nil
}
NSUserDefaults.standardUserDefaults().receiverEnabled = receiverEnabled
receiver?.delegate = self
enableRileyLinkHeartbeatIfNeeded()
}
}

var receiverEnabled: Bool {
get {
return receiver != nil
}
set {
receiver = newValue ? Receiver() : nil
NSUserDefaults.standardUserDefaults().receiverEnabled = newValue
}
}

var sensorInfo: SensorDisplayable? {
return latestGlucoseG5 ?? latestGlucoseG4 ?? latestPumpStatusFromMySentry
}
Expand Down Expand Up @@ -140,7 +127,7 @@ class DeviceDataManager: CarbStoreDelegate, TransmitterDelegate, ReceiverDelegat
}

func enableRileyLinkHeartbeatIfNeeded() {
if case .Ready = transmitterState {
if transmitter != nil {
rileyLinkManager.timerTickEnabled = false
} else if receiverEnabled {
rileyLinkManager.timerTickEnabled = false
Expand Down Expand Up @@ -498,48 +485,34 @@ class DeviceDataManager: CarbStoreDelegate, TransmitterDelegate, ReceiverDelegat
assertCurrentPumpData()
}

func transmitter(transmitter: xDripG5.Transmitter, didReadGlucose glucoseMessage: xDripG5.GlucoseRxMessage) {
transmitterStartTime = transmitter.startTimeInterval

func transmitter(transmitter: xDripG5.Transmitter, didRead glucose: xDripG5.Glucose) {
assertCurrentPumpData()

guard glucoseMessage != latestGlucoseG5 else {
guard glucose != latestGlucoseG5 else {
return
}

latestGlucoseG5 = glucoseMessage
latestGlucoseG5 = glucose

guard let glucose = TransmitterGlucose(glucoseMessage: glucoseMessage, startTime: transmitter.startTimeInterval), glucoseStore = glucoseStore else {
guard let glucoseStore = glucoseStore, let quantity = glucose.glucose else {
NSNotificationCenter.defaultCenter().postNotificationName(self.dynamicType.GlucoseUpdatedNotification, object: self)
return
}

let device = HKDevice(name: "xDripG5", manufacturer: "Dexcom", model: "G5 Mobile", hardwareVersion: nil, firmwareVersion: nil, softwareVersion: String(xDripG5VersionNumber), localIdentifier: nil, UDIDeviceIdentifier: "00386270000002")

glucoseStore.addGlucose(glucose.quantity, date: glucose.startDate, isDisplayOnly: glucoseMessage.glucoseIsDisplayOnly, device: device, resultHandler: { (_, _, error) -> Void in
glucoseStore.addGlucose(quantity, date: glucose.readDate, isDisplayOnly: glucose.isDisplayOnly, device: device) { (_, _, error) -> Void in
if let error = error {
self.logger.addError(error, fromSource: "GlucoseStore")
}

NSNotificationCenter.defaultCenter().postNotificationName(self.dynamicType.GlucoseUpdatedNotification, object: self)
})
}
}

// MARK: G5 data

private var transmitterStartTime: NSTimeInterval? = NSUserDefaults.standardUserDefaults().transmitterStartTime {
didSet {
if oldValue != transmitterStartTime {
NSUserDefaults.standardUserDefaults().transmitterStartTime = transmitterStartTime

if let transmitterStartTime = transmitterStartTime, drift = oldValue?.distanceTo(transmitterStartTime) where abs(drift) > 1 {
AnalyticsManager.sharedManager.transmitterTimeDidDrift(drift)
}
}
}
}

private var latestGlucoseG5: GlucoseRxMessage?
private var latestGlucoseG5: xDripG5.Glucose?

/**
Attempts to backfill glucose data from the share servers if a G5 connection hasn't been established.
Expand Down Expand Up @@ -731,38 +704,27 @@ class DeviceDataManager: CarbStoreDelegate, TransmitterDelegate, ReceiverDelegat

// MARK: G5 Transmitter

private var transmitterState: State<Transmitter> = .NeedsConfiguration {
internal private(set) var transmitter: Transmitter? {
didSet {
if case .Ready(let transmitter) = transmitterState {
transmitter.delegate = self
}
transmitter?.delegate = self
enableRileyLinkHeartbeatIfNeeded()
}
}

var transmitterID: String? {
didSet {
if transmitterID?.characters.count != 6 {
transmitterID = nil
}
get {
return transmitter?.ID
}
set {
guard transmitterID != newValue else { return }

switch (transmitterState, transmitterID) {
case (.NeedsConfiguration, let transmitterID?):
transmitterState = .Ready(Transmitter(
ID: transmitterID,
startTimeInterval: NSUserDefaults.standardUserDefaults().transmitterStartTime,
passiveModeEnabled: true
))
case (.Ready, .None):
transmitterState = .NeedsConfiguration
case (.Ready(let transmitter), let transmitterID?):
transmitter.ID = transmitterID
transmitter.startTimeInterval = nil
case (.NeedsConfiguration, .None):
break
if let transmitterID = newValue where transmitterID.characters.count == 6 {
transmitter = Transmitter(ID: transmitterID, passiveModeEnabled: true)
} else {
transmitter = nil
}

NSUserDefaults.standardUserDefaults().transmitterID = transmitterID
NSUserDefaults.standardUserDefaults().transmitterID = newValue
}
}

Expand Down Expand Up @@ -957,9 +919,16 @@ class DeviceDataManager: CarbStoreDelegate, TransmitterDelegate, ReceiverDelegat

carbStore?.delegate = self

defer {
transmitterID = NSUserDefaults.standardUserDefaults().transmitterID
receiverEnabled = NSUserDefaults.standardUserDefaults().receiverEnabled
if NSUserDefaults.standardUserDefaults().receiverEnabled {
receiver = Receiver()
receiver?.delegate = self
}

if let transmitterID = NSUserDefaults.standardUserDefaults().transmitterID {
transmitter = Transmitter(ID: transmitterID, passiveModeEnabled: true)
transmitter?.delegate = self
}

enableRileyLinkHeartbeatIfNeeded()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,23 @@ import Foundation
import xDripG5


extension GlucoseRxMessage: SensorDisplayable {
extension Glucose: SensorDisplayable {
var stateDescription: String {
let status: String
switch self.status {
case .OK:
status = ""
case .LowBattery:
status = NSLocalizedString("Low Battery", comment: "The description of a low G5 transmitter battery")
status = NSLocalizedString(" Low Battery", comment: "The description of a low G5 transmitter battery with a leading space")
case .Unknown(let value):
status = String(format: "%02x", value)
}

return String(format: "%1$02x %2$@", state, status)
return String(format: "%1$02x %2$@", String(state), status)
}

var trendType: GlucoseTrend? {
guard trend < Int8.max else {
guard trend < Int(Int8.max) else {
return nil
}

Expand Down