Skip to content

Commit

Permalink
Merge pull request #296 from tmecklem/x22-sensor-timestamp-refinement
Browse files Browse the repository at this point in the history
X22 sensor timestamp refinement
  • Loading branch information
ps2 authored Dec 12, 2016
2 parents ed83be2 + 1690b10 commit 92e801a
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import Foundation

public struct GlucoseSensorDataGlucoseEvent: RelativeTimestampedGlucoseEvent {
public struct GlucoseSensorDataGlucoseEvent: SensorValueGlucoseEvent {
public let length: Int
public let rawData: Data
public let sgv: Int
Expand Down
15 changes: 0 additions & 15 deletions MinimedKit/GlucoseEvents/ReferenceTimestampedGlucoseEvent.swift

This file was deleted.

2 changes: 1 addition & 1 deletion MinimedKit/GlucoseEvents/SensorDataHighGlucoseEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import Foundation

public struct SensorDataHighGlucoseEvent: RelativeTimestampedGlucoseEvent {
public struct SensorDataHighGlucoseEvent: SensorValueGlucoseEvent {
public let length: Int
public let rawData: Data
public let sgv: Int
Expand Down
2 changes: 1 addition & 1 deletion MinimedKit/GlucoseEvents/SensorDataLowGlucoseEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import Foundation

public struct SensorDataLowGlucoseEvent: RelativeTimestampedGlucoseEvent {
public struct SensorDataLowGlucoseEvent: SensorValueGlucoseEvent {
public let length: Int
public let rawData: Data
public let sgv: Int
Expand Down
46 changes: 28 additions & 18 deletions MinimedKit/GlucoseEvents/SensorTimestampGlucoseEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,32 @@

import Foundation

public struct SensorTimestampGlucoseEvent: ReferenceTimestampedGlucoseEvent {
public enum SensorTimestampType: String {
case lastRf
case pageEnd
case gap
case unknown

init(code: UInt8) {
switch code {
case 0x00:
self = .lastRf
case 0x01:
self = .pageEnd
case 0x02:
self = .gap
default:
self = .unknown
}
}

}

public struct SensorTimestampGlucoseEvent: GlucoseEvent {
public let length: Int
public let rawData: Data
public let timestamp: DateComponents
private let timestampType: String
public let timestampType: SensorTimestampType

public init?(availableData: Data, relativeTimestamp: DateComponents) {
length = 5
Expand All @@ -21,24 +42,13 @@ public struct SensorTimestampGlucoseEvent: ReferenceTimestampedGlucoseEvent {
return nil
}

func d(_ idx:Int) -> Int {
return Int(availableData[idx] as UInt8)
}

rawData = availableData.subdata(in: 0..<length)
timestamp = DateComponents(glucoseEventBytes: availableData.subdata(in: 1..<5))

switch (d(3) >> 5 & 0b00000011) {
case 0x00:
timestampType = "last_rf"
case 0x01:
timestampType = "page_end"
case 0x02:
timestampType = "gap"
default:
timestampType = "unknown"
}

timestampType = SensorTimestampType(code: availableData[3] >> 5 & 0b00000011)
}

public func isForwardOffsetReference() -> Bool {
return timestampType == .lastRf || timestampType == .pageEnd
}

public var dictionaryRepresentation: [String: Any] {
Expand Down
17 changes: 17 additions & 0 deletions MinimedKit/GlucoseEvents/SensorValueGlucoseEvent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// SensorValueGlucoseEvent.swift
// RileyLink
//
// Created by Timothy Mecklem on 12/11/16.
// Copyright © 2016 Pete Schwamb. All rights reserved.
//

import Foundation

/// An event that contains an sgv
public protocol SensorValueGlucoseEvent: RelativeTimestampedGlucoseEvent {

var sgv: Int {
get
}
}
22 changes: 10 additions & 12 deletions MinimedKit/GlucosePage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ public class GlucosePage {
//opcodes are at the end of each event
let pageData = Data(pageData.subdata(in: 0..<1022).reversed())

var needsTimestamp = false
var offset = 0
let length = pageData.count
var events = [GlucoseEvent]()
Expand Down Expand Up @@ -64,16 +63,16 @@ public class GlucosePage {

func initialTimestamp() -> DateComponents? {
var tempOffset = offset
var relativeEventCount = 0
var relativeEventCount: Double = 0
while tempOffset < length {
let event = matchEvent(tempOffset, relativeTimestamp: DateComponents())
if event is RelativeTimestampedGlucoseEvent {
relativeEventCount += 1
} else if let event = event as? ReferenceTimestampedGlucoseEvent {
let offsetDate = calendar.date(byAdding: Calendar.Component.minute, value: 5 * relativeEventCount, to: event.timestamp.date!)!
var relativeTimestamp = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: offsetDate)
relativeTimestamp.calendar = calendar
return relativeTimestamp
} else if let sensorTimestampEvent = event as? SensorTimestampGlucoseEvent,
relativeEventCount == 0 || sensorTimestampEvent.isForwardOffsetReference() {

let offsetDate = sensorTimestampEvent.timestamp.date!.addingTimeInterval(TimeInterval(minutes: relativeEventCount * 5))
return calendar.dateComponents([.year, .month, .day, .hour, .minute, .calendar], from: offsetDate)
} else if !(event is NineteenSomethingGlucoseEvent /* seems to be a filler byte */ || event is DataEndGlucoseEvent) {
return nil
}
Expand All @@ -97,19 +96,18 @@ public class GlucosePage {
}

let event = matchEvent(offset, relativeTimestamp: relativeTimestamp)
if let event = event as? ReferenceTimestampedGlucoseEvent {
if let event = event as? SensorTimestampGlucoseEvent {
relativeTimestamp = event.timestamp
} else if event is RelativeTimestampedGlucoseEvent {
let offsetDate = calendar.date(byAdding: Calendar.Component.minute, value: -5, to: relativeTimestamp.date!)!
relativeTimestamp = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: offsetDate)
relativeTimestamp.calendar = calendar
let offsetDate = relativeTimestamp.date!.addingTimeInterval(TimeInterval(minutes: -5))
relativeTimestamp = calendar.dateComponents([.year, .month, .day, .hour, .minute, .calendar], from: offsetDate)
}

events.insert(event, at: 0)

offset += event.length
}
self.needsTimestamp = false
self.events = events
self.needsTimestamp = needsTimestamp
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class SensorTimestampGlucoseEventTests: XCTestCase {
let rawData = Data(hexadecimalString: "0814B62810")!
let subject = SensorTimestampGlucoseEvent(availableData: rawData, relativeTimestamp: DateComponents())!

XCTAssertEqual(subject.dictionaryRepresentation["timestampType"] as! String, "page_end")
XCTAssertEqual(subject.timestampType, .pageEnd)

let expectedTimestamp = DateComponents(calendar: Calendar.current,
year: 2016, month: 02, day: 08, hour: 20, minute: 54)
Expand All @@ -37,7 +37,7 @@ class SensorTimestampGlucoseEventTests: XCTestCase {
let rawData = Data(hexadecimalString: "088d9b5d0c")!
let subject = SensorTimestampGlucoseEvent(availableData: rawData, relativeTimestamp: DateComponents())!

XCTAssertEqual(subject.dictionaryRepresentation["timestampType"] as! String, "gap")
XCTAssertEqual(subject.timestampType, .gap)

let expectedTimestamp = DateComponents(calendar: Calendar.current,
year: 2012, month: 10, day: 29, hour: 13, minute: 27)
Expand All @@ -48,7 +48,7 @@ class SensorTimestampGlucoseEventTests: XCTestCase {
let rawData = Data(hexadecimalString: "088d9b1d0c")!
let subject = SensorTimestampGlucoseEvent(availableData: rawData, relativeTimestamp: DateComponents())!

XCTAssertEqual(subject.dictionaryRepresentation["timestampType"] as! String, "last_rf")
XCTAssertEqual(subject.timestampType, .lastRf)

let expectedTimestamp = DateComponents(calendar: Calendar.current,
year: 2012, month: 10, day: 29, hour: 13, minute: 27)
Expand Down
20 changes: 19 additions & 1 deletion MinimedKitTests/GlucosePageTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ class GlucosePageTests: XCTestCase {

func testDoesNotNeedTimestamp() {
do {
let pageData = Data(hexadecimalString: "1053b3940853535A".leftPadding(toLength: 2048, withPad: "0"))!
//sensor timestamp with timestampType of .lastRf
let pageData = Data(hexadecimalString: "1013b39408534232".leftPadding(toLength: 2048, withPad: "0"))!
let page = try GlucosePage(pageData: pageData)

XCTAssertFalse(page.needsTimestamp)
Expand All @@ -97,4 +98,21 @@ class GlucosePageTests: XCTestCase {
XCTFail("Unexpected exception...")
}
}

func testLastSensorTimestampTypeGapNeedsTimestamp() {
do {
//sensor timestamp with timestampType of .gap
let pageData = Data(hexadecimalString: "1053b3940853535A".leftPadding(toLength: 2048, withPad: "0"))!
let page = try GlucosePage(pageData: pageData)

XCTAssertTrue(page.needsTimestamp)

} catch GlucosePage.GlucosePageError.invalidCRC {
XCTFail("page decoding threw invalid crc")
} catch GlucosePage.GlucosePageError.unknownEventType(let eventType) {
XCTFail("unknown event type" + String(eventType))
} catch {
XCTFail("Unexpected exception...")
}
}
}
2 changes: 1 addition & 1 deletion NightscoutUploadKit/NightscoutEntry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class NightscoutEntry: DictionaryRepresentable {
}

convenience init?(event: TimestampedGlucoseEvent, device: String) {
if let glucoseSensorData = event.glucoseEvent as? GlucoseSensorDataGlucoseEvent {
if let glucoseSensorData = event.glucoseEvent as? SensorValueGlucoseEvent {
self.init(glucose: glucoseSensorData.sgv, timestamp: event.date, device: device, glucoseType: .Sensor)
} else {
return nil
Expand Down
8 changes: 4 additions & 4 deletions RileyLink.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@
54BC44981DB47D5300340EED /* SensorSyncGlucoseEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BC44971DB47D5300340EED /* SensorSyncGlucoseEvent.swift */; };
54BC449A1DB47DFE00340EED /* NineteenSomethingGlucoseEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BC44991DB47DFE00340EED /* NineteenSomethingGlucoseEvent.swift */; };
54BC449C1DB483F700340EED /* RelativeTimestampedGlucoseEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BC449B1DB483F700340EED /* RelativeTimestampedGlucoseEvent.swift */; };
54BC449E1DB484BD00340EED /* ReferenceTimestampedGlucoseEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BC449D1DB484BD00340EED /* ReferenceTimestampedGlucoseEvent.swift */; };
54BC44A11DB6F74300340EED /* BatteryChangeGlucoseEventTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BC44A01DB6F74300340EED /* BatteryChangeGlucoseEventTests.swift */; };
54BC44A31DB7021B00340EED /* SensorStatusGlucoseEventTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BC44A21DB7021B00340EED /* SensorStatusGlucoseEventTests.swift */; };
54BC44A51DB702C800340EED /* DateTimeChangeGlucoseEventTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BC44A41DB702C800340EED /* DateTimeChangeGlucoseEventTests.swift */; };
Expand All @@ -132,6 +131,7 @@
54BC44B51DB7184D00340EED /* NSStringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BC44B41DB7184D00340EED /* NSStringExtensions.swift */; };
54BC44B71DB81B5100340EED /* GetGlucosePageMessageBodyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BC44B61DB81B5100340EED /* GetGlucosePageMessageBodyTests.swift */; };
54BC44B91DB81D6100340EED /* GetGlucosePageMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BC44B81DB81D6100340EED /* GetGlucosePageMessageBody.swift */; };
54DA4E851DFDC0A70007F489 /* SensorValueGlucoseEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54DA4E841DFDC0A70007F489 /* SensorValueGlucoseEvent.swift */; };
C10AB08D1C855613000F102E /* FindDeviceMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C10AB08C1C855613000F102E /* FindDeviceMessageBody.swift */; };
C10AB08F1C855F34000F102E /* DeviceLinkMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C10AB08E1C855F34000F102E /* DeviceLinkMessageBody.swift */; };
C10D9BC41C8269D500378342 /* MinimedKit.h in Headers */ = {isa = PBXBuildFile; fileRef = C10D9BC31C8269D500378342 /* MinimedKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
Expand Down Expand Up @@ -548,7 +548,6 @@
54BC44971DB47D5300340EED /* SensorSyncGlucoseEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SensorSyncGlucoseEvent.swift; sourceTree = "<group>"; };
54BC44991DB47DFE00340EED /* NineteenSomethingGlucoseEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NineteenSomethingGlucoseEvent.swift; sourceTree = "<group>"; };
54BC449B1DB483F700340EED /* RelativeTimestampedGlucoseEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RelativeTimestampedGlucoseEvent.swift; sourceTree = "<group>"; };
54BC449D1DB484BD00340EED /* ReferenceTimestampedGlucoseEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReferenceTimestampedGlucoseEvent.swift; sourceTree = "<group>"; };
54BC44A01DB6F74300340EED /* BatteryChangeGlucoseEventTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BatteryChangeGlucoseEventTests.swift; sourceTree = "<group>"; };
54BC44A21DB7021B00340EED /* SensorStatusGlucoseEventTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SensorStatusGlucoseEventTests.swift; sourceTree = "<group>"; };
54BC44A41DB702C800340EED /* DateTimeChangeGlucoseEventTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateTimeChangeGlucoseEventTests.swift; sourceTree = "<group>"; };
Expand All @@ -562,6 +561,7 @@
54BC44B41DB7184D00340EED /* NSStringExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSStringExtensions.swift; sourceTree = "<group>"; };
54BC44B61DB81B5100340EED /* GetGlucosePageMessageBodyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GetGlucosePageMessageBodyTests.swift; sourceTree = "<group>"; };
54BC44B81DB81D6100340EED /* GetGlucosePageMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GetGlucosePageMessageBody.swift; sourceTree = "<group>"; };
54DA4E841DFDC0A70007F489 /* SensorValueGlucoseEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SensorValueGlucoseEvent.swift; sourceTree = "<group>"; };
C10AB08C1C855613000F102E /* FindDeviceMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FindDeviceMessageBody.swift; sourceTree = "<group>"; };
C10AB08E1C855F34000F102E /* DeviceLinkMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeviceLinkMessageBody.swift; sourceTree = "<group>"; };
C10D9BC11C8269D500378342 /* MinimedKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MinimedKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -966,7 +966,6 @@
54BC44771DB46C7D00340EED /* GlucoseEvent.swift */,
54BC447D1DB4753A00340EED /* GlucoseSensorDataGlucoseEvent.swift */,
54BC44991DB47DFE00340EED /* NineteenSomethingGlucoseEvent.swift */,
54BC449D1DB484BD00340EED /* ReferenceTimestampedGlucoseEvent.swift */,
54BC449B1DB483F700340EED /* RelativeTimestampedGlucoseEvent.swift */,
54BC44831DB476F600340EED /* SensorCalFactorGlucoseEvent.swift */,
54BC448B1DB47BEA00340EED /* SensorCalGlucoseEvent.swift */,
Expand All @@ -977,6 +976,7 @@
54BC44931DB47CFB00340EED /* SensorStatusGlucoseEvent.swift */,
54BC44971DB47D5300340EED /* SensorSyncGlucoseEvent.swift */,
54BC448F1DB47C7400340EED /* SensorTimestampGlucoseEvent.swift */,
54DA4E841DFDC0A70007F489 /* SensorValueGlucoseEvent.swift */,
54BC44891DB47BA500340EED /* SensorWeakSignalGlucoseEvent.swift */,
54BC447F1DB4762200340EED /* TenSomethingGlucoseEvent.swift */,
54A840D01DB85D0600B1F202 /* UnknownGlucoseEvent.swift */,
Expand Down Expand Up @@ -2006,7 +2006,6 @@
C1274F861D8242BE0002912B /* PumpRegion.swift in Sources */,
C15AF2AF1D7498930031FC9D /* RestoreMystery54PumpEvent.swift in Sources */,
C10AB08D1C855613000F102E /* FindDeviceMessageBody.swift in Sources */,
54BC449E1DB484BD00340EED /* ReferenceTimestampedGlucoseEvent.swift in Sources */,
545AEFB41DF5D99700DF9433 /* SensorDataLowGlucoseEvent.swift in Sources */,
C1711A5A1C952D2900CB25BD /* GetPumpModelCarelinkMessageBody.swift in Sources */,
C1EB955D1C887FE5002517DF /* HistoryPage.swift in Sources */,
Expand Down Expand Up @@ -2048,6 +2047,7 @@
C1842C011C8FA45100DB42AC /* JournalEntryPumpLowBatteryPumpEvent.swift in Sources */,
54BC447E1DB4753A00340EED /* GlucoseSensorDataGlucoseEvent.swift in Sources */,
C1842BBD1C8E7C6E00DB42AC /* PumpEvent.swift in Sources */,
54DA4E851DFDC0A70007F489 /* SensorValueGlucoseEvent.swift in Sources */,
C1842BCB1C8F9A7200DB42AC /* RewindPumpEvent.swift in Sources */,
C1842BCD1C8F9BBD00DB42AC /* PrimePumpEvent.swift in Sources */,
C1842C071C8FA45100DB42AC /* ClearAlarmPumpEvent.swift in Sources */,
Expand Down
6 changes: 3 additions & 3 deletions RileyLinkKit/PumpOpsSynchronous.swift
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ class PumpOpsSynchronous {
logGlucoseHistory(pageData: pageData, pageNum: pageNum)
page = try GlucosePage(pageData: pageData)

if page.needsTimestamp {
if page.needsTimestamp && pageNum == startPage {
NSLog(String(format: "GlucosePage %02d needs a new sensor timestamp, writing...", pageNum))
let _ = try writeGlucoseHistoryTimestamp()

Expand All @@ -606,7 +606,7 @@ class PumpOpsSynchronous {
}

if let date = timestamp.date {
if date < startDate && event is ReferenceTimestampedGlucoseEvent {
if date < startDate && event is SensorTimestampGlucoseEvent {
NSLog("Found reference event at (%@) to be before startDate(%@)", date as NSDate, startDate as NSDate);
break pages
} else {
Expand Down Expand Up @@ -662,7 +662,7 @@ class PumpOpsSynchronous {

internal func writeGlucoseHistoryTimestamp() throws -> Void {
let shortWriteTimestamp = makePumpMessage(to: .writeGlucoseHistoryTimestamp)
let shortResponse = try sendAndListen(shortWriteTimestamp, timeoutMS: 12000, repeatCount: 255, msBetweenPackets: 0, retryCount: 0)
let shortResponse = try sendAndListen(shortWriteTimestamp, timeoutMS: 12000)

if shortResponse.messageType == .pumpAck {
return
Expand Down

0 comments on commit 92e801a

Please sign in to comment.