From 5099a38e0014ac05218a11eac67197248138338d Mon Sep 17 00:00:00 2001 From: Nathan Racklyeft Date: Sat, 5 Mar 2016 09:52:30 -0800 Subject: [PATCH] Surfacing display-only calibration indicators --- xDripG5.podspec | 2 +- xDripG5.xcodeproj/project.pbxproj | 12 +++-- xDripG5/Info.plist | 2 +- xDripG5/Messages/GlucoseRxMessage.swift | 12 +++-- xDripG5/NSData.swift | 48 ------------------- xDripG5Tests/GlucoseRxMessageTests.swift | 54 +++++++++++++++++++++ xDripG5Tests/NSData.swift | 60 ++++++++++++++++++++++++ xDripG5Tests/fixtures.txt | 8 ---- xDripG5Tests/xDripG5Tests.swift | 37 --------------- 9 files changed, 132 insertions(+), 103 deletions(-) create mode 100644 xDripG5Tests/GlucoseRxMessageTests.swift create mode 100644 xDripG5Tests/NSData.swift delete mode 100644 xDripG5Tests/fixtures.txt delete mode 100644 xDripG5Tests/xDripG5Tests.swift diff --git a/xDripG5.podspec b/xDripG5.podspec index 7227645a..d755a1e7 100644 --- a/xDripG5.podspec +++ b/xDripG5.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "xDripG5" - s.version = "0.2.2" + s.version = "0.3.0" s.summary = "An interface for communicating with the G5 glucose transmitter over Bluetooth." s.description = <<-DESC diff --git a/xDripG5.xcodeproj/project.pbxproj b/xDripG5.xcodeproj/project.pbxproj index 9763ce1f..e1d1f2d9 100644 --- a/xDripG5.xcodeproj/project.pbxproj +++ b/xDripG5.xcodeproj/project.pbxproj @@ -12,7 +12,6 @@ 434FD68A1C3523A7000B4E2E /* CommonCrypto.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4337D7EA1C351B0B0016851F /* CommonCrypto.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 43CABDF71C3506F100005705 /* xDripG5.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CABDF61C3506F100005705 /* xDripG5.h */; settings = {ATTRIBUTES = (Public, ); }; }; 43CABDFE1C3506F100005705 /* xDripG5.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43CABDF31C3506F100005705 /* xDripG5.framework */; }; - 43CABE031C3506F100005705 /* xDripG5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43CABE021C3506F100005705 /* xDripG5Tests.swift */; }; 43CABE121C350B2800005705 /* BluetoothManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43CABE0E1C350B2800005705 /* BluetoothManager.swift */; }; 43CABE131C350B2800005705 /* BluetoothServices.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43CABE0F1C350B2800005705 /* BluetoothServices.swift */; }; 43CABE141C350B2800005705 /* NSData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43CABE101C350B2800005705 /* NSData.swift */; }; @@ -29,6 +28,8 @@ 43CABE2C1C350B3D00005705 /* TransmitterMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43CABE201C350B3D00005705 /* TransmitterMessage.swift */; }; 43CABE2D1C350B3D00005705 /* TransmitterTimeRxMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43CABE211C350B3D00005705 /* TransmitterTimeRxMessage.swift */; }; 43CABE2E1C350B3D00005705 /* TransmitterTimeTxMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43CABE221C350B3D00005705 /* TransmitterTimeTxMessage.swift */; }; + 43DC87C01C8B509B005BC30D /* NSData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43DC87BF1C8B509B005BC30D /* NSData.swift */; }; + 43DC87C21C8B520F005BC30D /* GlucoseRxMessageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43DC87C11C8B520F005BC30D /* GlucoseRxMessageTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -60,7 +61,6 @@ 43CABDF61C3506F100005705 /* xDripG5.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = xDripG5.h; sourceTree = ""; }; 43CABDF81C3506F100005705 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 43CABDFD1C3506F100005705 /* xDripG5Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = xDripG5Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 43CABE021C3506F100005705 /* xDripG5Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = xDripG5Tests.swift; sourceTree = ""; }; 43CABE041C3506F100005705 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 43CABE0E1C350B2800005705 /* BluetoothManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BluetoothManager.swift; sourceTree = ""; }; 43CABE0F1C350B2800005705 /* BluetoothServices.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BluetoothServices.swift; sourceTree = ""; }; @@ -78,6 +78,8 @@ 43CABE201C350B3D00005705 /* TransmitterMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransmitterMessage.swift; sourceTree = ""; }; 43CABE211C350B3D00005705 /* TransmitterTimeRxMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransmitterTimeRxMessage.swift; sourceTree = ""; }; 43CABE221C350B3D00005705 /* TransmitterTimeTxMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransmitterTimeTxMessage.swift; sourceTree = ""; }; + 43DC87BF1C8B509B005BC30D /* NSData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSData.swift; sourceTree = ""; }; + 43DC87C11C8B520F005BC30D /* GlucoseRxMessageTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlucoseRxMessageTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -137,8 +139,9 @@ 43CABE011C3506F100005705 /* xDripG5Tests */ = { isa = PBXGroup; children = ( - 43CABE021C3506F100005705 /* xDripG5Tests.swift */, 43CABE041C3506F100005705 /* Info.plist */, + 43DC87C11C8B520F005BC30D /* GlucoseRxMessageTests.swift */, + 43DC87BF1C8B509B005BC30D /* NSData.swift */, ); path = xDripG5Tests; sourceTree = ""; @@ -294,7 +297,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 43CABE031C3506F100005705 /* xDripG5Tests.swift in Sources */, + 43DC87C01C8B509B005BC30D /* NSData.swift in Sources */, + 43DC87C21C8B520F005BC30D /* GlucoseRxMessageTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/xDripG5/Info.plist b/xDripG5/Info.plist index 33d5c6da..f42ccf54 100644 --- a/xDripG5/Info.plist +++ b/xDripG5/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.2.2 + 0.3.0 CFBundleSignature ???? CFBundleVersion diff --git a/xDripG5/Messages/GlucoseRxMessage.swift b/xDripG5/Messages/GlucoseRxMessage.swift index 2ed9b263..ab7d9061 100644 --- a/xDripG5/Messages/GlucoseRxMessage.swift +++ b/xDripG5/Messages/GlucoseRxMessage.swift @@ -11,10 +11,10 @@ import Foundation public struct GlucoseRxMessage: TransmitterRxMessage { static let opcode: UInt8 = 0x31 - let glucoseIsDisplayOnly: Bool = false // TODO - let status: UInt8 - let sequence: UInt32 + public let status: UInt8 + public let sequence: UInt32 public let timestamp: UInt32 + public let glucoseIsDisplayOnly: Bool public let glucose: UInt16 public let state: UInt8 public let trend: Int8 @@ -25,7 +25,11 @@ public struct GlucoseRxMessage: TransmitterRxMessage { status = data[1] sequence = data[2...5] timestamp = data[6...9] - glucose = data[10...11] & 0xfff + + let glucoseBytes: UInt16 = data[10...11] + glucoseIsDisplayOnly = (glucoseBytes & 0xf000) > 0 + glucose = glucoseBytes & 0xfff + state = data[12] trend = data[13] } else { diff --git a/xDripG5/NSData.swift b/xDripG5/NSData.swift index 95cf26a7..5a532baa 100644 --- a/xDripG5/NSData.swift +++ b/xDripG5/NSData.swift @@ -61,52 +61,4 @@ public extension NSData { subscript(range: Range) -> NSData { return subdataWithRange(NSRange(range)) } - - public convenience init?(hexadecimalString: String) { - if let - chars = hexadecimalString.cStringUsingEncoding(NSUTF8StringEncoding), - mutableData = NSMutableData(capacity: chars.count / 2) - { - for i in 0..(start: UnsafePointer(bytes), count: length) - - let string = NSMutableString(capacity: length * 2) - - for byte in bytesCollection { - string.appendFormat("%02x", byte) - } - - return string as String - } } diff --git a/xDripG5Tests/GlucoseRxMessageTests.swift b/xDripG5Tests/GlucoseRxMessageTests.swift new file mode 100644 index 00000000..809f8563 --- /dev/null +++ b/xDripG5Tests/GlucoseRxMessageTests.swift @@ -0,0 +1,54 @@ +// +// GlucoseRxMessageTests.swift +// xDripG5 +// +// Created by Nathan Racklyeft on 3/5/16. +// Copyright © 2016 Nathan Racklyeft. All rights reserved. +// + +import XCTest +@testable import xDripG5 + + +class GlucoseRxMessageTests: XCTestCase { + + func testMessageData() { + let data = NSData(hexadecimalString: "3100680a00008a715700cc0006ffc42a")! + let message = GlucoseRxMessage(data: data)! + + XCTAssertEqual(0, message.status) + XCTAssertEqual(2664, message.sequence) + XCTAssertEqual(5730698, message.timestamp) + XCTAssertFalse(message.glucoseIsDisplayOnly) + XCTAssertEqual(204, message.glucose) + XCTAssertEqual(6, message.state) + XCTAssertEqual(-1, message.trend) + } + + func testNegativeTrend() { + let data = NSData(hexadecimalString: "31006f0a0000be7957007a0006e4818d")! + let message = GlucoseRxMessage(data: data)! + + XCTAssertEqual(0, message.status) + XCTAssertEqual(2671, message.sequence) + XCTAssertEqual(5732798, message.timestamp) + XCTAssertFalse(message.glucoseIsDisplayOnly) + XCTAssertEqual(122, message.glucose) + XCTAssertEqual(6, message.state) + XCTAssertEqual(-28, message.trend) + } + + func testDisplayOnly() { + let data = NSData(hexadecimalString: "3100700a0000f17a5700584006e3cee9")! + let message = GlucoseRxMessage(data: data)! + + XCTAssertEqual(0, message.status) + XCTAssertEqual(2672, message.sequence) + XCTAssertEqual(5733105, message.timestamp) + XCTAssertTrue(message.glucoseIsDisplayOnly) + XCTAssertEqual(88, message.glucose) + XCTAssertEqual(6, message.state) + XCTAssertEqual(-29, message.trend) + } + +} diff --git a/xDripG5Tests/NSData.swift b/xDripG5Tests/NSData.swift new file mode 100644 index 00000000..e3bfb4a3 --- /dev/null +++ b/xDripG5Tests/NSData.swift @@ -0,0 +1,60 @@ +// +// NSData.swift +// xDripG5 +// +// Created by Nathan Racklyeft on 3/5/16. +// Copyright © 2016 Nathan Racklyeft. All rights reserved. +// + +import Foundation + + +extension NSData { + public convenience init?(hexadecimalString: String) { + if let + chars = hexadecimalString.cStringUsingEncoding(NSUTF8StringEncoding), + mutableData = NSMutableData(capacity: chars.count / 2) + { + for i in 0..(start: UnsafePointer(bytes), count: length) + + let string = NSMutableString(capacity: length * 2) + + for byte in bytesCollection { + string.appendFormat("%02x", byte) + } + + return string as String + } +} \ No newline at end of file diff --git a/xDripG5Tests/fixtures.txt b/xDripG5Tests/fixtures.txt deleted file mode 100644 index 9f73c0a1..00000000 --- a/xDripG5Tests/fixtures.txt +++ /dev/null @@ -1,8 +0,0 @@ -3100680a 00008a71 5700cc00 06ffc42a -204, -1, 06 - -31006f0a 0000be79 57007a00 06e4818d -122, -28, 06 - -3100700a 0000f17a 57005840 06e3cee9 -88 (display only), -29, 06 diff --git a/xDripG5Tests/xDripG5Tests.swift b/xDripG5Tests/xDripG5Tests.swift deleted file mode 100644 index 6206a02a..00000000 --- a/xDripG5Tests/xDripG5Tests.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// xDripG5Tests.swift -// xDripG5Tests -// -// Created by Nathan Racklyeft on 12/30/15. -// Copyright © 2015 Nathan Racklyeft. All rights reserved. -// - -import XCTest -import CommonCrypto -@testable import xDripG5 - -class xDripG5Tests: XCTestCase { - - override func setUp() { - super.setUp() - // Put setup code here. This method is called before the invocation of each test method in the class. - } - - override func tearDown() { - // Put teardown code here. This method is called after the invocation of each test method in the class. - super.tearDown() - } - - func testExample() { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct results. - } - - func testPerformanceExample() { - // This is an example of a performance test case. - self.measureBlock { - // Put the code you want to measure the time of here. - } - } - -}