From 6ff0b340f8ca3695d3f78852e1c4a1f496682426 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Fri, 13 Apr 2018 23:37:17 -0500 Subject: [PATCH 01/12] Add Nightscout profile struct, serialization and upload function --- .gitignore | 1 + NightscoutUploadKit/NightscoutProfile.swift | 85 ++++++++++++++++++++ NightscoutUploadKit/NightscoutUploader.swift | 5 ++ RileyLink.xcodeproj/project.pbxproj | 4 + 4 files changed, 95 insertions(+) create mode 100644 NightscoutUploadKit/NightscoutProfile.swift diff --git a/.gitignore b/.gitignore index 8c43aaa07..bedeedee5 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ DerivedData project.xcworkspace .DS_Store *.log +project.xcworkspace # CocoaPods # diff --git a/NightscoutUploadKit/NightscoutProfile.swift b/NightscoutUploadKit/NightscoutProfile.swift new file mode 100644 index 000000000..ed2a191c9 --- /dev/null +++ b/NightscoutUploadKit/NightscoutProfile.swift @@ -0,0 +1,85 @@ +// +// NightscoutProfile.swift +// NightscoutUploadKit +// + +import Foundation + +public class NightscoutProfile { + + public struct ScheduleItem { + let offset: TimeInterval + let value: Double + + public init(offset: TimeInterval, value: Double) { + self.offset = offset + self.value = value + } + + public var dictionaryRepresentation: [String: Any] { + var rep = [String: Any]() + let hours = floor(offset.hours) + let minutes = floor((offset - TimeInterval(hours: hours)).minutes) + rep["time"] = String(format:"%02i:%02i", Int(hours), Int(minutes)) + rep["value"] = value + rep["timeAsSeconds"] = Int(offset) + return rep + } + } + + let startDate : Date + let name : String + let timezone : TimeZone + let dia : TimeInterval + let sensitivity : [ScheduleItem] + let carbratio : [ScheduleItem] + let basal : [ScheduleItem] + let targetLow : [ScheduleItem] + let targetHigh : [ScheduleItem] + let units: String + + public init(startDate: Date, name: String, timezone: TimeZone, dia: TimeInterval, sensitivity: [ScheduleItem], carbratio: [ScheduleItem], basal: [ScheduleItem], targetLow: [ScheduleItem], targetHigh: [ScheduleItem], units: String) { + self.startDate = startDate + self.name = name + self.timezone = timezone + self.dia = dia + self.sensitivity = sensitivity + self.carbratio = carbratio + self.basal = basal + self.targetLow = targetLow + self.targetHigh = targetHigh + self.units = units + } + + public var dictionaryRepresentation: [String: Any] { + let dateFormatter = DateFormatter.ISO8601DateFormatter() + + let profile : [String: Any] = [ + "dia": dia.hours, + "carbs_hr": "0", + "delay": "0", + "timezone": timezone.identifier, + "target_low": targetLow.map { $0.dictionaryRepresentation }, + "target_high": targetHigh.map { $0.dictionaryRepresentation }, + "sens": sensitivity.map { $0.dictionaryRepresentation }, + "basal": basal.map { $0.dictionaryRepresentation }, + "carbratio": carbratio.map { $0.dictionaryRepresentation }, + ] + + + let store : [String: Any] = [ + name: profile + ] + + let rval : [String: Any] = [ + "defaultProfile": name, + "startDate": dateFormatter.string(from: startDate), + "mills": "0", + "units": units, + "enteredBy": "Loop", + "store": store + ] + + return rval + } +} diff --git a/NightscoutUploadKit/NightscoutUploader.swift b/NightscoutUploadKit/NightscoutUploader.swift index 31a741dc1..9798cad7d 100644 --- a/NightscoutUploadKit/NightscoutUploader.swift +++ b/NightscoutUploadKit/NightscoutUploader.swift @@ -20,6 +20,7 @@ private let defaultNightscoutEntriesPath = "/api/v1/entries" private let defaultNightscoutTreatmentPath = "/api/v1/treatments" private let defaultNightscoutDeviceStatusPath = "/api/v1/devicestatus" private let defaultNightscoutAuthTestPath = "/api/v1/experiments/test" +private let defaultNightscoutProfilePath = "/api/v1/profile" public class NightscoutUploader { @@ -241,6 +242,10 @@ public class NightscoutUploader { lastMeterMessageRxTime = date } } + + public func uploadProfile(profile: NightscoutProfile, completion: @escaping (Either<[String],Error>) -> Void) { + postToNS([profile.dictionaryRepresentation], endpoint:defaultNightscoutProfilePath, completion: completion) + } // MARK: - Uploading diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index b9d9710d7..af4a1e51e 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -302,6 +302,7 @@ C1842C241C8FA45100DB42AC /* BatteryPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BFA1C8FA45100DB42AC /* BatteryPumpEvent.swift */; }; C1842C251C8FA45100DB42AC /* AlarmSensorPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BFB1C8FA45100DB42AC /* AlarmSensorPumpEvent.swift */; }; C18C8C531D64123400E043FB /* EnableBolusWizardPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C18C8C521D64123400E043FB /* EnableBolusWizardPumpEvent.swift */; }; + C18EB742207EE20100EA002B /* NightscoutProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C18EB741207EE20100EA002B /* NightscoutProfile.swift */; }; C1A492631D4A5A19008964FF /* IOBStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A492621D4A5A19008964FF /* IOBStatus.swift */; }; C1A492651D4A5DEB008964FF /* BatteryStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A492641D4A5DEB008964FF /* BatteryStatus.swift */; }; C1A492671D4A65D9008964FF /* RecommendedTempBasal.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A492661D4A65D9008964FF /* RecommendedTempBasal.swift */; }; @@ -789,6 +790,7 @@ C1842C281C908A3C00DB42AC /* NightscoutUploader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NightscoutUploader.swift; sourceTree = ""; }; C1842C2A1C90DFB600DB42AC /* NightscoutPumpEvents.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NightscoutPumpEvents.swift; sourceTree = ""; }; C18C8C521D64123400E043FB /* EnableBolusWizardPumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnableBolusWizardPumpEvent.swift; sourceTree = ""; }; + C18EB741207EE20100EA002B /* NightscoutProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutProfile.swift; sourceTree = ""; }; C1A492621D4A5A19008964FF /* IOBStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IOBStatus.swift; sourceTree = ""; }; C1A492641D4A5DEB008964FF /* BatteryStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BatteryStatus.swift; sourceTree = ""; }; C1A492661D4A65D9008964FF /* RecommendedTempBasal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecommendedTempBasal.swift; sourceTree = ""; }; @@ -1522,6 +1524,7 @@ C1B3830D1CD0665D00CE7782 /* NightscoutUploadKit.h */, 43B0ADC81D1268B300AAD278 /* TimeFormat.swift */, C1AF21EA1D4900880088C41D /* Treatments */, + C18EB741207EE20100EA002B /* NightscoutProfile.swift */, ); path = NightscoutUploadKit; sourceTree = ""; @@ -2417,6 +2420,7 @@ buildActionMask = 2147483647; files = ( C1B383291CD0668600CE7782 /* NightscoutPumpEvents.swift in Sources */, + C18EB742207EE20100EA002B /* NightscoutProfile.swift in Sources */, 43B0ADCC1D126E3000AAD278 /* NSDateFormatter.swift in Sources */, C1AF21E81D4866960088C41D /* PumpStatus.swift in Sources */, C1AF21F01D4901220088C41D /* BolusNightscoutTreatment.swift in Sources */, From 45979dfab8e4db55b026b132490bcf15a046fc44 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sat, 14 Apr 2018 20:02:53 -0500 Subject: [PATCH 02/12] Support multiple profiles, and updates --- NightscoutUploadKit/NightscoutProfile.swift | 90 +++++++++++--------- NightscoutUploadKit/NightscoutUploader.swift | 12 ++- 2 files changed, 62 insertions(+), 40 deletions(-) diff --git a/NightscoutUploadKit/NightscoutProfile.swift b/NightscoutUploadKit/NightscoutProfile.swift index ed2a191c9..cbee2faa9 100644 --- a/NightscoutUploadKit/NightscoutProfile.swift +++ b/NightscoutUploadKit/NightscoutProfile.swift @@ -5,7 +5,7 @@ import Foundation -public class NightscoutProfile { +public class ProfileSet { public struct ScheduleItem { let offset: TimeInterval @@ -27,57 +27,71 @@ public class NightscoutProfile { } } + public struct Profile { + let timezone : TimeZone + let dia : TimeInterval + let sensitivity : [ScheduleItem] + let carbratio : [ScheduleItem] + let basal : [ScheduleItem] + let targetLow : [ScheduleItem] + let targetHigh : [ScheduleItem] + let units: String + + public init(timezone: TimeZone, dia: TimeInterval, sensitivity: [ScheduleItem], carbratio: [ScheduleItem], basal: [ScheduleItem], targetLow: [ScheduleItem], targetHigh: [ScheduleItem], units: String) { + self.timezone = timezone + self.dia = dia + self.sensitivity = sensitivity + self.carbratio = carbratio + self.basal = basal + self.targetLow = targetLow + self.targetHigh = targetHigh + self.units = units + } + + public var dictionaryRepresentation: [String: Any] { + return [ + "dia": dia.hours, + "carbs_hr": "0", + "delay": "0", + "timezone": timezone.identifier, + "target_low": targetLow.map { $0.dictionaryRepresentation }, + "target_high": targetHigh.map { $0.dictionaryRepresentation }, + "sens": sensitivity.map { $0.dictionaryRepresentation }, + "basal": basal.map { $0.dictionaryRepresentation }, + "carbratio": carbratio.map { $0.dictionaryRepresentation }, + ] + } + + } + let startDate : Date - let name : String - let timezone : TimeZone - let dia : TimeInterval - let sensitivity : [ScheduleItem] - let carbratio : [ScheduleItem] - let basal : [ScheduleItem] - let targetLow : [ScheduleItem] - let targetHigh : [ScheduleItem] let units: String + let enteredBy: String + let defaultProfile: String + let store: [String: Profile] - public init(startDate: Date, name: String, timezone: TimeZone, dia: TimeInterval, sensitivity: [ScheduleItem], carbratio: [ScheduleItem], basal: [ScheduleItem], targetLow: [ScheduleItem], targetHigh: [ScheduleItem], units: String) { + public init(startDate: Date, units: String, enteredBy: String, defaultProfile: String, store: [String: Profile]) { self.startDate = startDate - self.name = name - self.timezone = timezone - self.dia = dia - self.sensitivity = sensitivity - self.carbratio = carbratio - self.basal = basal - self.targetLow = targetLow - self.targetHigh = targetHigh self.units = units + self.enteredBy = enteredBy + self.defaultProfile = defaultProfile + self.store = store } public var dictionaryRepresentation: [String: Any] { let dateFormatter = DateFormatter.ISO8601DateFormatter() + let mills = String(format: "%.0f", startDate.timeIntervalSince1970.milliseconds) - let profile : [String: Any] = [ - "dia": dia.hours, - "carbs_hr": "0", - "delay": "0", - "timezone": timezone.identifier, - "target_low": targetLow.map { $0.dictionaryRepresentation }, - "target_high": targetHigh.map { $0.dictionaryRepresentation }, - "sens": sensitivity.map { $0.dictionaryRepresentation }, - "basal": basal.map { $0.dictionaryRepresentation }, - "carbratio": carbratio.map { $0.dictionaryRepresentation }, - ] - - - let store : [String: Any] = [ - name: profile - ] + let dictProfiles = Dictionary(uniqueKeysWithValues: + store.map { key, value in (key, value.dictionaryRepresentation) }) let rval : [String: Any] = [ - "defaultProfile": name, + "defaultProfile": defaultProfile, "startDate": dateFormatter.string(from: startDate), - "mills": "0", + "mills": mills, "units": units, - "enteredBy": "Loop", - "store": store + "enteredBy": enteredBy, + "store": dictProfiles ] return rval diff --git a/NightscoutUploadKit/NightscoutUploader.swift b/NightscoutUploadKit/NightscoutUploader.swift index 9798cad7d..d159b124c 100644 --- a/NightscoutUploadKit/NightscoutUploader.swift +++ b/NightscoutUploadKit/NightscoutUploader.swift @@ -242,9 +242,17 @@ public class NightscoutUploader { lastMeterMessageRxTime = date } } + + // MARK: - Profiles + + public func uploadProfile(profileSet: ProfileSet, completion: @escaping (Either<[String],Error>) -> Void) { + postToNS([profileSet.dictionaryRepresentation], endpoint:defaultNightscoutProfilePath, completion: completion) + } - public func uploadProfile(profile: NightscoutProfile, completion: @escaping (Either<[String],Error>) -> Void) { - postToNS([profile.dictionaryRepresentation], endpoint:defaultNightscoutProfilePath, completion: completion) + public func updateProfile(profileSet: ProfileSet, id: String, completion: @escaping (Error?) -> Void) { + var rep = profileSet.dictionaryRepresentation + rep["_id"] = id + putToNS(rep, endpoint: defaultNightscoutProfilePath, completion: completion) } // MARK: - Uploading From f32a4fe407f298121ff53f821ad9166374b2c237 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 16 Apr 2018 19:12:06 -0500 Subject: [PATCH 03/12] Add ability to enable diagnostic leds --- RileyLinkBLEKit/Command.swift | 23 +++++++++++++++ RileyLinkBLEKit/CommandSession.swift | 8 ++++++ .../PeripheralManager+RileyLink.swift | 28 +++++++++++++++++-- RileyLinkBLEKit/RileyLinkDevice.swift | 6 +++- RileyLinkKit/PumpMessageSender.swift | 3 ++ RileyLinkKit/PumpOpsSession.swift | 4 +++ ...sponseViewController+RileyLinkDevice.swift | 22 +++++++++++++++ .../RileyLinkDeviceTableViewController.swift | 8 +++++- 8 files changed, 98 insertions(+), 4 deletions(-) diff --git a/RileyLinkBLEKit/Command.swift b/RileyLinkBLEKit/Command.swift index 284ade5bf..68bc60735 100644 --- a/RileyLinkBLEKit/Command.swift +++ b/RileyLinkBLEKit/Command.swift @@ -25,6 +25,11 @@ enum RileyLinkCommand: UInt8 { case resetRadioConfig = 13 } +enum RileyLinkLEDType: UInt8 { + case green = 0 + case blue = 1 +} + protocol Command { associatedtype ResponseType: Response @@ -261,6 +266,24 @@ struct SetPreamble: Command { } } +struct SetLedMode: Command { + typealias ResponseType = CodeResponse + + let led: RileyLinkLEDType + let mode: RileyLinkLEDMode + + + init(_ led: RileyLinkLEDType, mode: RileyLinkLEDMode) { + self.led = led + self.mode = mode + } + + var data: Data { + return Data(bytes: [RileyLinkCommand.led.rawValue, led.rawValue, mode.rawValue]) + } +} + + struct ResetRadioConfig: Command { typealias ResponseType = CodeResponse diff --git a/RileyLinkBLEKit/CommandSession.swift b/RileyLinkBLEKit/CommandSession.swift index 3bd8a9b37..b4c710d5f 100644 --- a/RileyLinkBLEKit/CommandSession.swift +++ b/RileyLinkBLEKit/CommandSession.swift @@ -106,6 +106,14 @@ public struct CommandSession { let command = UpdateRegister(address, value: value, firmwareVersion: firmwareVersion) _ = try writeCommand(command, timeout: 0) } + + /// - Throws: RileyLinkDeviceError + public func enableCCLEDs() throws { + let enableBlue = SetLedMode(.blue, mode: .auto) + _ = try writeCommand(enableBlue, timeout: 0) + let enableGreen = SetLedMode(.green, mode: .auto) + _ = try writeCommand(enableGreen, timeout: 0) + } private static let xtalFrequency = Measurement(value: 24, unit: .megahertz) diff --git a/RileyLinkBLEKit/PeripheralManager+RileyLink.swift b/RileyLinkBLEKit/PeripheralManager+RileyLink.swift index d688bec15..548f3c20b 100644 --- a/RileyLinkBLEKit/PeripheralManager+RileyLink.swift +++ b/RileyLinkBLEKit/PeripheralManager+RileyLink.swift @@ -27,6 +27,13 @@ enum MainServiceCharacteristicUUID: String, CBUUIDRawValue { case customName = "D93B2AF0-1E28-11E4-8C21-0800200C9A66" case timerTick = "6E6C7910-B89E-43A5-78AF-50C5E2B86F7E" case firmwareVersion = "30D99DC9-7C91-4295-A051-0A104D238CF2" + case ledMode = "C6D84241-F1A7-4F9C-A25F-FCE16732F14E" +} + +enum RileyLinkLEDMode: UInt8 { + case off = 0x00 + case on = 0x01 + case auto = 0x02 } @@ -39,7 +46,8 @@ extension PeripheralManager.Configuration { MainServiceCharacteristicUUID.responseCount.cbUUID, MainServiceCharacteristicUUID.customName.cbUUID, MainServiceCharacteristicUUID.timerTick.cbUUID, - MainServiceCharacteristicUUID.firmwareVersion.cbUUID + MainServiceCharacteristicUUID.firmwareVersion.cbUUID, + MainServiceCharacteristicUUID.ledMode.cbUUID ] ], notifyingCharacteristics: [ @@ -127,6 +135,22 @@ extension PeripheralManager { } } + func setLEDMode(mode: RileyLinkLEDMode) { + perform { (manager) in + do { + guard let characteristic = manager.peripheral.getCharacteristicWithUUID(.ledMode) else { + throw PeripheralManagerError.unknownCharacteristic + } + let value = Data([mode.rawValue]) + try manager.writeValue(value, for: characteristic, type: .withResponse, timeout: PeripheralManager.expectedMaxBLELatency) + } catch (let error) { + assertionFailure(String(describing: error)) + } + } + } + + + func startIdleListening(idleTimeout: TimeInterval, channel: UInt8, timeout: TimeInterval = expectedMaxBLELatency, completion: @escaping (_ error: RileyLinkDeviceError?) -> Void) { perform { (manager) in let command = GetPacket(listenChannel: channel, timeoutMS: UInt32(clamping: Int(idleTimeout.milliseconds))) @@ -233,7 +257,7 @@ extension PeripheralManager { throw RileyLinkDeviceError.peripheralManagerError(error) } } - + /// - Throws: /// - RileyLinkDeviceError.invalidResponse /// - RileyLinkDeviceError.peripheralManagerError diff --git a/RileyLinkBLEKit/RileyLinkDevice.swift b/RileyLinkBLEKit/RileyLinkDevice.swift index f3dea9ba3..f1e2c2cd6 100644 --- a/RileyLinkBLEKit/RileyLinkDevice.swift +++ b/RileyLinkBLEKit/RileyLinkDevice.swift @@ -104,6 +104,10 @@ extension RileyLinkDevice { public func setCustomName(_ name: String) { manager.setCustomName(name) } + + public func enableBLELEDs() { + manager.setLEDMode(mode: .on) + } } @@ -310,7 +314,7 @@ extension RileyLinkDevice: PeripheralManagerDelegate { NotificationCenter.default.post(name: .DeviceTimerDidTick, object: self) assertIdleListening(forceRestart: false) - case .customName?, .firmwareVersion?, .none: + case .customName?, .firmwareVersion?, .ledMode?, .none: break } } diff --git a/RileyLinkKit/PumpMessageSender.swift b/RileyLinkKit/PumpMessageSender.swift index 208eed346..fa33ed9a2 100644 --- a/RileyLinkKit/PumpMessageSender.swift +++ b/RileyLinkKit/PumpMessageSender.swift @@ -42,6 +42,9 @@ protocol PumpMessageSender { /// - Throws: LocalizedError func send(_ data: Data, onChannel channel: Int, timeout: TimeInterval) throws + + /// - Throws: LocalizedError + func enableCCLEDs() throws } extension PumpMessageSender { diff --git a/RileyLinkKit/PumpOpsSession.swift b/RileyLinkKit/PumpOpsSession.swift index 3915920c1..ca4c81ae2 100644 --- a/RileyLinkKit/PumpOpsSession.swift +++ b/RileyLinkKit/PumpOpsSession.swift @@ -698,6 +698,10 @@ extension PumpOpsSession { throw PumpOpsError.deviceError(error) } } + + public func enableCCLEDs() throws { + try session.enableCCLEDs() + } /// - Throws: /// - PumpOpsError.deviceError diff --git a/RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift b/RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift index e7c895268..b5835d2fa 100644 --- a/RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift +++ b/RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift @@ -192,6 +192,28 @@ extension CommandResponseViewController { return NSLocalizedString("Reading basal schedule…", comment: "Progress message for reading basal schedule") } } + + static func enableLEDs(ops: PumpOps?, device: RileyLinkDevice) -> T { + return T { (completionHandler) -> String in + device.enableBLELEDs() + ops?.runSession(withName: "Read pump status", using: device) { (session) in + let response: String + do { + try session.enableCCLEDs() + response = "OK" + } catch let error { + response = String(describing: error) + } + + DispatchQueue.main.async { + completionHandler(response) + } + } + + return NSLocalizedString("Enabled Diagnostic LEDs", comment: "Progress message for enabling diagnostic LEDs") + } + } + static func readPumpStatus(ops: PumpOps?, device: RileyLinkDevice, decimalFormatter: NumberFormatter) -> T { return T { (completionHandler) -> String in diff --git a/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift b/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift index b29ae6fdc..6944ffdb0 100644 --- a/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift +++ b/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift @@ -248,6 +248,7 @@ public class RileyLinkDeviceTableViewController: UITableViewController { case pressDownButton case readPumpStatus case readBasalSchedule + case enableLED } private func cellForRow(_ row: DeviceRow) -> UITableViewCell? { @@ -374,7 +375,10 @@ public class RileyLinkDeviceTableViewController: UITableViewController { case .readBasalSchedule: cell.textLabel?.text = NSLocalizedString("Read Basal Schedule", comment: "The title of the command to read basal schedule") -} + + case .enableLED: + cell.textLabel?.text = NSLocalizedString("Enable Diagnostic LEDs", comment: "The title of the command to enable diagnostic LEDs") + } } return cell @@ -448,6 +452,8 @@ public class RileyLinkDeviceTableViewController: UITableViewController { vc = .readPumpStatus(ops: ops, device: device, decimalFormatter: decimalFormatter) case .readBasalSchedule: vc = .readBasalSchedule(ops: ops, device: device, integerFormatter: integerFormatter) + case .enableLED: + vc = .enableLEDs(ops: ops, device: device) } if let cell = tableView.cellForRow(at: indexPath) { From 0ebc46ba71e774430fe5fe86511dae2dacdcd0bc Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 16 Apr 2018 19:19:12 -0500 Subject: [PATCH 04/12] Update test stubs --- RileyLinkKitTests/PumpOpsSynchronousTests.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/RileyLinkKitTests/PumpOpsSynchronousTests.swift b/RileyLinkKitTests/PumpOpsSynchronousTests.swift index f7ddd311e..816fc77c7 100644 --- a/RileyLinkKitTests/PumpOpsSynchronousTests.swift +++ b/RileyLinkKitTests/PumpOpsSynchronousTests.swift @@ -375,6 +375,10 @@ class PumpMessageSenderStub: PumpMessageSender { throw PumpOpsError.noResponse(during: "Tests") } + func enableCCLEDs() throws { + throw PumpOpsError.noResponse(during: "Tests") + } + var responses = [MessageType: [PumpMessage]]() // internal tracking of how many times a response type has been received From 393d906171f1d8cf00e2ce9f62fdfb7600fd5f45 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sat, 5 May 2018 19:01:33 +0200 Subject: [PATCH 05/12] Allow PumpState to be read on PumpOpsSession --- .../ReadSettingsCarelinkMessageBody.swift | 6 +++--- .../AuthenticationViewController.swift | 16 ++++++++++------ .../SettingsTableViewController.swift | 6 +++--- RileyLinkBLEKit/PeripheralManager.swift | 2 +- RileyLinkBLEKit/RileyLinkDevice.swift | 6 +++--- RileyLinkKit/PumpOpsSession.swift | 2 +- .../RileyLinkDeviceTableViewController.swift | 8 -------- 7 files changed, 21 insertions(+), 25 deletions(-) diff --git a/MinimedKit/Messages/ReadSettingsCarelinkMessageBody.swift b/MinimedKit/Messages/ReadSettingsCarelinkMessageBody.swift index bbd59393b..14cc4c0ed 100644 --- a/MinimedKit/Messages/ReadSettingsCarelinkMessageBody.swift +++ b/MinimedKit/Messages/ReadSettingsCarelinkMessageBody.swift @@ -68,14 +68,14 @@ public class ReadSettingsCarelinkMessageBody: CarelinkLongMessageBody { let newer = rxData[0] == 25 // x23 let maxBolusTicks: UInt8 - let maxBasalTicks: Int + let maxBasalTicks: UInt16 if newer { maxBolusTicks = rxData[7] - maxBasalTicks = Int(bigEndianBytes: rxData.subdata(in: 8..<10)) + maxBasalTicks = rxData[8..<10].to(UInt16.self) } else { maxBolusTicks = rxData[6] - maxBasalTicks = Int(bigEndianBytes: rxData.subdata(in: 7..<9)) + maxBasalTicks = rxData[7..<9].to(UInt16.self) } maxBolus = Double(maxBolusTicks) / type(of: self).maxBolusMultiplier maxBasal = Double(maxBasalTicks) / type(of: self).maxBasalMultiplier diff --git a/RileyLink/View Controllers/AuthenticationViewController.swift b/RileyLink/View Controllers/AuthenticationViewController.swift index e9217bccd..d6491ee4e 100644 --- a/RileyLink/View Controllers/AuthenticationViewController.swift +++ b/RileyLink/View Controllers/AuthenticationViewController.swift @@ -30,21 +30,25 @@ class AuthenticationViewController: UITableViewControl }) tableView.reloadSections(IndexSet(integersIn: 0...1), with: .automatic) - authentication.verify { [unowned self] (success, error) in + authentication.verify { [weak self] (success, error) in + guard let strongSelf = self { + return + } + DispatchQueue.main.async { UIView.animate(withDuration: 0.25, animations: { - self.navigationItem.titleView = nil - self.navigationItem.hidesBackButton = false + strongSelf.navigationItem.titleView = nil + strongSelf.navigationItem.hidesBackButton = false }) if success { - self.state = .authorized + strongSelf.state = .authorized } else { if let error = error { - self.presentAlertControllerWithError(error) + strongSelf.presentAlertControllerWithError(error) } - self.state = .unauthorized + strongSelf.state = .unauthorized } } } diff --git a/RileyLink/View Controllers/SettingsTableViewController.swift b/RileyLink/View Controllers/SettingsTableViewController.swift index d858c884e..a584e31c0 100644 --- a/RileyLink/View Controllers/SettingsTableViewController.swift +++ b/RileyLink/View Controllers/SettingsTableViewController.swift @@ -174,10 +174,10 @@ class SettingsTableViewController: UITableViewController, TextFieldTableViewCont case .nightscout: let service = dataManager.remoteDataManager.nightscoutService let vc = AuthenticationViewController(authentication: service) - vc.authenticationObserver = { [unowned self] (service) in - self.dataManager.remoteDataManager.nightscoutService = service + vc.authenticationObserver = { [weak self] (service) in + self?.dataManager.remoteDataManager.nightscoutService = service - self.tableView.reloadRows(at: [indexPath], with: .none) + self?.tableView.reloadRows(at: [indexPath], with: .none) } show(vc, sender: indexPath) diff --git a/RileyLinkBLEKit/PeripheralManager.swift b/RileyLinkBLEKit/PeripheralManager.swift index adda9993e..e6e71dba9 100644 --- a/RileyLinkBLEKit/PeripheralManager.swift +++ b/RileyLinkBLEKit/PeripheralManager.swift @@ -99,7 +99,7 @@ protocol PeripheralManagerDelegate: class { // MARK: - Operation sequence management extension PeripheralManager { func configureAndRun(_ block: @escaping (_ manager: PeripheralManager) -> Void) -> (() -> Void) { - return { [unowned self] in + return { if !self.needsConfiguration && self.peripheral.services == nil { self.log.error("Configured peripheral has no services. Reconfiguring…") } diff --git a/RileyLinkBLEKit/RileyLinkDevice.swift b/RileyLinkBLEKit/RileyLinkDevice.swift index f1e2c2cd6..2571d8c69 100644 --- a/RileyLinkBLEKit/RileyLinkDevice.swift +++ b/RileyLinkBLEKit/RileyLinkDevice.swift @@ -66,10 +66,10 @@ public class RileyLinkDevice { peripheralManager.delegate = self - sessionQueueOperationCountObserver = sessionQueue.observe(\.operationCount, options: [.new]) { [unowned self] (queue, change) in + sessionQueueOperationCountObserver = sessionQueue.observe(\.operationCount, options: [.new]) { [weak self] (queue, change) in if let newValue = change.newValue, newValue == 0 { - self.log.debug("Session queue operation count is now empty") - self.assertIdleListening(forceRestart: true) + self?.log.debug("Session queue operation count is now empty") + self?.assertIdleListening(forceRestart: true) } } } diff --git a/RileyLinkKit/PumpOpsSession.swift b/RileyLinkKit/PumpOpsSession.swift index ca4c81ae2..ee5cec13e 100644 --- a/RileyLinkKit/PumpOpsSession.swift +++ b/RileyLinkKit/PumpOpsSession.swift @@ -18,7 +18,7 @@ protocol PumpOpsSessionDelegate: class { public class PumpOpsSession { - private var pump: PumpState { + private(set) public var pump: PumpState { didSet { delegate.pumpOpsSession(self, didChange: pump) } diff --git a/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift b/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift index 6944ffdb0..e576cbf86 100644 --- a/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift +++ b/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift @@ -123,14 +123,6 @@ public class RileyLinkDeviceTableViewController: UITableViewController { } } - private var deviceObserver: Any? { - willSet { - if let observer = deviceObserver { - NotificationCenter.default.removeObserver(observer) - } - } - } - private func observe() { let center = NotificationCenter.default let mainQueue = OperationQueue.main From 1c9a95f3237d129a2c62e895064204570bd1d833 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sat, 5 May 2018 19:12:37 +0200 Subject: [PATCH 06/12] Fix syntax error --- RileyLink/View Controllers/AuthenticationViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RileyLink/View Controllers/AuthenticationViewController.swift b/RileyLink/View Controllers/AuthenticationViewController.swift index d6491ee4e..e4032fc04 100644 --- a/RileyLink/View Controllers/AuthenticationViewController.swift +++ b/RileyLink/View Controllers/AuthenticationViewController.swift @@ -31,7 +31,7 @@ class AuthenticationViewController: UITableViewControl tableView.reloadSections(IndexSet(integersIn: 0...1), with: .automatic) authentication.verify { [weak self] (success, error) in - guard let strongSelf = self { + guard let strongSelf = self else { return } From 224bd4a48f6c1e392e0c9d768a34b100639b42cb Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 9 May 2018 19:39:21 -0500 Subject: [PATCH 07/12] pull in the new Data methods from omnikit, as well as the new CommandResponseViewController changes from LoopKit to improve sharing --- Common/{NSData.swift => Data.swift} | 21 ++++++++ .../ReadSettingsCarelinkMessageBody.swift | 4 +- RileyLink.xcodeproj/project.pbxproj | 30 ++++++------ RileyLinkBLEKit/Command.swift | 13 +---- RileyLinkBLEKit/CommandSession.swift | 4 +- RileyLinkKit/PumpOpsError.swift | 18 +++++++ RileyLinkKit/PumpOpsSession.swift | 9 +++- .../CommandResponseViewController.swift | 48 +++++++++++++++++-- 8 files changed, 110 insertions(+), 37 deletions(-) rename Common/{NSData.swift => Data.swift} (71%) diff --git a/Common/NSData.swift b/Common/Data.swift similarity index 71% rename from Common/NSData.swift rename to Common/Data.swift index c5cc9a66b..bde0d1d42 100644 --- a/Common/NSData.swift +++ b/Common/Data.swift @@ -15,6 +15,27 @@ extension Data { return T(littleEndian: bytes.pointee) } } + + func toBigEndian(_: T.Type) -> T { + return self.withUnsafeBytes { + return T(bigEndian: $0.pointee) + } + } + + mutating func append(_ newElement: T) { + var element = newElement.littleEndian + append(UnsafeBufferPointer(start: &element, count: 1)) + } + + mutating func appendBigEndian(_ newElement: T) { + var element = newElement.bigEndian + append(UnsafeBufferPointer(start: &element, count: 1)) + } + + init(_ value: T) { + var value = value.littleEndian + self.init(buffer: UnsafeBufferPointer(start: &value, count: 1)) + } } // String conversion methods, adapted from https://stackoverflow.com/questions/40276322/hex-binary-string-conversion-in-swift/40278391#40278391 diff --git a/MinimedKit/Messages/ReadSettingsCarelinkMessageBody.swift b/MinimedKit/Messages/ReadSettingsCarelinkMessageBody.swift index 14cc4c0ed..46f860d11 100644 --- a/MinimedKit/Messages/ReadSettingsCarelinkMessageBody.swift +++ b/MinimedKit/Messages/ReadSettingsCarelinkMessageBody.swift @@ -72,10 +72,10 @@ public class ReadSettingsCarelinkMessageBody: CarelinkLongMessageBody { if newer { maxBolusTicks = rxData[7] - maxBasalTicks = rxData[8..<10].to(UInt16.self) + maxBasalTicks = rxData[8..<10].toBigEndian(UInt16.self) } else { maxBolusTicks = rxData[6] - maxBasalTicks = rxData[7..<9].to(UInt16.self) + maxBasalTicks = rxData[7..<9].toBigEndian(UInt16.self) } maxBolus = Double(maxBolusTicks) / type(of: self).maxBolusMultiplier maxBasal = Double(maxBasalTicks) / type(of: self).maxBasalMultiplier diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index af4a1e51e..fdeda4016 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -17,8 +17,8 @@ 2FDE1A071E57B12D00B56A27 /* ReadCurrentPageNumberMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FDE1A061E57B12D00B56A27 /* ReadCurrentPageNumberMessageBody.swift */; }; 43047FC41FAEC70600508343 /* RadioFirmwareVersionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43047FC31FAEC70600508343 /* RadioFirmwareVersionTests.swift */; }; 43047FC61FAEC83000508343 /* RFPacketTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43047FC51FAEC83000508343 /* RFPacketTests.swift */; }; - 43047FC71FAEC9BC00508343 /* NSData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BA1C826B92006DBA60 /* NSData.swift */; }; - 43047FC91FAECA8700508343 /* NSData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BA1C826B92006DBA60 /* NSData.swift */; }; + 43047FC71FAEC9BC00508343 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BA1C826B92006DBA60 /* Data.swift */; }; + 43047FC91FAECA8700508343 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BA1C826B92006DBA60 /* Data.swift */; }; 431CE7781F98564200255374 /* RileyLinkBLEKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 431CE76F1F98564100255374 /* RileyLinkBLEKit.framework */; }; 431CE7811F98564200255374 /* RileyLinkBLEKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 431CE7711F98564100255374 /* RileyLinkBLEKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 431CE7841F98564200255374 /* RileyLinkBLEKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 431CE76F1F98564100255374 /* RileyLinkBLEKit.framework */; }; @@ -52,7 +52,7 @@ 434AB0961CBA0DF600422F4A /* PumpOps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434AB0921CBA0DF600422F4A /* PumpOps.swift */; }; 434AB0971CBA0DF600422F4A /* PumpOpsSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434AB0931CBA0DF600422F4A /* PumpOpsSession.swift */; }; 434AB0981CBA0DF600422F4A /* PumpState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434AB0941CBA0DF600422F4A /* PumpState.swift */; }; - 434AB0C71CBCB76400422F4A /* NSData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BA1C826B92006DBA60 /* NSData.swift */; }; + 434AB0C71CBCB76400422F4A /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BA1C826B92006DBA60 /* Data.swift */; }; 434FF1DC1CF268BD000DB779 /* IdentifiableClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431185AE1CF25A590059ED98 /* IdentifiableClass.swift */; }; 434FF1DE1CF268F3000DB779 /* RileyLinkDeviceTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434FF1DD1CF268F3000DB779 /* RileyLinkDeviceTableViewCell.swift */; }; 435535D61FB6D98400CE5A23 /* UserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435535D51FB6D98400CE5A23 /* UserDefaults.swift */; }; @@ -69,13 +69,13 @@ 437462391FA9287A00643383 /* RileyLinkDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437462381FA9287A00643383 /* RileyLinkDevice.swift */; }; 437F54071FBD52120070FF2C /* DeviceState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437F54061FBD52120070FF2C /* DeviceState.swift */; }; 437F54091FBF9E0A0070FF2C /* RileyLinkDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437F54081FBF9E0A0070FF2C /* RileyLinkDevice.swift */; }; - 437F540A1FBFDAA60070FF2C /* NSData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BA1C826B92006DBA60 /* NSData.swift */; }; + 437F540A1FBFDAA60070FF2C /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BA1C826B92006DBA60 /* Data.swift */; }; 4384C8C61FB92F8100D916E6 /* HistoryPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4384C8C51FB92F8100D916E6 /* HistoryPage.swift */; }; 4384C8C81FB937E500D916E6 /* PumpSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4384C8C71FB937E500D916E6 /* PumpSettings.swift */; }; 4384C8C91FB941FB00D916E6 /* TimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EBE4501EAD238C0073A0B5 /* TimeInterval.swift */; }; 438D39221D19011700D40CA4 /* PlaceholderPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 438D39211D19011700D40CA4 /* PlaceholderPumpEvent.swift */; }; 43A068EC1CF6BA6900F9EFE4 /* ReadRemainingInsulinMessageBodyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43A068EB1CF6BA6900F9EFE4 /* ReadRemainingInsulinMessageBodyTests.swift */; }; - 43A9E50E1F6B865000307931 /* NSData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BA1C826B92006DBA60 /* NSData.swift */; }; + 43A9E50E1F6B865000307931 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BA1C826B92006DBA60 /* Data.swift */; }; 43B0ADC01D0FC03200AAD278 /* NSDateComponentsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43B0ADBF1D0FC03200AAD278 /* NSDateComponentsTests.swift */; }; 43B0ADC21D12454700AAD278 /* TimestampedHistoryEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43B0ADC11D12454700AAD278 /* TimestampedHistoryEvent.swift */; }; 43B0ADC41D12506A00AAD278 /* NSDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43B0ADC31D12506A00AAD278 /* NSDateFormatter.swift */; }; @@ -340,7 +340,7 @@ C1EAD6B61C826B6D006DBA60 /* PacketType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6B11C826B6D006DBA60 /* PacketType.swift */; }; C1EAD6B71C826B6D006DBA60 /* PumpMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6B21C826B6D006DBA60 /* PumpMessage.swift */; }; C1EAD6C51C826B92006DBA60 /* Int.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6B91C826B92006DBA60 /* Int.swift */; }; - C1EAD6C61C826B92006DBA60 /* NSData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BA1C826B92006DBA60 /* NSData.swift */; }; + C1EAD6C61C826B92006DBA60 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BA1C826B92006DBA60 /* Data.swift */; }; C1EAD6C71C826B92006DBA60 /* NSDateComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BB1C826B92006DBA60 /* NSDateComponents.swift */; }; C1EAD6C81C826B92006DBA60 /* CarelinkMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BD1C826B92006DBA60 /* CarelinkMessageBody.swift */; }; C1EAD6C91C826B92006DBA60 /* MySentryAckMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BE1C826B92006DBA60 /* MySentryAckMessageBody.swift */; }; @@ -833,7 +833,7 @@ C1EAD6B11C826B6D006DBA60 /* PacketType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PacketType.swift; sourceTree = ""; }; C1EAD6B21C826B6D006DBA60 /* PumpMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpMessage.swift; sourceTree = ""; }; C1EAD6B91C826B92006DBA60 /* Int.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Int.swift; sourceTree = ""; }; - C1EAD6BA1C826B92006DBA60 /* NSData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSData.swift; sourceTree = ""; }; + C1EAD6BA1C826B92006DBA60 /* Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; C1EAD6BB1C826B92006DBA60 /* NSDateComponents.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSDateComponents.swift; sourceTree = ""; }; C1EAD6BD1C826B92006DBA60 /* CarelinkMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CarelinkMessageBody.swift; sourceTree = ""; }; C1EAD6BE1C826B92006DBA60 /* MySentryAckMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MySentryAckMessageBody.swift; sourceTree = ""; }; @@ -1084,10 +1084,10 @@ 43EBE44F1EAD234F0073A0B5 /* Common */ = { isa = PBXGroup; children = ( + C1EAD6BA1C826B92006DBA60 /* Data.swift */, 431185AE1CF25A590059ED98 /* IdentifiableClass.swift */, - 431CE7941F9B0DAE00255374 /* OSLog.swift */, - C1EAD6BA1C826B92006DBA60 /* NSData.swift */, 43323EA61FA81A0F003FB0FA /* NumberFormatter.swift */, + 431CE7941F9B0DAE00255374 /* OSLog.swift */, 43EBE4501EAD238C0073A0B5 /* TimeInterval.swift */, 4345D1CD1DA16AF300BAAD22 /* TimeZone.swift */, ); @@ -2090,7 +2090,7 @@ 432847C31FA57C0F00CDE69C /* RadioFirmwareVersion.swift in Sources */, 431CE7931F985DE700255374 /* PeripheralManager+RileyLink.swift in Sources */, 431CE79A1F9B0F1600255374 /* OSLog.swift in Sources */, - 43047FC91FAECA8700508343 /* NSData.swift in Sources */, + 43047FC91FAECA8700508343 /* Data.swift in Sources */, 431CE7A51F9D78F500255374 /* RFPacket.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2101,7 +2101,7 @@ files = ( 4322B75620282DA60002837D /* ResponseBufferTests.swift in Sources */, 43047FC41FAEC70600508343 /* RadioFirmwareVersionTests.swift in Sources */, - 43047FC71FAEC9BC00508343 /* NSData.swift in Sources */, + 43047FC71FAEC9BC00508343 /* Data.swift in Sources */, 43047FC61FAEC83000508343 /* RFPacketTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2116,7 +2116,7 @@ 43EBE4531EAD23CE0073A0B5 /* TimeInterval.swift in Sources */, 436CCEF21FB953E800A6822B /* CommandSession.swift in Sources */, C1A721601EC29C0B0080FAD7 /* PumpOpsError.swift in Sources */, - 434AB0C71CBCB76400422F4A /* NSData.swift in Sources */, + 434AB0C71CBCB76400422F4A /* Data.swift in Sources */, 4384C8C61FB92F8100D916E6 /* HistoryPage.swift in Sources */, 434AB0981CBA0DF600422F4A /* PumpState.swift in Sources */, 431CE7961F9B0F0200255374 /* OSLog.swift in Sources */, @@ -2135,7 +2135,7 @@ files = ( 2F962EBF1E678BAA0070EFBD /* PumpOpsSynchronousTests.swift in Sources */, 4384C8C91FB941FB00D916E6 /* TimeInterval.swift in Sources */, - 43A9E50E1F6B865000307931 /* NSData.swift in Sources */, + 43A9E50E1F6B865000307931 /* Data.swift in Sources */, 2F962EC51E705C6E0070EFBD /* PumpOpsSynchronousBuildFromFramesTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2285,7 +2285,7 @@ C1842C001C8FA45100DB42AC /* JournalEntryPumpLowReservoirPumpEvent.swift in Sources */, 54A840D11DB85D0600B1F202 /* UnknownGlucoseEvent.swift in Sources */, C1842BCF1C8F9E5100DB42AC /* PumpAlarmPumpEvent.swift in Sources */, - C1EAD6C61C826B92006DBA60 /* NSData.swift in Sources */, + C1EAD6C61C826B92006DBA60 /* Data.swift in Sources */, C1842C211C8FA45100DB42AC /* ChangeAlarmNotifyModePumpEvent.swift in Sources */, C1842BC31C8E931E00DB42AC /* BolusNormalPumpEvent.swift in Sources */, 541688DD1DB82213005B1891 /* ReadCurrentGlucosePageMessageBody.swift in Sources */, @@ -2378,7 +2378,7 @@ C14FFC5E1D3D75200049CF85 /* ButtonTableViewCell.swift in Sources */, 43EBE4551EAD24410073A0B5 /* TimeInterval.swift in Sources */, C14FFC691D3D7E560049CF85 /* KeychainManager+RileyLink.swift in Sources */, - 437F540A1FBFDAA60070FF2C /* NSData.swift in Sources */, + 437F540A1FBFDAA60070FF2C /* Data.swift in Sources */, C14FFC511D3D6DEF0049CF85 /* ServiceCredential.swift in Sources */, C14FFC5B1D3D74F90049CF85 /* NibLoadable.swift in Sources */, C14FFC611D3D75470049CF85 /* UIColor.swift in Sources */, diff --git a/RileyLinkBLEKit/Command.swift b/RileyLinkBLEKit/Command.swift index 68bc60735..6484176ac 100644 --- a/RileyLinkBLEKit/Command.swift +++ b/RileyLinkBLEKit/Command.swift @@ -244,7 +244,7 @@ struct SetSoftwareEncoding: Command { return Data(bytes: [ RileyLinkCommand.setSWEncoding.rawValue, encodingType.rawValue - ]) + ]) } } @@ -266,7 +266,7 @@ struct SetPreamble: Command { } } -struct SetLedMode: Command { +struct SetLEDMode: Command { typealias ResponseType = CodeResponse let led: RileyLinkLEDType @@ -291,12 +291,3 @@ struct ResetRadioConfig: Command { return Data(bytes: [RileyLinkCommand.resetRadioConfig.rawValue]) } } - - -// MARK: - Helpers -extension Data { - fileprivate mutating func appendBigEndian(_ newElement: T) { - var element = newElement.byteSwapped - append(UnsafeBufferPointer(start: &element, count: 1)) - } -} diff --git a/RileyLinkBLEKit/CommandSession.swift b/RileyLinkBLEKit/CommandSession.swift index b4c710d5f..1940ab4a1 100644 --- a/RileyLinkBLEKit/CommandSession.swift +++ b/RileyLinkBLEKit/CommandSession.swift @@ -109,9 +109,9 @@ public struct CommandSession { /// - Throws: RileyLinkDeviceError public func enableCCLEDs() throws { - let enableBlue = SetLedMode(.blue, mode: .auto) + let enableBlue = SetLEDMode(.blue, mode: .auto) _ = try writeCommand(enableBlue, timeout: 0) - let enableGreen = SetLedMode(.green, mode: .auto) + let enableGreen = SetLEDMode(.green, mode: .auto) _ = try writeCommand(enableGreen, timeout: 0) } diff --git a/RileyLinkKit/PumpOpsError.swift b/RileyLinkKit/PumpOpsError.swift index 153de1e07..be72427f0 100644 --- a/RileyLinkKit/PumpOpsError.swift +++ b/RileyLinkKit/PumpOpsError.swift @@ -114,6 +114,15 @@ extension PumpOpsError: LocalizedError { extension PumpCommandError: LocalizedError { + public var errorDescription: String? { + switch self { + case .arguments(let error): + return error.errorDescription + case .command(let error): + return error.errorDescription + } + } + public var failureReason: String? { switch self { case .arguments(let error): @@ -122,4 +131,13 @@ extension PumpCommandError: LocalizedError { return error.failureReason } } + + public var recoverySuggestion: String? { + switch self { + case .arguments(let error): + return error.recoverySuggestion + case .command(let error): + return error.recoverySuggestion + } + } } diff --git a/RileyLinkKit/PumpOpsSession.swift b/RileyLinkKit/PumpOpsSession.swift index ee5cec13e..afbabc45c 100644 --- a/RileyLinkKit/PumpOpsSession.swift +++ b/RileyLinkKit/PumpOpsSession.swift @@ -698,9 +698,14 @@ extension PumpOpsSession { throw PumpOpsError.deviceError(error) } } - + + /// - Throws: PumpOpsError.deviceError public func enableCCLEDs() throws { - try session.enableCCLEDs() + do { + try session.enableCCLEDs() + } catch let error as LocalizedError { + throw PumpOpsError.deviceError(error) + } } /// - Throws: diff --git a/RileyLinkKitUI/CommandResponseViewController.swift b/RileyLinkKitUI/CommandResponseViewController.swift index cee94644d..a7e6db85a 100644 --- a/RileyLinkKitUI/CommandResponseViewController.swift +++ b/RileyLinkKitUI/CommandResponseViewController.swift @@ -7,6 +7,7 @@ // import UIKit +import os.log class CommandResponseViewController: UIViewController { @@ -22,6 +23,10 @@ class CommandResponseViewController: UIViewController { fatalError("init(coder:) has not been implemented") } + public var fileName: String? + + private let uuid = UUID() + private let command: Command private lazy var textView = UITextView() @@ -57,22 +62,55 @@ class CommandResponseViewController: UIViewController { } @objc func shareText(_: AnyObject?) { - let activityVC = UIActivityViewController(activityItems: [self], applicationActivities: nil) + let title = fileName ?? "\(self.title ?? uuid.uuidString).txt" + + guard let item = SharedResponse(text: textView.text, title: title) else { + return + } + + let activityVC = UIActivityViewController(activityItems: [item], applicationActivities: nil) present(activityVC, animated: true, completion: nil) } } -extension CommandResponseViewController: UIActivityItemSource { + +private class SharedResponse: NSObject, UIActivityItemSource { + + let title: String + let fileURL: URL + + init?(text: String, title: String) { + self.title = title + + var url = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true) + url.appendPathComponent(title, isDirectory: false) + + do { + try text.write(to: url, atomically: true, encoding: .utf8) + } catch let error { + os_log("Failed to write to file %{public}@: %{public}@", log: .default, type: .error, title, String(describing: error)) + return nil + } + + fileURL = url + + super.init() + } + public func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any { - return title ?? textView.text ?? "" + return fileURL } public func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivityType?) -> Any? { - return textView.attributedText ?? "" + return fileURL } public func activityViewController(_ activityViewController: UIActivityViewController, subjectForActivityType activityType: UIActivityType?) -> String { - return title ?? textView.text + return title + } + + public func activityViewController(_ activityViewController: UIActivityViewController, dataTypeIdentifierForActivityType activityType: UIActivityType?) -> String { + return "public.utf8-plain-text" } } From 3a57ddcd26db8d9291ab2a425a0b54bf87158574 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 23 May 2018 23:26:44 -0500 Subject: [PATCH 08/12] Updates for decoupling NS from MM (#393) --- MinimedKit/BatteryChemistryType.swift | 4 ++-- .../Treatments/TempBasalNightscoutTreatment.swift | 4 ++-- RileyLink/DeviceDataManager.swift | 2 +- RileyLinkBLEKit/RileyLinkDevice.swift | 4 ++-- RileyLinkKit/PumpOpsSession.swift | 6 +++--- .../CommandResponseViewController+RileyLinkDevice.swift | 6 +++--- RileyLinkKitUI/RileyLinkDeviceTableViewController.swift | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/MinimedKit/BatteryChemistryType.swift b/MinimedKit/BatteryChemistryType.swift index 075afdb82..30a047835 100644 --- a/MinimedKit/BatteryChemistryType.swift +++ b/MinimedKit/BatteryChemistryType.swift @@ -39,8 +39,8 @@ public enum BatteryChemistryType: Int, CustomStringConvertible { } } - public func chargeRemaining(voltage: Double) -> Double { - let computed = (voltage - self.minVoltage)/(self.maxVoltage - self.minVoltage) + public func chargeRemaining(at voltage: Measurement) -> Double { + let computed = (voltage.converted(to: .volts).value - self.minVoltage)/(self.maxVoltage - self.minVoltage) return max(min(computed, 1), 0) } } diff --git a/NightscoutUploadKit/Treatments/TempBasalNightscoutTreatment.swift b/NightscoutUploadKit/Treatments/TempBasalNightscoutTreatment.swift index 225d998f3..6e5204908 100644 --- a/NightscoutUploadKit/Treatments/TempBasalNightscoutTreatment.swift +++ b/NightscoutUploadKit/Treatments/TempBasalNightscoutTreatment.swift @@ -10,7 +10,7 @@ import Foundation public class TempBasalNightscoutTreatment: NightscoutTreatment { - enum RateType: String { + public enum RateType: String { case Absolute = "absolute" case Percentage = "percentage" } @@ -21,7 +21,7 @@ public class TempBasalNightscoutTreatment: NightscoutTreatment { let temp: RateType let duration: Int - init(timestamp: Date, enteredBy: String, temp: RateType, rate: Double, absolute: Double?, duration: Int) { + public init(timestamp: Date, enteredBy: String, temp: RateType, rate: Double, absolute: Double?, duration: Int) { self.rate = rate self.absolute = absolute self.temp = temp diff --git a/RileyLink/DeviceDataManager.swift b/RileyLink/DeviceDataManager.swift index b3ac36bf3..5b6d3b457 100644 --- a/RileyLink/DeviceDataManager.swift +++ b/RileyLink/DeviceDataManager.swift @@ -256,7 +256,7 @@ class DeviceDataManager { let status = try session.getCurrentPumpStatus() DispatchQueue.main.async { self.latestPolledPumpStatus = status - let battery = BatteryStatus(voltage: status.batteryVolts, status: BatteryIndicator(batteryStatus: status.batteryStatus)) + let battery = BatteryStatus(voltage: status.batteryVolts.converted(to: .volts).value, status: BatteryIndicator(batteryStatus: status.batteryStatus)) guard let date = status.clock.date else { print("Could not interpret clock") return diff --git a/RileyLinkBLEKit/RileyLinkDevice.swift b/RileyLinkBLEKit/RileyLinkDevice.swift index 2571d8c69..461fc388b 100644 --- a/RileyLinkBLEKit/RileyLinkDevice.swift +++ b/RileyLinkBLEKit/RileyLinkDevice.swift @@ -16,10 +16,10 @@ public class RileyLinkDevice { private let log = OSLog(category: "RileyLinkDevice") // Confined to `manager.queue` - private(set) var bleFirmwareVersion: BLEFirmwareVersion? + private var bleFirmwareVersion: BLEFirmwareVersion? // Confined to `manager.queue` - private(set) var radioFirmwareVersion: RadioFirmwareVersion? + private var radioFirmwareVersion: RadioFirmwareVersion? // Confined to `queue` private var idleListeningState: IdleListeningState = .disabled { diff --git a/RileyLinkKit/PumpOpsSession.swift b/RileyLinkKit/PumpOpsSession.swift index afbabc45c..8e5249560 100644 --- a/RileyLinkKit/PumpOpsSession.swift +++ b/RileyLinkKit/PumpOpsSession.swift @@ -23,7 +23,7 @@ public class PumpOpsSession { delegate.pumpOpsSession(self, didChange: pump) } } - private let settings: PumpSettings + public let settings: PumpSettings private let session: PumpMessageSender private unowned let delegate: PumpOpsSessionDelegate @@ -252,7 +252,7 @@ extension PumpOpsSession { public struct PumpStatus { // Date components read from the pump, along with PumpState.timeZone public let clock: DateComponents - public let batteryVolts: Double + public let batteryVolts: Measurement public let batteryStatus: BatteryStatus public let suspended: Bool public let bolusing: Bool @@ -305,7 +305,7 @@ extension PumpOpsSession { return PumpStatus( clock: clock, - batteryVolts: battResp.volts, + batteryVolts: Measurement(value: battResp.volts, unit: UnitElectricPotentialDifference.volts), batteryStatus: battResp.status, suspended: status.suspended, bolusing: status.bolusing, diff --git a/RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift b/RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift index b5835d2fa..d84940e8c 100644 --- a/RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift +++ b/RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift @@ -215,15 +215,15 @@ extension CommandResponseViewController { } - static func readPumpStatus(ops: PumpOps?, device: RileyLinkDevice, decimalFormatter: NumberFormatter) -> T { + static func readPumpStatus(ops: PumpOps?, device: RileyLinkDevice, measurementFormatter: MeasurementFormatter) -> T { return T { (completionHandler) -> String in ops?.runSession(withName: "Read pump status", using: device) { (session) in let response: String do { let status = try session.getCurrentPumpStatus() - var str = String(format: NSLocalizedString("%1$@ Units of insulin remaining\n", comment: "The format string describing units of insulin remaining: (1: number of units)"), decimalFormatter.string(from: NSNumber(value: status.reservoir))!) - str += String(format: NSLocalizedString("Battery: %1$@ volts\n", comment: "The format string describing pump battery voltage: (1: battery voltage)"), decimalFormatter.string(from: NSNumber(value: status.batteryVolts))!) + var str = String(format: NSLocalizedString("%1$@ Units of insulin remaining\n", comment: "The format string describing units of insulin remaining: (1: number of units)"), measurementFormatter.numberFormatter.string(from: NSNumber(value: status.reservoir))!) + str += String(format: NSLocalizedString("Battery: %1$@ volts\n", comment: "The format string describing pump battery voltage: (1: battery voltage)"), measurementFormatter.string(from: status.batteryVolts)) str += String(format: NSLocalizedString("Suspended: %1$@\n", comment: "The format string describing pump suspended state: (1: suspended)"), String(describing: status.suspended)) str += String(format: NSLocalizedString("Bolusing: %1$@\n", comment: "The format string describing pump bolusing state: (1: bolusing)"), String(describing: status.bolusing)) response = str diff --git a/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift b/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift index e576cbf86..e97b6a0b9 100644 --- a/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift +++ b/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift @@ -441,7 +441,7 @@ public class RileyLinkDeviceTableViewController: UITableViewController { case .pressDownButton: vc = .pressDownButton(ops: ops, device: device) case .readPumpStatus: - vc = .readPumpStatus(ops: ops, device: device, decimalFormatter: decimalFormatter) + vc = .readPumpStatus(ops: ops, device: device, measurementFormatter: measurementFormatter) case .readBasalSchedule: vc = .readBasalSchedule(ops: ops, device: device, integerFormatter: integerFormatter) case .enableLED: From d127771ba1724672819d9c060259adaab2e16af3 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 28 May 2018 06:39:42 -0500 Subject: [PATCH 09/12] Add messages for checking MySentry pairing status (#394) --- MinimedKit/MessageType.swift | 16 ++++++++ .../ReadOtherDevicesIDsMessageBody.swift | 40 +++++++++++++++++++ .../ReadOtherDevicesStatusMessageBody.swift | 26 ++++++++++++ .../Messages/ReadPumpStatusMessageBody.swift | 4 +- .../ReadOtherDevicesIDsMessageBodyTests.swift | 37 +++++++++++++++++ NightscoutUploadKit/NightscoutUploader.swift | 15 ++++++- RileyLink.xcodeproj/project.pbxproj | 32 ++++++++++----- RileyLinkBLEKit/PeripheralManager.swift | 4 +- RileyLinkBLEKit/RileyLinkDevice.swift | 4 +- RileyLinkKit/PumpOpsSession.swift | 30 ++++++++++++-- ...sponseViewController+RileyLinkDevice.swift | 15 ++++++- .../RileyLinkDeviceTableViewController.swift | 6 +++ 12 files changed, 208 insertions(+), 21 deletions(-) create mode 100644 MinimedKit/Messages/ReadOtherDevicesIDsMessageBody.swift create mode 100644 MinimedKit/Messages/ReadOtherDevicesStatusMessageBody.swift create mode 100644 MinimedKitTests/Messages/ReadOtherDevicesIDsMessageBodyTests.swift diff --git a/MinimedKit/MessageType.swift b/MinimedKit/MessageType.swift index 1704ea4a8..df3580e03 100644 --- a/MinimedKit/MessageType.swift +++ b/MinimedKit/MessageType.swift @@ -17,6 +17,9 @@ public enum MessageType: UInt8 { case deviceLink = 0x0A case errorResponse = 0x15 case writeGlucoseHistoryTimestamp = 0x28 + + case readRemoteControlID = 0x2e // Refused by x23 pumps + case changeTime = 0x40 case bolus = 0x42 @@ -67,6 +70,15 @@ public enum MessageType: UInt8 { case readSettings = 0xc0 case readCurrentGlucosePage = 0xcd case readPumpStatus = 0xce + + case unknown_e2 = 0xe2 // a7594040e214190226330000000000021f99011801e00103012c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + case unknown_e6 = 0xe6 // a7594040e60200190000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + case settingsChangeCounter = 0xec // Body[3] increments by 1 after changing certain settings 0200af0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + case readOtherDevicesIDs = 0xf0 + case readCaptureEventEnabled = 0xf1 // Body[1] encodes the bool state 0101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + case changeCaptureEventEnable = 0xf2 + case readOtherDevicesStatus = 0xf3 var bodyType: MessageBody.Type { switch self { @@ -114,6 +126,10 @@ public enum MessageType: UInt8 { return GetGlucosePageMessageBody.self case .errorResponse: return PumpErrorMessageBody.self + case .readOtherDevicesIDs: + return ReadOtherDevicesIDsMessageBody.self + case .readOtherDevicesStatus: + return ReadOtherDevicesStatusMessageBody.self default: return UnknownMessageBody.self } diff --git a/MinimedKit/Messages/ReadOtherDevicesIDsMessageBody.swift b/MinimedKit/Messages/ReadOtherDevicesIDsMessageBody.swift new file mode 100644 index 000000000..9e266628b --- /dev/null +++ b/MinimedKit/Messages/ReadOtherDevicesIDsMessageBody.swift @@ -0,0 +1,40 @@ +// +// ReadOtherDevicesIDsMessageBody.swift +// MinimedKit +// +// Copyright © 2018 Pete Schwamb. All rights reserved. +// + +import Foundation + + +public class ReadOtherDevicesIDsMessageBody: CarelinkLongMessageBody { + + let ids: [Data] + + public required init?(rxData: Data) { + guard rxData.count == type(of: self).length else { + return nil + } + + let count = Int(rxData[1]) + + var ids: [Data] = [] + + for index in stride(from: 0, to: count, by: 1) { + let start = (index * 5 + 3) + let end = start + 4 + + ids.append(rxData.subdata(in: start.. 0 - suspended = (rxData[3] as UInt8) > 0 + bolusing = rxData[2] > 0 + suspended = rxData[3] > 0 super.init(rxData: rxData) } diff --git a/MinimedKitTests/Messages/ReadOtherDevicesIDsMessageBodyTests.swift b/MinimedKitTests/Messages/ReadOtherDevicesIDsMessageBodyTests.swift new file mode 100644 index 000000000..2e3e478f7 --- /dev/null +++ b/MinimedKitTests/Messages/ReadOtherDevicesIDsMessageBodyTests.swift @@ -0,0 +1,37 @@ +// +// ReadOtherDevicesIDsMessageBodyTests.swift +// MinimedKitTests +// +// Copyright © 2018 Pete Schwamb. All rights reserved. +// + +import XCTest +@testable import MinimedKit + +class ReadOtherDevicesIDsMessageBodyTests: XCTestCase { + + func test0IDs() { + let message = PumpMessage(rxData: Data(hexadecimalString: "a7594040f01f0015036800406001070636036f0040600107062f1dfc004020c107062f0e77000000000000000000000000000000000000000000000000000000000000000000")!) + let body = message?.messageBody as! ReadOtherDevicesIDsMessageBody + + XCTAssertEqual(0, body.ids.count) + } + + func test1IDs() { + let message = PumpMessage(rxData: Data(hexadecimalString: "a7594040f01f0101a21057280000000636036f0040600107062f1dfc004020c107062f0e77000000000000000000000000000000000000000000000000000000000000000000")!) + let body = message?.messageBody as! ReadOtherDevicesIDsMessageBody + + XCTAssertEqual(1, body.ids.count) + XCTAssertEqual("a2105728", body.ids[0].hexadecimalString) + } + + func test2IDs() { + let message = PumpMessage(rxData: Data(hexadecimalString: "a7594040f01f0201a210572800a2016016036f0040600107062f1dfc004020c107062f0e77000000000000000000000000000000000000000000000000000000000000000000")!) + let body = message?.messageBody as! ReadOtherDevicesIDsMessageBody + + XCTAssertEqual(2, body.ids.count) + XCTAssertEqual("a2105728", body.ids[0].hexadecimalString) + XCTAssertEqual("a2016016", body.ids[1].hexadecimalString) + } + +} diff --git a/NightscoutUploadKit/NightscoutUploader.swift b/NightscoutUploadKit/NightscoutUploader.swift index d159b124c..63c8499cd 100644 --- a/NightscoutUploadKit/NightscoutUploader.swift +++ b/NightscoutUploadKit/NightscoutUploader.swift @@ -216,13 +216,26 @@ public class NightscoutUploader { case .flat: return "Flat" } - }() + }() let entry = NightscoutEntry(glucose: glucose, timestamp: sensorDate, device: device, glucoseType: .Sensor, previousSGV: previousSGV, previousSGVNotActive: previousSGVNotActive, direction: direction) entries.append(entry) } flushAll() } + + public func uploadSGV(glucoseMGDL: Int, at date: Date, direction: String?, device: String) { + let entry = NightscoutEntry( + glucose: glucoseMGDL, + timestamp: date, + device: device, + glucoseType: .Sensor, + previousSGV: nil, + previousSGVNotActive: nil, + direction: direction + ) + entries.append(entry) + } public func handleMeterMessage(_ msg: MeterMessage) { diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index fdeda4016..9b8280e9e 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -119,6 +119,9 @@ 43D5E7A21FAF7CF2004ACDB7 /* CaseCountable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1C659181E16BA9D0025CC58 /* CaseCountable.swift */; }; 43D5E7A31FAF7D05004ACDB7 /* CBPeripheralState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C170C98D1CECD6F300F3D8E5 /* CBPeripheralState.swift */; }; 43D5E7A41FAF7D4D004ACDB7 /* TimeZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4345D1CD1DA16AF300BAAD22 /* TimeZone.swift */; }; + 43DAD00220A6A470000F8529 /* ReadOtherDevicesStatusMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43DAD00120A6A470000F8529 /* ReadOtherDevicesStatusMessageBody.swift */; }; + 43DAD00420A6A677000F8529 /* ReadOtherDevicesIDsMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43DAD00320A6A677000F8529 /* ReadOtherDevicesIDsMessageBody.swift */; }; + 43DAD00620A6B10A000F8529 /* ReadOtherDevicesIDsMessageBodyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43DAD00520A6B10A000F8529 /* ReadOtherDevicesIDsMessageBodyTests.swift */; }; 43EBE4521EAD23C40073A0B5 /* TimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EBE4501EAD238C0073A0B5 /* TimeInterval.swift */; }; 43EBE4531EAD23CE0073A0B5 /* TimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EBE4501EAD238C0073A0B5 /* TimeInterval.swift */; }; 43EBE4541EAD23EC0073A0B5 /* TimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EBE4501EAD238C0073A0B5 /* TimeInterval.swift */; }; @@ -583,6 +586,9 @@ 43D5E78E1FAF7BFB004ACDB7 /* RileyLinkKitUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RileyLinkKitUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 43D5E7901FAF7BFB004ACDB7 /* RileyLinkKitUI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RileyLinkKitUI.h; sourceTree = ""; }; 43D5E7911FAF7BFB004ACDB7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 43DAD00120A6A470000F8529 /* ReadOtherDevicesStatusMessageBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadOtherDevicesStatusMessageBody.swift; sourceTree = ""; }; + 43DAD00320A6A677000F8529 /* ReadOtherDevicesIDsMessageBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadOtherDevicesIDsMessageBody.swift; sourceTree = ""; }; + 43DAD00520A6B10A000F8529 /* ReadOtherDevicesIDsMessageBodyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadOtherDevicesIDsMessageBodyTests.swift; sourceTree = ""; }; 43EBE4501EAD238C0073A0B5 /* TimeInterval.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeInterval.swift; sourceTree = ""; }; 43EC9DCA1B786C6200DB0D18 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = ""; }; 43F348051D596270009933DC /* HKUnit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HKUnit.swift; sourceTree = ""; }; @@ -1216,6 +1222,7 @@ C14303171C97CC6B00A40450 /* GetPumpModelCarelinkMessageBodyTests.swift */, C1EAD6D21C826C43006DBA60 /* MySentryPumpStatusMessageBodyTests.swift */, 541688DA1DB820BF005B1891 /* ReadCurrentGlucosePageMessageBodyTests.swift */, + 43DAD00520A6B10A000F8529 /* ReadOtherDevicesIDsMessageBodyTests.swift */, 43A068EB1CF6BA6900F9EFE4 /* ReadRemainingInsulinMessageBodyTests.swift */, C1EAD6D41C826C43006DBA60 /* ReadSettingsCarelinkMessageBodyTests.swift */, 43CA93301CB97191000026B5 /* ReadTempBasalCarelinkMessageBodyTests.swift */, @@ -1567,6 +1574,7 @@ C1EAD6BD1C826B92006DBA60 /* CarelinkMessageBody.swift */, 43CA93281CB8CF22000026B5 /* ChangeTempBasalCarelinkMessageBody.swift */, 43CA932A1CB8CF76000026B5 /* ChangeTimeCarelinkMessageBody.swift */, + C1F0004B1EBE68A600F65163 /* DataFrameMessageBody.swift */, C10AB08E1C855F34000F102E /* DeviceLinkMessageBody.swift */, C10AB08C1C855613000F102E /* FindDeviceMessageBody.swift */, C1711A5B1C953F3000CB25BD /* GetBatteryCarelinkMessageBody.swift */, @@ -1579,17 +1587,18 @@ C1EAD6C11C826B92006DBA60 /* MySentryPumpStatusMessageBody.swift */, C1EAD6C21C826B92006DBA60 /* PowerOnCarelinkMessageBody.swift */, C14303151C97C98000A40450 /* PumpAckMessageBody.swift */, + C1A721611EC3E0500080FAD7 /* PumpErrorMessageBody.swift */, + 541688DC1DB82213005B1891 /* ReadCurrentGlucosePageMessageBody.swift */, + 2FDE1A061E57B12D00B56A27 /* ReadCurrentPageNumberMessageBody.swift */, + 43DAD00320A6A677000F8529 /* ReadOtherDevicesIDsMessageBody.swift */, + 43DAD00120A6A470000F8529 /* ReadOtherDevicesStatusMessageBody.swift */, C178845C1D4EF3D800405663 /* ReadPumpStatusMessageBody.swift */, 433568751CF67FA800FD9D54 /* ReadRemainingInsulinMessageBody.swift */, - 541688DC1DB82213005B1891 /* ReadCurrentGlucosePageMessageBody.swift */, C1EAD6C31C826B92006DBA60 /* ReadSettingsCarelinkMessageBody.swift */, 43CA932C1CB8CFA1000026B5 /* ReadTempBasalCarelinkMessageBody.swift */, 43CA932D1CB8CFA1000026B5 /* ReadTimeCarelinkMessageBody.swift */, - C1EAD6C41C826B92006DBA60 /* UnknownMessageBody.swift */, - 2FDE1A061E57B12D00B56A27 /* ReadCurrentPageNumberMessageBody.swift */, - C1F0004B1EBE68A600F65163 /* DataFrameMessageBody.swift */, - C1A721611EC3E0500080FAD7 /* PumpErrorMessageBody.swift */, 43BF58AF1FF594CB00499C46 /* SelectBasalProfileMessageBody.swift */, + C1EAD6C41C826B92006DBA60 /* UnknownMessageBody.swift */, ); path = Messages; sourceTree = ""; @@ -1919,10 +1928,12 @@ LastSwiftMigration = 0900; }; C12EA236198B436800309FA4 = { + DevelopmentTeam = 57NRR26737; LastSwiftMigration = 0900; ProvisioningStyle = Automatic; }; C12EA251198B436800309FA4 = { + DevelopmentTeam = 57NRR26737; ProvisioningStyle = Automatic; TestTargetID = C12EA236198B436800309FA4; }; @@ -2177,6 +2188,7 @@ files = ( C1842C1C1C8FA45100DB42AC /* ChangeBGReminderOffsetPumpEvent.swift in Sources */, C1842BD11C8FA3D200DB42AC /* AlarmClockReminderPumpEvent.swift in Sources */, + 43DAD00220A6A470000F8529 /* ReadOtherDevicesStatusMessageBody.swift in Sources */, C1842C1B1C8FA45100DB42AC /* ChangeBolusReminderEnablePumpEvent.swift in Sources */, C1842BC51C8F897E00DB42AC /* BasalProfileStartPumpEvent.swift in Sources */, 54BC448C1DB47BEA00340EED /* SensorCalGlucoseEvent.swift in Sources */, @@ -2227,6 +2239,7 @@ 54BC449C1DB483F700340EED /* RelativeTimestampedGlucoseEvent.swift in Sources */, C1330F431DBDA46400569064 /* ChangeSensorAlarmSilenceConfigPumpEvent.swift in Sources */, C1F6EB871F89C3B100CFE393 /* CRC8.swift in Sources */, + 43DAD00420A6A677000F8529 /* ReadOtherDevicesIDsMessageBody.swift in Sources */, 546A85D81DF7C83A00733213 /* SensorDataHighGlucoseEvent.swift in Sources */, C1842C091C8FA45100DB42AC /* ChangeWatchdogEnablePumpEvent.swift in Sources */, C1842BC91C8F968B00DB42AC /* BGReceivedPumpEvent.swift in Sources */, @@ -2335,6 +2348,7 @@ 43A068EC1CF6BA6900F9EFE4 /* ReadRemainingInsulinMessageBodyTests.swift in Sources */, 2F962EC81E7074E60070EFBD /* BolusNormalPumpEventTests.swift in Sources */, C1EAD6D61C826C43006DBA60 /* MySentryPumpStatusMessageBodyTests.swift in Sources */, + 43DAD00620A6B10A000F8529 /* ReadOtherDevicesIDsMessageBodyTests.swift in Sources */, C1EAD6D81C826C43006DBA60 /* ReadSettingsCarelinkMessageBodyTests.swift in Sources */, 43B0ADC01D0FC03200AAD278 /* NSDateComponentsTests.swift in Sources */, 546A85D21DF7BD5F00733213 /* SensorErrorGlucoseEventTests.swift in Sources */, @@ -3199,7 +3213,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 57NRR26737; INFOPLIST_FILE = "RileyLink/RileyLink-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.rlapp; @@ -3220,7 +3234,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 57NRR26737; INFOPLIST_FILE = "RileyLink/RileyLink-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.rlapp; @@ -3239,7 +3253,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 57NRR26737; GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; INFOPLIST_FILE = "RileyLinkTests/RileyLinkTests-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -3259,7 +3273,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 57NRR26737; INFOPLIST_FILE = "RileyLinkTests/RileyLinkTests-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.rileylink.${PRODUCT_NAME:rfc1034identifier}"; diff --git a/RileyLinkBLEKit/PeripheralManager.swift b/RileyLinkBLEKit/PeripheralManager.swift index e6e71dba9..1fce10461 100644 --- a/RileyLinkBLEKit/PeripheralManager.swift +++ b/RileyLinkBLEKit/PeripheralManager.swift @@ -45,7 +45,7 @@ class PeripheralManager: NSObject { /// Any error surfaced during the active operation private var commandError: Error? - unowned let central: CBCentralManager + private(set) weak var central: CBCentralManager? let configuration: Configuration @@ -168,7 +168,7 @@ extension PeripheralManager { func runCommand(timeout: TimeInterval, command: () -> Void) throws { // Prelude dispatchPrecondition(condition: .onQueue(queue)) - guard central.state == .poweredOn && peripheral.state == .connected else { + guard central?.state == .poweredOn && peripheral.state == .connected else { throw PeripheralManagerError.notReady } diff --git a/RileyLinkBLEKit/RileyLinkDevice.swift b/RileyLinkBLEKit/RileyLinkDevice.swift index 461fc388b..cbe42f715 100644 --- a/RileyLinkBLEKit/RileyLinkDevice.swift +++ b/RileyLinkBLEKit/RileyLinkDevice.swift @@ -95,7 +95,7 @@ extension RileyLinkDevice { } public func readRSSI() { - guard case .connected = manager.peripheral.state, case .poweredOn = manager.central.state else { + guard case .connected = manager.peripheral.state, case .poweredOn? = manager.central?.state else { return } manager.peripheral.readRSSI() @@ -182,7 +182,7 @@ extension RileyLinkDevice { return } - guard case .connected = self.manager.peripheral.state, case .poweredOn = self.manager.central.state else { + guard case .connected = self.manager.peripheral.state, case .poweredOn? = self.manager.central?.state else { return } diff --git a/RileyLinkKit/PumpOpsSession.swift b/RileyLinkKit/PumpOpsSession.swift index 8e5249560..ccf18857f 100644 --- a/RileyLinkKit/PumpOpsSession.swift +++ b/RileyLinkKit/PumpOpsSession.swift @@ -245,6 +245,19 @@ extension PumpOpsSession { return BasalSchedule(rawValue: scheduleData)! } + + public func getOtherDevicesIDs() throws -> ReadOtherDevicesIDsMessageBody { + try wakeup() + + return try session.getResponse(to: PumpMessage(settings: settings, type: .readOtherDevicesIDs), responseType: .readOtherDevicesIDs) + } + + public func getOtherDevicesEnabled() throws -> Bool { + try wakeup() + + let response: ReadOtherDevicesStatusMessageBody = try session.getResponse(to: PumpMessage(settings: settings, type: .readOtherDevicesStatus), responseType: .readOtherDevicesStatus) + return response.isEnabled + } } @@ -525,10 +538,9 @@ extension PumpOpsSession { } } - public func discoverCommands(_ updateHandler: (_ messages: [String]) -> Void) { - let codes: [MessageType] = [ - .PumpExperiment_O103, - ] + public func discoverCommands(in range: CountableClosedRange, _ updateHandler: (_ messages: [String]) -> Void) { + + let codes = range.compactMap { MessageType(rawValue: $0) } for code in codes { var messages = [String]() @@ -551,6 +563,16 @@ extension PumpOpsSession { // Check history? + } catch PumpOpsError.unexpectedResponse(let response, from: _) { + messages.append(contentsOf: [ + "Unexpected response:", + response.txData.hexadecimalString, + ]) + } catch PumpOpsError.unknownResponse(rx: let response, during: _) { + messages.append(contentsOf: [ + "Unknown response:", + response.hexadecimalString, + ]) } catch let error { messages.append(contentsOf: [ String(describing: error), diff --git a/RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift b/RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift index d84940e8c..8b06de238 100644 --- a/RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift +++ b/RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift @@ -39,6 +39,20 @@ extension CommandResponseViewController { } } + static func discoverCommands(ops: PumpOps?, device: RileyLinkDevice) -> T { + return T { (completionHandler) -> String in + ops?.runSession(withName: "Discover Commands", using: device) { (session) in + session.discoverCommands(in: 0xf0...0xff, { (results) in + DispatchQueue.main.async { + completionHandler(results.joined(separator: "\n")) + } + }) + } + + return NSLocalizedString("Discovering commands…", comment: "Progress message for discovering commands.") + } + } + static func dumpHistory(ops: PumpOps?, device: RileyLinkDevice) -> T { return T { (completionHandler) -> String in let calendar = Calendar(identifier: Calendar.Identifier.gregorian) @@ -214,7 +228,6 @@ extension CommandResponseViewController { } } - static func readPumpStatus(ops: PumpOps?, device: RileyLinkDevice, measurementFormatter: MeasurementFormatter) -> T { return T { (completionHandler) -> String in ops?.runSession(withName: "Read pump status", using: device) { (session) in diff --git a/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift b/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift index e97b6a0b9..38d9e90b1 100644 --- a/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift +++ b/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift @@ -241,6 +241,7 @@ public class RileyLinkDeviceTableViewController: UITableViewController { case readPumpStatus case readBasalSchedule case enableLED + case discoverCommands } private func cellForRow(_ row: DeviceRow) -> UITableViewCell? { @@ -370,6 +371,9 @@ public class RileyLinkDeviceTableViewController: UITableViewController { case .enableLED: cell.textLabel?.text = NSLocalizedString("Enable Diagnostic LEDs", comment: "The title of the command to enable diagnostic LEDs") + + case .discoverCommands: + cell.textLabel?.text = NSLocalizedString("Discover Commands", comment: "The title of the command to discover commands") } } @@ -446,6 +450,8 @@ public class RileyLinkDeviceTableViewController: UITableViewController { vc = .readBasalSchedule(ops: ops, device: device, integerFormatter: integerFormatter) case .enableLED: vc = .enableLEDs(ops: ops, device: device) + case .discoverCommands: + vc = .discoverCommands(ops: ops, device: device) } if let cell = tableView.cellForRow(at: indexPath) { From 23d52e7aa8688cd4dfc4cee8ef1fa3ee4067ccfb Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 28 May 2018 07:05:30 -0500 Subject: [PATCH 10/12] Add correction range to loop status reporting (#395) --- .../DeviceStatus/CorrectionRange.swift | 32 +++++++++++++++++++ .../DeviceStatus/LoopStatus.swift | 9 +++++- RileyLink.xcodeproj/project.pbxproj | 4 +++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 NightscoutUploadKit/DeviceStatus/CorrectionRange.swift diff --git a/NightscoutUploadKit/DeviceStatus/CorrectionRange.swift b/NightscoutUploadKit/DeviceStatus/CorrectionRange.swift new file mode 100644 index 000000000..1442470e5 --- /dev/null +++ b/NightscoutUploadKit/DeviceStatus/CorrectionRange.swift @@ -0,0 +1,32 @@ +// +// CorrectionRange.swift +// NightscoutUploadKit +// +// Created by Pete Schwamb on 5/28/18. +// Copyright © 2018 Pete Schwamb. All rights reserved. +// + +import Foundation +import HealthKit + +public struct CorrectionRange { + let minValue: Int + let maxValue: Int + + public init(minValue: HKQuantity, maxValue: HKQuantity) { + + // BG values in nightscout are in mg/dL. + let unit = HKUnit.milligramsPerDeciliterUnit() + self.minValue = Int(round(minValue.doubleValue(for: unit))) + self.maxValue = Int(round(maxValue.doubleValue(for: unit))) + } + + public var dictionaryRepresentation: [String: Any] { + var rval = [String: Any]() + + rval["minValue"] = minValue + rval["maxValue"] = maxValue + + return rval + } +} diff --git a/NightscoutUploadKit/DeviceStatus/LoopStatus.swift b/NightscoutUploadKit/DeviceStatus/LoopStatus.swift index 10d9f68f2..15cb6332c 100644 --- a/NightscoutUploadKit/DeviceStatus/LoopStatus.swift +++ b/NightscoutUploadKit/DeviceStatus/LoopStatus.swift @@ -21,8 +21,10 @@ public struct LoopStatus { let enacted: LoopEnacted? let rileylinks: [RileyLinkStatus]? let failureReason: Error? + let currentCorrectionRange: CorrectionRange? - public init(name: String, version: String, timestamp: Date, iob: IOBStatus? = nil, cob: COBStatus? = nil, predicted: PredictedBG? = nil, recommendedTempBasal:RecommendedTempBasal? = nil, recommendedBolus: Double? = nil, enacted: LoopEnacted? = nil, rileylinks: [RileyLinkStatus]? = nil, failureReason: Error? = nil) { + + public init(name: String, version: String, timestamp: Date, iob: IOBStatus? = nil, cob: COBStatus? = nil, predicted: PredictedBG? = nil, recommendedTempBasal:RecommendedTempBasal? = nil, recommendedBolus: Double? = nil, enacted: LoopEnacted? = nil, rileylinks: [RileyLinkStatus]? = nil, failureReason: Error? = nil, currentCorrectionRange: CorrectionRange? = nil) { self.name = name self.version = version self.timestamp = timestamp @@ -34,6 +36,7 @@ public struct LoopStatus { self.enacted = enacted self.rileylinks = rileylinks self.failureReason = failureReason + self.currentCorrectionRange = currentCorrectionRange } public var dictionaryRepresentation: [String: Any] { @@ -75,6 +78,10 @@ public struct LoopStatus { rval["rileylinks"] = rileylinks.map { $0.dictionaryRepresentation } } + if let currentCorrectionRange = currentCorrectionRange { + rval["currentCorrectionRange"] = currentCorrectionRange.dictionaryRepresentation + } + return rval } } diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 9b8280e9e..506200f8e 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -304,6 +304,7 @@ C1842C231C8FA45100DB42AC /* ChangeAlarmClockEnablePumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BF91C8FA45100DB42AC /* ChangeAlarmClockEnablePumpEvent.swift */; }; C1842C241C8FA45100DB42AC /* BatteryPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BFA1C8FA45100DB42AC /* BatteryPumpEvent.swift */; }; C1842C251C8FA45100DB42AC /* AlarmSensorPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BFB1C8FA45100DB42AC /* AlarmSensorPumpEvent.swift */; }; + C184875C20BC232F00ABE9E7 /* CorrectionRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = C184875B20BC232F00ABE9E7 /* CorrectionRange.swift */; }; C18C8C531D64123400E043FB /* EnableBolusWizardPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C18C8C521D64123400E043FB /* EnableBolusWizardPumpEvent.swift */; }; C18EB742207EE20100EA002B /* NightscoutProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C18EB741207EE20100EA002B /* NightscoutProfile.swift */; }; C1A492631D4A5A19008964FF /* IOBStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A492621D4A5A19008964FF /* IOBStatus.swift */; }; @@ -795,6 +796,7 @@ C1842BFB1C8FA45100DB42AC /* AlarmSensorPumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = AlarmSensorPumpEvent.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; C1842C281C908A3C00DB42AC /* NightscoutUploader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NightscoutUploader.swift; sourceTree = ""; }; C1842C2A1C90DFB600DB42AC /* NightscoutPumpEvents.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NightscoutPumpEvents.swift; sourceTree = ""; }; + C184875B20BC232F00ABE9E7 /* CorrectionRange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CorrectionRange.swift; sourceTree = ""; }; C18C8C521D64123400E043FB /* EnableBolusWizardPumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnableBolusWizardPumpEvent.swift; sourceTree = ""; }; C18EB741207EE20100EA002B /* NightscoutProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutProfile.swift; sourceTree = ""; }; C1A492621D4A5A19008964FF /* IOBStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IOBStatus.swift; sourceTree = ""; }; @@ -1498,6 +1500,7 @@ C133CF921D5943780034B82D /* PredictedBG.swift */, C1E5BEAC1D5E26F200BD4390 /* RileyLinkStatus.swift */, C1BAD1171E63984C009BA1C6 /* RadioAdapter.swift */, + C184875B20BC232F00ABE9E7 /* CorrectionRange.swift */, ); path = DeviceStatus; sourceTree = ""; @@ -2436,6 +2439,7 @@ C1B383291CD0668600CE7782 /* NightscoutPumpEvents.swift in Sources */, C18EB742207EE20100EA002B /* NightscoutProfile.swift in Sources */, 43B0ADCC1D126E3000AAD278 /* NSDateFormatter.swift in Sources */, + C184875C20BC232F00ABE9E7 /* CorrectionRange.swift in Sources */, C1AF21E81D4866960088C41D /* PumpStatus.swift in Sources */, C1AF21F01D4901220088C41D /* BolusNightscoutTreatment.swift in Sources */, C1AF21F21D4901220088C41D /* BGCheckNightscoutTreatment.swift in Sources */, From 85ce83c40c71d853a8a936a20c28b06e4e639ae1 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 28 May 2018 07:20:57 -0500 Subject: [PATCH 11/12] New pump event type (#397) --- .../CalBGForGHGlucoseEvent.swift | 4 ++-- .../SensorCalFactorGlucoseEvent.swift | 4 ++-- .../GlucoseEvents/SensorCalGlucoseEvent.swift | 4 ++-- .../SensorErrorGlucoseEvent.swift | 4 ++-- .../SensorPacketGlucoseEvent.swift | 4 ++-- .../SensorStatusGlucoseEvent.swift | 4 ++-- .../SensorSyncGlucoseEvent.swift | 4 ++-- MinimedKit/GlucosePage.swift | 6 ++--- MinimedKit/HistoryPage.swift | 6 ++--- .../GetBatteryCarelinkMessageBody.swift | 4 ++-- .../Messages/GetGlucosePageMessageBody.swift | 4 ++-- .../GetHistoryPageCarelinkMessageBody.swift | 4 ++-- MinimedKit/Messages/MeterMessage.swift | 4 ++-- .../MySentryPumpStatusMessageBody.swift | 2 +- .../ReadCurrentGlucosePageMessageBody.swift | 4 ++-- .../ReadTimeCarelinkMessageBody.swift | 10 ++++----- MinimedKit/PumpEventType.swift | 1 + .../PumpEvents/BGReceivedPumpEvent.swift | 4 ++-- .../PumpEvents/BolusNormalPumpEvent.swift | 2 +- .../BolusWizardEstimatePumpEvent.swift | 4 ++-- .../PumpEvents/CalBGForPHPumpEvent.swift | 4 ++-- .../ChangeTempBasalTypePumpEvent.swift | 4 ++-- .../ChangeTimeFormatPumpEvent.swift | 4 ++-- .../JournalEntryInsulinMarkerPumpEvent.swift | 4 ++-- .../JournalEntryMealMarkerPumpEvent.swift | 6 ++--- .../PumpEvents/PlaceholderPumpEvent.swift | 4 ++-- MinimedKit/PumpEvents/PrimePumpEvent.swift | 4 ++-- .../TempBasalDurationPumpEvent.swift | 4 ++-- .../PumpEvents/TempBasalPumpEvent.swift | 4 ++-- .../UnabsorbedInsulinPumpEvent.swift | 6 ++--- MinimedKitTests/HistoryPageTests.swift | 22 +++++++++++++++++++ 31 files changed, 86 insertions(+), 63 deletions(-) diff --git a/MinimedKit/GlucoseEvents/CalBGForGHGlucoseEvent.swift b/MinimedKit/GlucoseEvents/CalBGForGHGlucoseEvent.swift index c26615b2e..7a2c9f59a 100644 --- a/MinimedKit/GlucoseEvents/CalBGForGHGlucoseEvent.swift +++ b/MinimedKit/GlucoseEvents/CalBGForGHGlucoseEvent.swift @@ -22,8 +22,8 @@ public struct CalBGForGHGlucoseEvent: GlucoseEvent { return nil } - func d(_ idx:Int) -> Int { - return Int(availableData[idx] as UInt8) + func d(_ idx: Int) -> Int { + return Int(availableData[idx]) } rawData = availableData.subdata(in: 0.. Int { - return Int(availableData[idx] as UInt8) + func d(_ idx: Int) -> Int { + return Int(availableData[idx]) } rawData = availableData.subdata(in: 0.. Int { - return Int(availableData[idx] as UInt8) + func d(_ idx: Int) -> Int { + return Int(availableData[idx]) } rawData = availableData.subdata(in: 0.. Int { - return Int(availableData[idx] as UInt8) + func d(_ idx: Int) -> Int { + return Int(availableData[idx]) } rawData = availableData.subdata(in: 0.. Int { - return Int(availableData[idx] as UInt8) + func d(_ idx: Int) -> Int { + return Int(availableData[idx]) } rawData = availableData.subdata(in: 0.. Int { - return Int(availableData[idx] as UInt8) + func d(_ idx: Int) -> Int { + return Int(availableData[idx]) } rawData = availableData.subdata(in: 0.. Int { - return Int(availableData[idx] as UInt8) + func d(_ idx: Int) -> Int { + return Int(availableData[idx]) } rawData = availableData.subdata(in: 0.. GlucoseEvent { let remainingData = pageData.subdata(in: offset.. PumpEvent? { - if let eventType = PumpEventType(rawValue:(pageData[offset] as UInt8)) { + if let eventType = PumpEventType(rawValue: pageData[offset]) { let remainingData = pageData.subdata(in: offset.. 0 + frameNumber = Int(rxData[0]) & 0b1111111 + lastFrame = (rxData[0]) & 0b10000000 > 0 frame = rxData.subdata(in: 1..<65) super.init(rxData: rxData) } diff --git a/MinimedKit/Messages/GetHistoryPageCarelinkMessageBody.swift b/MinimedKit/Messages/GetHistoryPageCarelinkMessageBody.swift index 23023cb60..506858930 100644 --- a/MinimedKit/Messages/GetHistoryPageCarelinkMessageBody.swift +++ b/MinimedKit/Messages/GetHistoryPageCarelinkMessageBody.swift @@ -17,8 +17,8 @@ public class GetHistoryPageCarelinkMessageBody: CarelinkLongMessageBody { guard rxData.count == type(of: self).length else { return nil } - frameNumber = Int(rxData[0] as UInt8) & 0b1111111 - lastFrame = (rxData[0] as UInt8) & 0b10000000 > 0 + frameNumber = Int(rxData[0]) & 0b1111111 + lastFrame = (rxData[0]) & 0b10000000 > 0 frame = rxData.subdata(in: 1..<65) super.init(rxData: rxData) } diff --git a/MinimedKit/Messages/MeterMessage.swift b/MinimedKit/Messages/MeterMessage.swift index ceea89127..8779bf573 100644 --- a/MinimedKit/Messages/MeterMessage.swift +++ b/MinimedKit/Messages/MeterMessage.swift @@ -22,9 +22,9 @@ public class MeterMessage { if rxData.count == length, let packetType = PacketType(rawValue: rxData[0]), packetType == .meter { - let flags = ((rxData[4] as UInt8) & 0b110) >> 1 + let flags = ((rxData[4]) & 0b110) >> 1 ackFlag = flags == 0x03 - glucose = Int((rxData[4] as UInt8) & 0b1) << 8 + Int(rxData[4] as UInt8) + glucose = Int((rxData[4]) & 0b1) << 8 + Int(rxData[4]) } else { ackFlag = false glucose = 0 diff --git a/MinimedKit/Messages/MySentryPumpStatusMessageBody.swift b/MinimedKit/Messages/MySentryPumpStatusMessageBody.swift index 39cb8d963..5ef79cd40 100644 --- a/MinimedKit/Messages/MySentryPumpStatusMessageBody.swift +++ b/MinimedKit/Messages/MySentryPumpStatusMessageBody.swift @@ -186,7 +186,7 @@ public struct MySentryPumpStatusMessageBody: MessageBody, DictionaryRepresentabl let matchingHour: UInt8 = rxData[20] nextSensorCalibrationDateComponents = DateComponents() nextSensorCalibrationDateComponents?.hour = Int(matchingHour) - nextSensorCalibrationDateComponents?.minute = Int(rxData[21] as UInt8) + nextSensorCalibrationDateComponents?.minute = Int(rxData[21]) nextSensorCalibrationDateComponents?.calendar = calendar } diff --git a/MinimedKit/Messages/ReadCurrentGlucosePageMessageBody.swift b/MinimedKit/Messages/ReadCurrentGlucosePageMessageBody.swift index a4dbf9ce2..b35b34ede 100644 --- a/MinimedKit/Messages/ReadCurrentGlucosePageMessageBody.swift +++ b/MinimedKit/Messages/ReadCurrentGlucosePageMessageBody.swift @@ -21,8 +21,8 @@ public class ReadCurrentGlucosePageMessageBody: CarelinkLongMessageBody { self.pageNum = rxData[1..<5 ].withUnsafeBytes { UInt32(bigEndian: $0.pointee) } - self.glucose = Int(rxData[6] as UInt8) - self.isig = Int(rxData[8] as UInt8) + self.glucose = Int(rxData[6]) + self.isig = Int(rxData[8]) super.init(rxData: rxData) } diff --git a/MinimedKit/Messages/ReadTimeCarelinkMessageBody.swift b/MinimedKit/Messages/ReadTimeCarelinkMessageBody.swift index 61cbceaeb..a91c96508 100644 --- a/MinimedKit/Messages/ReadTimeCarelinkMessageBody.swift +++ b/MinimedKit/Messages/ReadTimeCarelinkMessageBody.swift @@ -20,12 +20,12 @@ public class ReadTimeCarelinkMessageBody: CarelinkLongMessageBody { var dateComponents = DateComponents() dateComponents.calendar = Calendar(identifier: Calendar.Identifier.gregorian) - dateComponents.hour = Int(rxData[1] as UInt8) - dateComponents.minute = Int(rxData[2] as UInt8) - dateComponents.second = Int(rxData[3] as UInt8) + dateComponents.hour = Int(rxData[1]) + dateComponents.minute = Int(rxData[2]) + dateComponents.second = Int(rxData[3]) dateComponents.year = Int(bigEndianBytes: rxData.subdata(in: 4..<6)) - dateComponents.month = Int(rxData[6] as UInt8) - dateComponents.day = Int(rxData[7] as UInt8) + dateComponents.month = Int(rxData[6]) + dateComponents.day = Int(rxData[7]) self.dateComponents = dateComponents diff --git a/MinimedKit/PumpEventType.swift b/MinimedKit/PumpEventType.swift index deb06c3b3..d36fef386 100644 --- a/MinimedKit/PumpEventType.swift +++ b/MinimedKit/PumpEventType.swift @@ -47,6 +47,7 @@ public enum PumpEventType: UInt8 { case journalEntryExerciseMarker = 0x41 case journalEntryInsulinMarker = 0x42 case journalEntryOtherMarker = 0x43 + case changeSensorAutoCalEnable = 0x44 case changeBolusWizardSetup = 0x4f case changeSensorSetup2 = 0x50 case restoreMystery51 = 0x51 diff --git a/MinimedKit/PumpEvents/BGReceivedPumpEvent.swift b/MinimedKit/PumpEvents/BGReceivedPumpEvent.swift index ff0584ee3..f033376a6 100644 --- a/MinimedKit/PumpEvents/BGReceivedPumpEvent.swift +++ b/MinimedKit/PumpEvents/BGReceivedPumpEvent.swift @@ -24,8 +24,8 @@ public struct BGReceivedPumpEvent: TimestampedPumpEvent { rawData = availableData.subdata(in: 0.. Int { - return Int(availableData[idx] as UInt8) + func d(_ idx: Int) -> Int { + return Int(availableData[idx]) } timestamp = DateComponents(pumpEventData: availableData, offset: 2) diff --git a/MinimedKit/PumpEvents/BolusNormalPumpEvent.swift b/MinimedKit/PumpEvents/BolusNormalPumpEvent.swift index 5baf00de2..a0424099d 100644 --- a/MinimedKit/PumpEvents/BolusNormalPumpEvent.swift +++ b/MinimedKit/PumpEvents/BolusNormalPumpEvent.swift @@ -64,7 +64,7 @@ public struct BolusNormalPumpEvent: TimestampedPumpEvent { let duration: TimeInterval func doubleValueFromData(at index: Int) -> Double { - return Double(availableData[index] as UInt8) + return Double(availableData[index]) } func decodeInsulin(from bytes: Data) -> Double { diff --git a/MinimedKit/PumpEvents/BolusWizardEstimatePumpEvent.swift b/MinimedKit/PumpEvents/BolusWizardEstimatePumpEvent.swift index 967d449f9..d4e26fe48 100644 --- a/MinimedKit/PumpEvents/BolusWizardEstimatePumpEvent.swift +++ b/MinimedKit/PumpEvents/BolusWizardEstimatePumpEvent.swift @@ -25,8 +25,8 @@ public struct BolusWizardEstimatePumpEvent: TimestampedPumpEvent { public init?(availableData: Data, pumpModel: PumpModel) { - func d(_ idx:Int) -> Int { - return Int(availableData[idx] as UInt8) + func d(_ idx: Int) -> Int { + return Int(availableData[idx]) } func insulinDecode(_ a: Int, b: Int) -> Double { diff --git a/MinimedKit/PumpEvents/CalBGForPHPumpEvent.swift b/MinimedKit/PumpEvents/CalBGForPHPumpEvent.swift index cc6d065ff..54c8178e9 100644 --- a/MinimedKit/PumpEvents/CalBGForPHPumpEvent.swift +++ b/MinimedKit/PumpEvents/CalBGForPHPumpEvent.swift @@ -23,8 +23,8 @@ public struct CalBGForPHPumpEvent: TimestampedPumpEvent { rawData = availableData.subdata(in: 0.. Int { - return Int(availableData[idx] as UInt8) + func d(_ idx: Int) -> Int { + return Int(availableData[idx]) } timestamp = DateComponents(pumpEventData: availableData, offset: 2) diff --git a/MinimedKit/PumpEvents/ChangeTempBasalTypePumpEvent.swift b/MinimedKit/PumpEvents/ChangeTempBasalTypePumpEvent.swift index 166aced7d..183e6b5fe 100644 --- a/MinimedKit/PumpEvents/ChangeTempBasalTypePumpEvent.swift +++ b/MinimedKit/PumpEvents/ChangeTempBasalTypePumpEvent.swift @@ -17,8 +17,8 @@ public struct ChangeTempBasalTypePumpEvent: TimestampedPumpEvent { public init?(availableData: Data, pumpModel: PumpModel) { length = 7 - func d(_ idx:Int) -> Int { - return Int(availableData[idx] as UInt8) + func d(_ idx: Int) -> Int { + return Int(availableData[idx]) } guard length <= availableData.count else { diff --git a/MinimedKit/PumpEvents/ChangeTimeFormatPumpEvent.swift b/MinimedKit/PumpEvents/ChangeTimeFormatPumpEvent.swift index 7918cf1c7..0425bb5a2 100644 --- a/MinimedKit/PumpEvents/ChangeTimeFormatPumpEvent.swift +++ b/MinimedKit/PumpEvents/ChangeTimeFormatPumpEvent.swift @@ -25,8 +25,8 @@ public struct ChangeTimeFormatPumpEvent: TimestampedPumpEvent { timestamp = DateComponents(pumpEventData: availableData, offset: 2) - func d(_ idx:Int) -> Int { - return Int(availableData[idx] as UInt8) + func d(_ idx: Int) -> Int { + return Int(availableData[idx]) } timeFormat = d(1) == 1 ? "24hr" : "am_pm" diff --git a/MinimedKit/PumpEvents/JournalEntryInsulinMarkerPumpEvent.swift b/MinimedKit/PumpEvents/JournalEntryInsulinMarkerPumpEvent.swift index 5633027d6..9f0467b92 100644 --- a/MinimedKit/PumpEvents/JournalEntryInsulinMarkerPumpEvent.swift +++ b/MinimedKit/PumpEvents/JournalEntryInsulinMarkerPumpEvent.swift @@ -25,8 +25,8 @@ public struct JournalEntryInsulinMarkerPumpEvent: TimestampedPumpEvent { timestamp = DateComponents(pumpEventData: availableData, offset: 2) - let lowBits = rawData[1] as UInt8 - let highBits = rawData[4] as UInt8 + let lowBits = rawData[1] + let highBits = rawData[4] amount = Double((Int(highBits & 0b1100000) << 3) + Int(lowBits)) / 10.0 } diff --git a/MinimedKit/PumpEvents/JournalEntryMealMarkerPumpEvent.swift b/MinimedKit/PumpEvents/JournalEntryMealMarkerPumpEvent.swift index cec3d1623..8be0dbdeb 100644 --- a/MinimedKit/PumpEvents/JournalEntryMealMarkerPumpEvent.swift +++ b/MinimedKit/PumpEvents/JournalEntryMealMarkerPumpEvent.swift @@ -23,11 +23,11 @@ public struct JournalEntryMealMarkerPumpEvent: TimestampedPumpEvent { public init?(availableData: Data, pumpModel: PumpModel) { length = 9 - let useExchangesBit = ((availableData[8] as UInt8) >> 1) & 0b1 + let useExchangesBit = ((availableData[8]) >> 1) & 0b1 carbUnits = (useExchangesBit != 0) ? .Exchanges : .Grams - let carbHighBit = (availableData[1] as UInt8) & 0b1 - let carbLowBits = availableData[7] as UInt8 + let carbHighBit = (availableData[1]) & 0b1 + let carbLowBits = availableData[7] if carbUnits == .Exchanges { carbohydrates = Double(carbLowBits) / 10.0 diff --git a/MinimedKit/PumpEvents/PlaceholderPumpEvent.swift b/MinimedKit/PumpEvents/PlaceholderPumpEvent.swift index 46485cdd3..22b3f9802 100644 --- a/MinimedKit/PumpEvents/PlaceholderPumpEvent.swift +++ b/MinimedKit/PumpEvents/PlaceholderPumpEvent.swift @@ -27,10 +27,10 @@ public struct PlaceholderPumpEvent: TimestampedPumpEvent { public var dictionaryRepresentation: [String: Any] { let name: String - if let type = PumpEventType(rawValue: rawData[0] as UInt8) { + if let type = PumpEventType(rawValue: rawData[0]) { name = String(describing: type).components(separatedBy: ".").last! } else { - name = "UnknownPumpEvent(\(rawData[0] as UInt8))" + name = "UnknownPumpEvent(\(rawData[0]))" } return [ diff --git a/MinimedKit/PumpEvents/PrimePumpEvent.swift b/MinimedKit/PumpEvents/PrimePumpEvent.swift index cd97f6593..bfc0f2c92 100644 --- a/MinimedKit/PumpEvents/PrimePumpEvent.swift +++ b/MinimedKit/PumpEvents/PrimePumpEvent.swift @@ -25,8 +25,8 @@ public struct PrimePumpEvent: TimestampedPumpEvent { rawData = availableData.subdata(in: 0.. Int { - return Int(availableData[idx] as UInt8) + func d(_ idx: Int) -> Int { + return Int(availableData[idx]) } timestamp = DateComponents(pumpEventData: availableData, offset: 5) diff --git a/MinimedKit/PumpEvents/TempBasalDurationPumpEvent.swift b/MinimedKit/PumpEvents/TempBasalDurationPumpEvent.swift index 9adbd88da..81e44e818 100644 --- a/MinimedKit/PumpEvents/TempBasalDurationPumpEvent.swift +++ b/MinimedKit/PumpEvents/TempBasalDurationPumpEvent.swift @@ -17,8 +17,8 @@ public struct TempBasalDurationPumpEvent: TimestampedPumpEvent { public init?(availableData: Data, pumpModel: PumpModel) { length = 7 - func d(_ idx:Int) -> Int { - return Int(availableData[idx] as UInt8) + func d(_ idx: Int) -> Int { + return Int(availableData[idx]) } guard length <= availableData.count else { diff --git a/MinimedKit/PumpEvents/TempBasalPumpEvent.swift b/MinimedKit/PumpEvents/TempBasalPumpEvent.swift index 3dd0e7be1..1424b9544 100644 --- a/MinimedKit/PumpEvents/TempBasalPumpEvent.swift +++ b/MinimedKit/PumpEvents/TempBasalPumpEvent.swift @@ -25,8 +25,8 @@ public struct TempBasalPumpEvent: TimestampedPumpEvent { public init?(availableData: Data, pumpModel: PumpModel) { length = 8 - func d(_ idx:Int) -> Int { - return Int(availableData[idx] as UInt8) + func d(_ idx: Int) -> Int { + return Int(availableData[idx]) } guard length <= availableData.count else { diff --git a/MinimedKit/PumpEvents/UnabsorbedInsulinPumpEvent.swift b/MinimedKit/PumpEvents/UnabsorbedInsulinPumpEvent.swift index a5a93cd40..419904ca3 100644 --- a/MinimedKit/PumpEvents/UnabsorbedInsulinPumpEvent.swift +++ b/MinimedKit/PumpEvents/UnabsorbedInsulinPumpEvent.swift @@ -33,7 +33,7 @@ public struct UnabsorbedInsulinPumpEvent: PumpEvent { public let records: [Record] public init?(availableData: Data, pumpModel: PumpModel) { - length = Int(max(availableData[1] as UInt8, UInt8(2))) + length = Int(max(availableData[1], 2)) var records = [Record]() guard length <= availableData.count else { @@ -42,8 +42,8 @@ public struct UnabsorbedInsulinPumpEvent: PumpEvent { rawData = availableData.subdata(in: 0.. Int { - return Int(availableData[idx] as UInt8) + func d(_ idx: Int) -> Int { + return Int(availableData[idx]) } let numRecords = (d(1) - 2) / 3 diff --git a/MinimedKitTests/HistoryPageTests.swift b/MinimedKitTests/HistoryPageTests.swift index f81dc8e87..f8f415af6 100644 --- a/MinimedKitTests/HistoryPageTests.swift +++ b/MinimedKitTests/HistoryPageTests.swift @@ -379,4 +379,26 @@ class HistoryPageTests: XCTestCase { XCTAssert(events[21] is ChangeSensorAlarmSilenceConfigPumpEvent) } + func testUnknownEventType68() throws { + // Veo 754 2.6a + // Thanks to @Mandelkern73 for discovering! + let pumpModel = PumpModel.model754 + let hexadecimalString = "090079614a98123f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b0a79610a1812141c00610079610a9812321279610a9812660079610a9812670079610a9812001e3c0179610a98123dc225450000003e000000000000260179610a98122705b7a100000028000000000000600079610a5812230079610a98125e0179610a98122d0179610a98125a0a79610a9812050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000089180000640400530c004b10005c1600781a008c20006422004b0000001f041a0c17101c16241a2a201f221700323e0000000000000000000000000000000000000000003f620079610a98125f2979610a9812520079610a9812510279610a9812551179610a9812000f0f00ffff00ffff00ffff00ffff00ffff00ffff00ffff00001400ffff00ffff00ffff00ffff00ffff00ffff00ffff560079614a9812dcdc002828500079610a981220011e003c14001e3cffffffb44600003c41011e00781e001e3c23efa7642780801f54fc79614a9812fffcff00f05000ffff00ffff00ffff00ffff00ffff00ffff00fffffcfffcff00642c00ffff00ffff00ffff00ffff00ffff00ffff00ffff44017c0179610a9812260172620a18122705b7a10000002800000000000044007b650a181244015d660a181250005f660a181241011e00781e001e3cffffff642780801f41011e00781e001e3c23efa7642780801f5d005e670a18120b68006c6a4ab8120a464a6b4a18127b0b40400b1812161c0017004a4e0b581218005d4e0b5812810141530b181200a21c85687d0141530b181200a21c8568000000000000000000000000000000000000000000000000007b0c40400c1812181800170042630c5812180041630c58127d015b630c181200a21c8568000000000000000000000000000000000000000000000000007b0d40400d18121a18000b70004b614db8120b71004a6f4db8127b0e40400e18121c18007b0f40400f18121e20000b70005c664fb8127b104040101812202c007b1140401118122230000b70005d7951b8127b1240401218122430007b1340401318122630001e01624e1358121f2058541358127b1358541318122630007b144040141812282c000b7000595754b8123300516014181200160151601418123300546714181200160054671418120000004b1c" + let data = Data(hexadecimalString: hexadecimalString) + + let page = try HistoryPage(pageData: data!, pumpModel: pumpModel) + let events = page.events + + for event in events { + if let event = event as? TimestampedPumpEvent { + print(event.timestamp, event.dictionaryRepresentation) + } else { + print(event.dictionaryRepresentation) + } + } + + XCTAssertEqual(58, events.count) + XCTAssert(events[23] is PlaceholderPumpEvent) + XCTAssert(events[23].rawData[0] == PumpEventType.changeSensorAutoCalEnable.rawValue) + } } From bfd2f8a8425e833c1d7ce16b9e8d39ad75d3a718 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 28 May 2018 07:21:11 -0500 Subject: [PATCH 12/12] Bump version (#396) --- Crypto/Info.plist | 2 +- MinimedKit/Info.plist | 2 +- MinimedKitTests/Info.plist | 2 +- NightscoutUploadKit/Info.plist | 2 +- NightscoutUploadKitTests/Info.plist | 2 +- RileyLink.xcodeproj/project.pbxproj | 48 ++++++++++++------------ RileyLink/RileyLink-Info.plist | 2 +- RileyLinkBLEKit/Info.plist | 2 +- RileyLinkBLEKitTests/Info.plist | 2 +- RileyLinkKit/Info.plist | 2 +- RileyLinkKitTests/Info.plist | 2 +- RileyLinkKitUI/Info.plist | 2 +- RileyLinkTests/RileyLinkTests-Info.plist | 2 +- 13 files changed, 36 insertions(+), 36 deletions(-) diff --git a/Crypto/Info.plist b/Crypto/Info.plist index d87c8b3c8..0e27f5f6d 100644 --- a/Crypto/Info.plist +++ b/Crypto/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0.0 + 2.0.1 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/MinimedKit/Info.plist b/MinimedKit/Info.plist index 7e7479f00..783e22ec8 100644 --- a/MinimedKit/Info.plist +++ b/MinimedKit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0.0 + 2.0.1 CFBundleSignature ???? CFBundleVersion diff --git a/MinimedKitTests/Info.plist b/MinimedKitTests/Info.plist index 2d0a14240..b7683fde8 100644 --- a/MinimedKitTests/Info.plist +++ b/MinimedKitTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.0.0 + 2.0.1 CFBundleSignature ???? CFBundleVersion diff --git a/NightscoutUploadKit/Info.plist b/NightscoutUploadKit/Info.plist index 7e7479f00..783e22ec8 100644 --- a/NightscoutUploadKit/Info.plist +++ b/NightscoutUploadKit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0.0 + 2.0.1 CFBundleSignature ???? CFBundleVersion diff --git a/NightscoutUploadKitTests/Info.plist b/NightscoutUploadKitTests/Info.plist index f931463ef..840b2c791 100644 --- a/NightscoutUploadKitTests/Info.plist +++ b/NightscoutUploadKitTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.0.0 + 2.0.1 CFBundleSignature ???? CFBundleVersion diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 506200f8e..99ee088d3 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -2675,7 +2675,7 @@ DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 36; + DYLIB_CURRENT_VERSION = 37; DYLIB_INSTALL_NAME_BASE = "@rpath"; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = RileyLinkBLEKit/Info.plist; @@ -2711,7 +2711,7 @@ DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 36; + DYLIB_CURRENT_VERSION = 37; DYLIB_INSTALL_NAME_BASE = "@rpath"; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = RileyLinkBLEKit/Info.plist; @@ -2787,11 +2787,11 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - CURRENT_PROJECT_VERSION = 36; + CURRENT_PROJECT_VERSION = 37; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 36; + DYLIB_CURRENT_VERSION = 37; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -2818,11 +2818,11 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 36; + CURRENT_PROJECT_VERSION = 37; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 36; + DYLIB_CURRENT_VERSION = 37; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -2885,12 +2885,12 @@ CLANG_WARN_SUSPICIOUS_MOVES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - CURRENT_PROJECT_VERSION = 36; + CURRENT_PROJECT_VERSION = 37; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 36; + DYLIB_CURRENT_VERSION = 37; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = Crypto/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -2913,12 +2913,12 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 36; + CURRENT_PROJECT_VERSION = 37; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 36; + DYLIB_CURRENT_VERSION = 37; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = Crypto/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -2943,12 +2943,12 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 36; + CURRENT_PROJECT_VERSION = 37; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 36; + DYLIB_CURRENT_VERSION = 37; DYLIB_INSTALL_NAME_BASE = "@rpath"; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = RileyLinkKitUI/Info.plist; @@ -2979,12 +2979,12 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 36; + CURRENT_PROJECT_VERSION = 37; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 36; + DYLIB_CURRENT_VERSION = 37; DYLIB_INSTALL_NAME_BASE = "@rpath"; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = RileyLinkKitUI/Info.plist; @@ -3008,12 +3008,12 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - CURRENT_PROJECT_VERSION = 36; + CURRENT_PROJECT_VERSION = 37; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 36; + DYLIB_CURRENT_VERSION = 37; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -3039,11 +3039,11 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 36; + CURRENT_PROJECT_VERSION = 37; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 36; + DYLIB_CURRENT_VERSION = 37; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -3126,7 +3126,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 36; + CURRENT_PROJECT_VERSION = 37; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -3185,7 +3185,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 36; + CURRENT_PROJECT_VERSION = 37; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -3297,11 +3297,11 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - CURRENT_PROJECT_VERSION = 36; + CURRENT_PROJECT_VERSION = 37; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 36; + DYLIB_CURRENT_VERSION = 37; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -3327,11 +3327,11 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 36; + CURRENT_PROJECT_VERSION = 37; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 36; + DYLIB_CURRENT_VERSION = 37; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; diff --git a/RileyLink/RileyLink-Info.plist b/RileyLink/RileyLink-Info.plist index f8c865ba6..9611a7aa7 100644 --- a/RileyLink/RileyLink-Info.plist +++ b/RileyLink/RileyLink-Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.0.0 + 2.0.1 CFBundleSignature ???? CFBundleVersion diff --git a/RileyLinkBLEKit/Info.plist b/RileyLinkBLEKit/Info.plist index d74989676..12c94a4e8 100644 --- a/RileyLinkBLEKit/Info.plist +++ b/RileyLinkBLEKit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0.0 + 2.0.1 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/RileyLinkBLEKitTests/Info.plist b/RileyLinkBLEKitTests/Info.plist index f4285f218..40302d5d0 100644 --- a/RileyLinkBLEKitTests/Info.plist +++ b/RileyLinkBLEKitTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.0.0 + 2.0.1 CFBundleVersion 1 diff --git a/RileyLinkKit/Info.plist b/RileyLinkKit/Info.plist index 7e7479f00..783e22ec8 100644 --- a/RileyLinkKit/Info.plist +++ b/RileyLinkKit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0.0 + 2.0.1 CFBundleSignature ???? CFBundleVersion diff --git a/RileyLinkKitTests/Info.plist b/RileyLinkKitTests/Info.plist index 2d0a14240..b7683fde8 100644 --- a/RileyLinkKitTests/Info.plist +++ b/RileyLinkKitTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.0.0 + 2.0.1 CFBundleSignature ???? CFBundleVersion diff --git a/RileyLinkKitUI/Info.plist b/RileyLinkKitUI/Info.plist index d74989676..12c94a4e8 100644 --- a/RileyLinkKitUI/Info.plist +++ b/RileyLinkKitUI/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0.0 + 2.0.1 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/RileyLinkTests/RileyLinkTests-Info.plist b/RileyLinkTests/RileyLinkTests-Info.plist index 20849defa..5422a5804 100644 --- a/RileyLinkTests/RileyLinkTests-Info.plist +++ b/RileyLinkTests/RileyLinkTests-Info.plist @@ -13,7 +13,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.0.0 + 2.0.1 CFBundleSignature ???? CFBundleVersion