Skip to content

Commit

Permalink
Merge pull request #449 from ps2/dev
Browse files Browse the repository at this point in the history
Release 2.0.4
  • Loading branch information
ps2 authored Sep 3, 2018
2 parents 7a1f6bd + 8e122ec commit b005629
Show file tree
Hide file tree
Showing 95 changed files with 1,130 additions and 1,868 deletions.
8 changes: 6 additions & 2 deletions Common/LocalizedString.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ private class FrameworkBundle {
static let main = Bundle(for: FrameworkBundle.self)
}

func LocalizedString(_ key: String, tableName: String? = nil, value: String = "", comment: String) -> String {
return NSLocalizedString(key, tableName: tableName, bundle: FrameworkBundle.main, value: value, comment: comment)
func LocalizedString(_ key: String, tableName: String? = nil, value: String? = nil, comment: String) -> String {
if let value = value {
return NSLocalizedString(key, tableName: tableName, bundle: FrameworkBundle.main, value: value, comment: comment)
} else {
return NSLocalizedString(key, tableName: tableName, bundle: FrameworkBundle.main, comment: comment)
}
}
15 changes: 12 additions & 3 deletions Common/TimeInterval.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import Foundation


extension TimeInterval {

static func days(_ days: Double) -> TimeInterval {
return self.init(days: days)
}

static func hours(_ hours: Double) -> TimeInterval {
return self.init(hours: hours)
}
Expand All @@ -30,13 +35,17 @@ extension TimeInterval {
return self.init(milliseconds / 1000)
}

init(minutes: Double) {
self.init(minutes * 60)
init(days: Double) {
self.init(hours: days * 24)
}

init(hours: Double) {
self.init(minutes: hours * 60)
}

init(minutes: Double) {
self.init(minutes * 60)
}

init(seconds: Double) {
self.init(seconds)
Expand Down
2 changes: 1 addition & 1 deletion Crypto/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.0.3</string>
<string>2.0.4</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
Expand Down
2 changes: 1 addition & 1 deletion MinimedKit/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.0.3</string>
<string>2.0.4</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down
3 changes: 3 additions & 0 deletions MinimedKit/Messages/PumpErrorMessageBody.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public enum PumpErrorCode: UInt8, CustomStringConvertible {
case commandRefused = 0x08
case maxSettingExceeded = 0x09
case bolusInProgress = 0x0c
case pageDoesNotExist = 0x0d

public var description: String {
switch self {
Expand All @@ -22,6 +23,8 @@ public enum PumpErrorCode: UInt8, CustomStringConvertible {
return LocalizedString("Max setting exceeded", comment: "Pump error code describing max setting exceeded")
case .bolusInProgress:
return LocalizedString("Bolus in progress", comment: "Pump error code when bolus is in progress")
case .pageDoesNotExist:
return LocalizedString("History page does not exist", comment: "Pump error code when invalid history page is requested")
}
}

Expand Down
56 changes: 33 additions & 23 deletions MinimedKit/PumpManager/MinimedPumpManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,42 +15,51 @@ import os.log
public class MinimedPumpManager: RileyLinkPumpManager, PumpManager {
public static let managerIdentifier: String = "Minimed500"

public init(state: MinimedPumpManagerState, rileyLinkManager: RileyLinkDeviceManager?) {
public init(state: MinimedPumpManagerState, rileyLinkDeviceProvider: RileyLinkDeviceProvider, rileyLinkConnectionManager: RileyLinkConnectionManager? = nil, pumpOps: PumpOps? = nil) {
self.state = state

super.init(rileyLinkPumpManagerState: state.rileyLinkPumpManagerState, rileyLinkManager: rileyLinkManager)
super.init(rileyLinkDeviceProvider: rileyLinkDeviceProvider, rileyLinkConnectionManager: rileyLinkConnectionManager)

// Pump communication
let idleListeningEnabled = state.pumpModel.hasMySentry
self.pumpOps = PumpOps(pumpSettings: state.pumpSettings, pumpState: state.pumpState, delegate: self)
self.pumpOps = pumpOps ?? PumpOps(pumpSettings: state.pumpSettings, pumpState: state.pumpState, delegate: self)

self.rileyLinkManager.idleListeningState = idleListeningEnabled ? MinimedPumpManagerState.idleListeningEnabledDefaults : .disabled
self.rileyLinkDeviceProvider.idleListeningState = idleListeningEnabled ? MinimedPumpManagerState.idleListeningEnabledDefaults : .disabled
}

public required convenience init?(rawState: PumpManager.RawStateValue) {
guard let state = MinimedPumpManagerState(rawValue: rawState) else {
guard let state = MinimedPumpManagerState(rawValue: rawState),
let connectionManagerState = state.rileyLinkConnectionManagerState else
{
return nil
}

self.init(state: state, rileyLinkManager: nil)

let rileyLinkConnectionManager = RileyLinkConnectionManager(state: connectionManagerState)

self.init(state: state, rileyLinkDeviceProvider: rileyLinkConnectionManager.deviceProvider, rileyLinkConnectionManager: rileyLinkConnectionManager)

rileyLinkConnectionManager.delegate = self
}

public var rawState: PumpManager.RawStateValue {
return state.rawValue
}

override public var rileyLinkPumpManagerState: RileyLinkPumpManagerState {
didSet {
state.rileyLinkPumpManagerState = rileyLinkPumpManagerState
}
}

// TODO: apply lock
public private(set) var state: MinimedPumpManagerState {
didSet {
pumpManagerDelegate?.pumpManagerDidUpdateState(self)
}
}

override public var rileyLinkConnectionManagerState: RileyLinkConnectionManagerState? {
get {
return state.rileyLinkConnectionManagerState
}
set {
state.rileyLinkConnectionManagerState = newValue
}
}

public weak var cgmManagerDelegate: CGMManagerDelegate?

Expand Down Expand Up @@ -106,7 +115,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager {
/// characteristic which can cause the app to wake. For most users, the G5 Transmitter and
/// G4 Receiver are reliable as hearbeats, but users who find their resources extremely constrained
/// due to greedy apps or older devices may choose to always enable the timer by always setting `true`
self.rileyLinkManager.timerTickEnabled = self.isPumpDataStale || (self.pumpManagerDelegate?.pumpManagerShouldProvideBLEHeartbeat(self) == true)
self.rileyLinkDeviceProvider.timerTickEnabled = self.isPumpDataStale || (self.pumpManagerDelegate?.pumpManagerShouldProvideBLEHeartbeat(self) == true)
}
}

Expand Down Expand Up @@ -204,14 +213,14 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager {
}
} catch let error {
self.log.error("Device %{public}@ auto-tune failed with error: %{public}@", device.name ?? "", String(describing: error))
self.rileyLinkManager.deprioritize(device)
self.rileyLinkDeviceProvider.deprioritize(device, completion: nil)
if let error = error as? LocalizedError {
self.pumpManagerDelegate?.pumpManager(self, didError: PumpManagerError.communication(MinimedPumpManagerError.tuneFailed(error)))
}
}
}
} else {
rileyLinkManager.deprioritize(device)
rileyLinkDeviceProvider.deprioritize(device, completion: nil)
}
}

Expand Down Expand Up @@ -343,7 +352,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager {
/// - completion: A closure called once upon completion
/// - error: An error describing why the fetch and/or store failed
private func fetchPumpHistory(_ completion: @escaping (_ error: Error?) -> Void) {
rileyLinkManager.getDevices { (devices) in
rileyLinkDeviceProvider.getDevices { (devices) in
guard let device = devices.firstConnected else {
completion(PumpManagerError.connection(MinimedPumpManagerError.noRileyLink))
return
Expand Down Expand Up @@ -376,7 +385,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager {
/// TODO: Isolate to queue
private var isPumpDataStale: Bool {
// How long should we wait before we poll for new pump data?
let pumpStatusAgeTolerance = rileyLinkManager.idleListeningEnabled ? TimeInterval(minutes: 6) : TimeInterval(minutes: 4)
let pumpStatusAgeTolerance = rileyLinkDeviceProvider.idleListeningEnabled ? TimeInterval(minutes: 6) : TimeInterval(minutes: 4)

return isReservoirDataOlderThan(timeIntervalSinceNow: -pumpStatusAgeTolerance)
}
Expand All @@ -400,15 +409,15 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager {
*/
/// TODO: Isolate to queue
public func assertCurrentPumpData() {
rileyLinkManager.assertIdleListening(forcingRestart: true)
rileyLinkDeviceProvider.assertIdleListening(forcingRestart: true)

guard isPumpDataStale else {
return
}

self.log.debug("Pump data is stale, fetching.")

rileyLinkManager.getDevices { (devices) in
rileyLinkDeviceProvider.getDevices { (devices) in
guard let device = devices.firstConnected else {
let error = PumpManagerError.connection(MinimedPumpManagerError.noRileyLink)
self.log.error("No devices found while fetching pump data")
Expand Down Expand Up @@ -492,7 +501,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager {
// If we don't have recent pump data, or the pump was recently rewound, read new pump data before bolusing.
let shouldReadReservoir = isReservoirDataOlderThan(timeIntervalSinceNow: .minutes(-6))

pumpOps.runSession(withName: "Bolus", using: rileyLinkManager.firstConnectedDevice) { (session) in
pumpOps.runSession(withName: "Bolus", using: rileyLinkDeviceProvider.firstConnectedDevice) { (session) in
guard let session = session else {
completion(PumpManagerError.connection(MinimedPumpManagerError.noRileyLink))
return
Expand Down Expand Up @@ -536,7 +545,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager {
}

public func enactTempBasal(unitsPerHour: Double, for duration: TimeInterval, completion: @escaping (PumpManagerResult<DoseEntry>) -> Void) {
pumpOps.runSession(withName: "Set Temp Basal", using: rileyLinkManager.firstConnectedDevice) { (session) in
pumpOps.runSession(withName: "Set Temp Basal", using: rileyLinkDeviceProvider.firstConnectedDevice) { (session) in
guard let session = session else {
completion(.failure(PumpManagerError.connection(MinimedPumpManagerError.noRileyLink)))
return
Expand Down Expand Up @@ -646,7 +655,7 @@ extension MinimedPumpManager: CGMManager {
}

public func fetchNewDataIfNeeded(_ completion: @escaping (CGMResult) -> Void) {
rileyLinkManager.getDevices { (devices) in
rileyLinkDeviceProvider.getDevices { (devices) in
guard let device = devices.firstConnected else {
completion(.error(PumpManagerError.connection(MinimedPumpManagerError.noRileyLink)))
return
Expand Down Expand Up @@ -685,3 +694,4 @@ extension MinimedPumpManager: CGMManager {
}
}
}

43 changes: 31 additions & 12 deletions MinimedKit/PumpManager/MinimedPumpManagerState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import RileyLinkBLEKit
public struct MinimedPumpManagerState: RawRepresentable, Equatable {
public typealias RawValue = PumpManager.RawStateValue

public static let version = 1
public static let version = 2

public var batteryChemistry: BatteryChemistryType

Expand Down Expand Up @@ -52,68 +52,87 @@ public struct MinimedPumpManagerState: RawRepresentable, Equatable {
}
}

public var rileyLinkPumpManagerState: RileyLinkPumpManagerState
public var rileyLinkConnectionManagerState: RileyLinkConnectionManagerState?

public var timeZone: TimeZone

public init(batteryChemistry: BatteryChemistryType = .alkaline, preferredInsulinDataSource: InsulinDataSource = .pumpHistory, pumpColor: PumpColor, pumpID: String, pumpModel: PumpModel, pumpRegion: PumpRegion, rileyLinkPumpManagerState: RileyLinkPumpManagerState, timeZone: TimeZone) {
public init(batteryChemistry: BatteryChemistryType = .alkaline, preferredInsulinDataSource: InsulinDataSource = .pumpHistory, pumpColor: PumpColor, pumpID: String, pumpModel: PumpModel, pumpRegion: PumpRegion, rileyLinkConnectionManagerState: RileyLinkConnectionManagerState?, timeZone: TimeZone) {
self.batteryChemistry = batteryChemistry
self.preferredInsulinDataSource = preferredInsulinDataSource
self.pumpColor = pumpColor
self.pumpID = pumpID
self.pumpModel = pumpModel
self.pumpRegion = pumpRegion
self.rileyLinkPumpManagerState = rileyLinkPumpManagerState
self.rileyLinkConnectionManagerState = rileyLinkConnectionManagerState
self.timeZone = timeZone
}

public init?(rawValue: RawValue) {
guard
let version = rawValue["version"] as? Int,
let batteryChemistryRaw = rawValue["batteryChemistry"] as? BatteryChemistryType.RawValue,
let insulinDataSourceRaw = rawValue["insulinDataSource"] as? InsulinDataSource.RawValue,
let pumpColorRaw = rawValue["pumpColor"] as? PumpColor.RawValue,
let pumpID = rawValue["pumpID"] as? String,
let pumpModelNumber = rawValue["pumpModel"] as? PumpModel.RawValue,
let pumpRegionRaw = rawValue["pumpRegion"] as? PumpRegion.RawValue,
let rileyLinkPumpManagerStateRaw = rawValue["rileyLinkPumpManagerState"] as? RileyLinkPumpManagerState.RawValue,
let timeZoneSeconds = rawValue["timeZone"] as? Int,

let batteryChemistry = BatteryChemistryType(rawValue: batteryChemistryRaw),
let insulinDataSource = InsulinDataSource(rawValue: insulinDataSourceRaw),
let pumpColor = PumpColor(rawValue: pumpColorRaw),
let pumpModel = PumpModel(rawValue: pumpModelNumber),
let pumpRegion = PumpRegion(rawValue: pumpRegionRaw),
let rileyLinkPumpManagerState = RileyLinkPumpManagerState(rawValue: rileyLinkPumpManagerStateRaw),
let timeZone = TimeZone(secondsFromGMT: timeZoneSeconds)
else {
return nil
}


var rileyLinkConnectionManagerState: RileyLinkConnectionManagerState? = nil

// Migrate
if version == 1
{
if let oldRileyLinkPumpManagerStateRaw = rawValue["rileyLinkPumpManagerState"] as? [String : Any],
let connectedPeripheralIDs = oldRileyLinkPumpManagerStateRaw["connectedPeripheralIDs"] as? [String]
{
rileyLinkConnectionManagerState = RileyLinkConnectionManagerState(autoConnectIDs: Set(connectedPeripheralIDs))
}
} else {
if let rawState = rawValue["rileyLinkConnectionManagerState"] as? RileyLinkConnectionManagerState.RawValue {
rileyLinkConnectionManagerState = RileyLinkConnectionManagerState(rawValue: rawState)
}
}

self.init(
batteryChemistry: batteryChemistry,
preferredInsulinDataSource: insulinDataSource,
pumpColor: pumpColor,
pumpID: pumpID,
pumpModel: pumpModel,
pumpRegion: pumpRegion,
rileyLinkPumpManagerState: rileyLinkPumpManagerState,
rileyLinkConnectionManagerState: rileyLinkConnectionManagerState,
timeZone: timeZone
)
}

public var rawValue: RawValue {
return [
var value: [String : Any] = [
"batteryChemistry": batteryChemistry.rawValue,
"insulinDataSource": preferredInsulinDataSource.rawValue,
"pumpColor": pumpColor.rawValue,
"pumpID": pumpID,
"pumpModel": pumpModel.rawValue,
"pumpRegion": pumpRegion.rawValue,
"rileyLinkPumpManagerState": rileyLinkPumpManagerState.rawValue,
"timeZone": timeZone.secondsFromGMT(),

"version": MinimedPumpManagerState.version,
]
]

if let rileyLinkConnectionManagerState = rileyLinkConnectionManagerState {
value["rileyLinkConnectionManagerState"] = rileyLinkConnectionManagerState.rawValue
}
return value
}
}

Expand All @@ -134,7 +153,7 @@ extension MinimedPumpManagerState: CustomDebugStringConvertible {
"pumpModel: \(pumpModel.rawValue)",
"pumpRegion: \(pumpRegion)",
"timeZone: \(timeZone)",
String(reflecting: rileyLinkPumpManagerState),
String(reflecting: rileyLinkConnectionManagerState),
].joined(separator: "\n")
}
}
2 changes: 1 addition & 1 deletion MinimedKitTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>2.0.3</string>
<string>2.0.4</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down
Loading

0 comments on commit b005629

Please sign in to comment.