Skip to content

Commit

Permalink
Managed data interval now set per cgm type (#528)
Browse files Browse the repository at this point in the history
* Managed data interval now set per cgm type

* reset credentialOptionPicker on reuse
  • Loading branch information
ps2 authored Jul 24, 2017
1 parent c869bc5 commit f7d1054
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 35 deletions.
3 changes: 3 additions & 0 deletions Loop/Managers/CGM/CGMManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ protocol CGMManager: CustomDebugStringConvertible {
/// Whether the device is capable of waking the app
var providesBLEHeartbeat: Bool { get }

/// The length of time to keep samples in HealthKit before removal. Return nil to never remove samples.
var managedDataInterval: TimeInterval? { get }

var sensorState: SensorDisplayable? { get }

/// The representation of the device for use in HealthKit
Expand Down
21 changes: 20 additions & 1 deletion Loop/Managers/CGM/DexCGMManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ class DexCGMManager: CGMManager {
return shareManager?.sensorState
}

var managedDataInterval: TimeInterval? {
return shareManager?.managedDataInterval
}

fileprivate var shareManager: ShareClientManager? = ShareClientManager()

var device: HKDevice? {
Expand All @@ -53,12 +57,14 @@ class DexCGMManager: CGMManager {
final class ShareClientManager: CGMManager {
weak var delegate: CGMManagerDelegate?

var providesBLEHeartbeat = false
let providesBLEHeartbeat = false

var sensorState: SensorDisplayable? {
return latestBackfill
}

let managedDataInterval: TimeInterval? = nil

private var latestBackfill: ShareGlucose?

func fetchNewDataIfNeeded(with deviceManager: DeviceDataManager, _ completion: @escaping (CGMResult) -> Void) {
Expand Down Expand Up @@ -129,6 +135,14 @@ final class G5CGMManager: DexCGMManager, TransmitterDelegate {
return latestReading ?? super.sensorState
}

override var managedDataInterval: TimeInterval? {
if let transmitter = transmitter, transmitter.passiveModeEnabled {
return .hours(3)
}

return super.managedDataInterval
}

private var latestReading: Glucose? {
didSet {
// Once we have our first reading, disable backfill
Expand Down Expand Up @@ -202,6 +216,11 @@ final class G4CGMManager: DexCGMManager, ReceiverDelegate {
return latestReading ?? super.sensorState
}


override var managedDataInterval: TimeInterval? {
return .hours(3)
}

private var latestReading: GlucoseG4? {
didSet {
// Once we have our first reading, disable backfill
Expand Down
4 changes: 3 additions & 1 deletion Loop/Managers/CGM/EnliteCGMManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ import MinimedKit


final class EnliteCGMManager: CGMManager {
var providesBLEHeartbeat = false
let providesBLEHeartbeat = false

weak var delegate: CGMManagerDelegate?

var sensorState: SensorDisplayable?

let managedDataInterval: TimeInterval? = nil

func fetchNewDataIfNeeded(with deviceManager: DeviceDataManager, _ completion: @escaping (CGMResult) -> Void) {
guard let device = deviceManager.rileyLinkManager.firstConnectedDevice?.ops
else {
Expand Down
1 change: 1 addition & 0 deletions Loop/Managers/DeviceDataManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,7 @@ final class DeviceDataManager {
private func setupCGM() {
cgmManager = cgm?.createManager()
cgmManager?.delegate = self
loopManager.glucoseStore.managedDataInterval = cgmManager?.managedDataInterval

/// Controls the management of the RileyLink timer tick, which is a reliably-changing BLE
/// characteristic which can cause the app to wake. For most users, the G5 Transmitter and
Expand Down
107 changes: 74 additions & 33 deletions Loop/View Controllers/SettingsTableViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu
case enlite = 0
case g4
case g5
case dexcomShare // only displayed if g4 or g5 switched on
case g5TransmitterID // only displayed if g5 switched on
}

Expand All @@ -120,8 +121,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu
}

fileprivate enum ServiceRow: Int, CaseCountable {
case share = 0
case nightscout
case nightscout = 0
case mLab
case loggly
case amplitude
Expand Down Expand Up @@ -151,10 +151,12 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu
return PumpRow.count
case .cgm:
switch dataManager.cgm {
case .g4?:
return CGMRow.count - 1 // No Transmitter ID cell
case .g5?:
return CGMRow.count
default:
return CGMRow.count - 1
return CGMRow.count - 2 // No Share or Transmitter ID cell
}
case .configuration:
return ConfigurationRow.count
Expand All @@ -166,8 +168,6 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell

switch Section(rawValue: indexPath.section)! {
case .loop:
switch LoopRow(rawValue: indexPath.row)! {
Expand Down Expand Up @@ -205,20 +205,28 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu
configCell.textLabel?.text = NSLocalizedString("Pump Battery Type", comment: "The title text for the battery type value")
configCell.detailTextLabel?.text = String(describing: dataManager.batteryChemistry)
}
cell = configCell
return configCell
case .cgm:
let row = CGMRow(rawValue: indexPath.row)!
switch row {
case .dexcomShare:
let configCell = tableView.dequeueReusableCell(withIdentifier: ConfigCellIdentifier, for: indexPath)
let shareService = dataManager.remoteDataManager.shareService

configCell.textLabel?.text = shareService.title
configCell.detailTextLabel?.text = shareService.username ?? TapToSetString

return configCell
case .g5TransmitterID:
let configCell = tableView.dequeueReusableCell(withIdentifier: ConfigCellIdentifier, for: indexPath)

configCell.textLabel?.text = NSLocalizedString("G5 Transmitter ID", comment: "The title text for the Dexcom G5 transmitter ID config value")
configCell.textLabel?.text = NSLocalizedString("Transmitter ID", comment: "The title text for the Dexcom G5 transmitter ID config value")

if case .g5(let transmitterID)? = dataManager.cgm {
configCell.detailTextLabel?.text = transmitterID ?? TapToSetString
}

cell = configCell
return configCell
default:
let switchCell = tableView.dequeueReusableCell(withIdentifier: SwitchTableViewCell.className, for: indexPath) as! SwitchTableViewCell

Expand All @@ -240,11 +248,11 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu

switchCell.titleLabel.text = NSLocalizedString("G5 Transmitter", comment: "The title text for the G5 Transmitter switch cell")
switchCell.switch?.addTarget(self, action: #selector(g5Changed(_:)), for: .valueChanged)
case .g5TransmitterID:
case .dexcomShare, .g5TransmitterID:
assertionFailure()
}

cell = switchCell
return switchCell
}
case .configuration:
let configCell = tableView.dequeueReusableCell(withIdentifier: ConfigCellIdentifier, for: indexPath)
Expand Down Expand Up @@ -318,7 +326,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu
configCell.detailTextLabel?.text = TapToSetString
}
case .maxBasal:
configCell.textLabel?.text = NSLocalizedString("Maximum Basal Rate", comment: "The title text for the maximum basal rate value")
configCell.textLabel?.text = NSLocalizedString("Maximum Basal Rate", comment: "The title text for the maximum basal rate value")

if let maxBasal = dataManager.loopManager.settings.maximumBasalRatePerHour {
configCell.detailTextLabel?.text = "\(valueNumberFormatter.string(from: NSNumber(value: maxBasal))!) U/hour"
Expand All @@ -335,7 +343,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu
}
}

cell = configCell
return configCell
case .devices:
let deviceCell = tableView.dequeueReusableCell(withIdentifier: RileyLinkDeviceTableViewCell.className) as! RileyLinkDeviceTableViewCell
let device = dataManager.rileyLinkManager.devices[indexPath.row]
Expand All @@ -347,16 +355,11 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu

deviceCell.connectSwitch.addTarget(self, action: #selector(deviceConnectionChanged(_:)), for: .valueChanged)

cell = deviceCell
return deviceCell
case .services:
let configCell = tableView.dequeueReusableCell(withIdentifier: ConfigCellIdentifier, for: indexPath)

switch ServiceRow(rawValue: indexPath.row)! {
case .share:
let shareService = dataManager.remoteDataManager.shareService

configCell.textLabel?.text = shareService.title
configCell.detailTextLabel?.text = shareService.username ?? TapToSetString
case .nightscout:
let nightscoutService = dataManager.remoteDataManager.nightscoutService

Expand All @@ -381,7 +384,6 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu

return configCell
}
return cell
}

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
Expand All @@ -403,6 +405,22 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu

// MARK: - UITableViewDelegate

override func tableView(_ tableView: UITableView, indentationLevelForRowAt indexPath: IndexPath) -> Int {
switch Section(rawValue: indexPath.section)! {
case .cgm:
switch CGMRow(rawValue: indexPath.row)! {
case .dexcomShare, .g5TransmitterID:
return 1
default:
break
}
default:
break
}

return 0
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let sender = tableView.cellForRow(at: indexPath)

Expand Down Expand Up @@ -432,6 +450,16 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu
}
case .cgm:
switch CGMRow(rawValue: indexPath.row)! {
case .dexcomShare:
let service = dataManager.remoteDataManager.shareService
let vc = AuthenticationViewController(authentication: service)
vc.authenticationObserver = { [unowned self] (service) in
self.dataManager.remoteDataManager.shareService = service

self.tableView.reloadRows(at: [indexPath], with: .none)
}

show(vc, sender: sender)
case .g5TransmitterID:
let vc: TextFieldTableViewController
var value: String?
Expand Down Expand Up @@ -591,16 +619,6 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu
}
case .services:
switch ServiceRow(rawValue: indexPath.row)! {
case .share:
let service = dataManager.remoteDataManager.shareService
let vc = AuthenticationViewController(authentication: service)
vc.authenticationObserver = { [unowned self] (service) in
self.dataManager.remoteDataManager.shareService = service

self.tableView.reloadRows(at: [indexPath], with: .none)
}

show(vc, sender: sender)
case .nightscout:
let service = dataManager.remoteDataManager.nightscoutService
let vc = AuthenticationViewController(authentication: service)
Expand Down Expand Up @@ -687,10 +705,17 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu
if sender.isOn {
setG4SwitchOff()
setEnliteSwitchOff()
let shareRowExists = tableView.numberOfRows(inSection: Section.cgm.rawValue) > CGMRow.dexcomShare.rawValue
dataManager.cgm = .g5(transmitterID: g5TransmitterID)

tableView.insertRows(at: [IndexPath(row: CGMRow.g5TransmitterID.rawValue, section:Section.cgm.rawValue)], with: .top)
var indexPaths = [IndexPath(row: CGMRow.g5TransmitterID.rawValue, section:Section.cgm.rawValue)]
if !shareRowExists {
indexPaths.insert(IndexPath(row: CGMRow.dexcomShare.rawValue, section:Section.cgm.rawValue), at: 0)
}

tableView.insertRows(at: indexPaths, with: .top)
} else {
removeDexcomShareRow()
removeG5TransmitterIDRow()
dataManager.cgm = nil
}
Expand All @@ -702,8 +727,15 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu
if sender.isOn {
setG5SwitchOff()
setEnliteSwitchOff()
removeG5TransmitterIDRow()
let shareRowExists = tableView.numberOfRows(inSection: Section.cgm.rawValue) > CGMRow.dexcomShare.rawValue
dataManager.cgm = .g4

if !shareRowExists {
tableView.insertRows(at: [IndexPath(row: CGMRow.dexcomShare.rawValue, section:Section.cgm.rawValue)], with: .top)
}
} else {
removeDexcomShareRow()
dataManager.cgm = nil
}
tableView.endUpdates()
Expand All @@ -714,6 +746,8 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu
if sender.isOn {
setG5SwitchOff()
setG4SwitchOff()
removeDexcomShareRow()
removeG5TransmitterIDRow()
dataManager.cgm = .enlite
} else {
dataManager.cgm = nil
Expand All @@ -723,18 +757,25 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu

// MARK: Views

private func removeDexcomShareRow() {
switch dataManager.cgm {
case .g4?, .g5?:
tableView.deleteRows(at: [IndexPath(row: CGMRow.dexcomShare.rawValue, section: Section.cgm.rawValue)], with: .top)
default:
break;
}
}

private func removeG5TransmitterIDRow() {
if case .g5(let transmitterID)? = dataManager.cgm {
g5TransmitterID = transmitterID
tableView.deleteRows(at: [IndexPath(row: CGMRow.g5TransmitterID.rawValue, section:Section.cgm.rawValue)], with: .top)
tableView.deleteRows(at: [IndexPath(row: CGMRow.g5TransmitterID.rawValue, section: Section.cgm.rawValue)], with: .top)
}
}

private func setG5SwitchOff() {
let switchCell = tableView.cellForRow(at: IndexPath(row: CGMRow.g5.rawValue, section: Section.cgm.rawValue)) as! SwitchTableViewCell
switchCell.switch?.setOn(false, animated: true)

removeG5TransmitterIDRow()
}

private func setG4SwitchOff() {
Expand Down
1 change: 1 addition & 0 deletions Loop/Views/AuthenticationTableViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ final class AuthenticationTableViewCell: UITableViewCell, NibLoadable {
super.prepareForReuse()

textField.delegate = nil
credentialOptionPicker = nil
}

var credentialOptionPicker: CredentialOptionPicker? {
Expand Down

0 comments on commit f7d1054

Please sign in to comment.