Skip to content

Commit

Permalink
Merge pull request #125 from ps2/dev
Browse files Browse the repository at this point in the history
Version 0.4.0
  • Loading branch information
loudnate authored Jun 21, 2016
2 parents b1e6a2e + 8f6d526 commit ede9e01
Show file tree
Hide file tree
Showing 91 changed files with 752 additions and 681 deletions.
8 changes: 3 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
language: objective-c
osx_image: xcode7.3
xcode_sdk:
- iphonesimulator9.3
xcode_sdk: iphonesimulator9.3
xcode_project: RileyLink.xcodeproj
xcode_scheme:
- RileyLink
xcode_scheme: RileyLink
before_script:
- carthage bootstrap
script:
- xcodebuild -project RileyLink.xcodeproj -scheme RileyLink -sdk iphonesimulator9.3 test
- xcodebuild -project RileyLink.xcodeproj -scheme RileyLink -sdk iphonesimulator9.3 test | xcpretty
35 changes: 30 additions & 5 deletions MinimedKit/Extensions/NSDateComponents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,38 @@ extension NSDateComponents {
convenience init(mySentryBytes: [UInt8]) {
self.init()

hour = Int(mySentryBytes[0])
hour = Int(mySentryBytes[0])
minute = Int(mySentryBytes[1])
second = Int(mySentryBytes[2])
year = Int(mySentryBytes[3]) + 2000
month = Int(mySentryBytes[4])
day = Int(mySentryBytes[5])
year = Int(mySentryBytes[3]) + 2000
month = Int(mySentryBytes[4])
day = Int(mySentryBytes[5])

calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)
}
}

convenience init(pumpEventData: NSData, offset: Int, length: Int = 5) {
self.init(pumpEventBytes: pumpEventData[offset..<offset + length])
}

convenience init(pumpEventBytes: [UInt8]) {
self.init()

if pumpEventBytes.count == 5 {
second = Int(pumpEventBytes[0] & 0b00111111)
minute = Int(pumpEventBytes[1] & 0b00111111)
hour = Int(pumpEventBytes[2] & 0b00011111)
day = Int(pumpEventBytes[3] & 0b00011111)
month = Int((pumpEventBytes[0] & 0b11000000) >> 4 +
(pumpEventBytes[1] & 0b11000000) >> 6)
year = Int(pumpEventBytes[4] & 0b01111111) + 2000
} else {
day = Int(pumpEventBytes[0] & 0b00011111)
month = Int((pumpEventBytes[0] & 0b11100000) >> 4 +
(pumpEventBytes[1] & 0b10000000) >> 7)
year = Int(pumpEventBytes[1] & 0b01111111) + 2000
}

calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)
}
}
22 changes: 22 additions & 0 deletions MinimedKit/Extensions/NSDateFormatter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// NSDateFormatter.swift
// RileyLink
//
// Created by Nate Racklyeft on 6/15/16.
// Copyright © 2016 Pete Schwamb. All rights reserved.
//

import Foundation


extension NSDateFormatter {
class func ISO8601DateFormatter() -> Self {
let formatter = self.init()
formatter.calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierISO8601)
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssX"

return formatter
}
}
11 changes: 6 additions & 5 deletions MinimedKit/HistoryPage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,18 @@ public class HistoryPage {
offset += 1
continue
}
guard let event = matchEvent(offset) else {
guard var event = matchEvent(offset) else {
events = [PumpEvent]()
throw Error.UnknownEventType(eventType: pageData[offset] as UInt8)
}
if event.dynamicType == BolusNormalPumpEvent.self && unabsorbedInsulinRecord != nil {
let bolus: BolusNormalPumpEvent = event as! BolusNormalPumpEvent

if unabsorbedInsulinRecord != nil, var bolus = event as? BolusNormalPumpEvent {
bolus.unabsorbedInsulinRecord = unabsorbedInsulinRecord
unabsorbedInsulinRecord = nil
event = bolus
}
if event.dynamicType == UnabsorbedInsulinPumpEvent.self {
unabsorbedInsulinRecord = event as? UnabsorbedInsulinPumpEvent
if let event = event as? UnabsorbedInsulinPumpEvent {
unabsorbedInsulinRecord = event
} else {
tempEvents.append(event)
}
Expand Down
2 changes: 1 addition & 1 deletion MinimedKit/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.3.3</string>
<string>0.4.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down
3 changes: 3 additions & 0 deletions MinimedKit/PumpEventType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public enum PumpEventType: UInt8 {
case CalBGForPH = 0x0a
case AlarmSensor = 0x0b
case ClearAlarm = 0x0c
case SelectBasalProfile = 0x14
case TempBasalDuration = 0x16
case ChangeTime = 0x17
case JournalEntryPumpLowBattery = 0x19
Expand Down Expand Up @@ -176,6 +177,8 @@ public enum PumpEventType: UInt8 {
return DeleteOtherDeviceIDPumpEvent.self
case .ChangeCaptureEventEnable:
return ChangeCaptureEventEnablePumpEvent.self
case .SelectBasalProfile:
return SelectBasalProfilePumpEvent.self
}
}
}
Expand Down
9 changes: 4 additions & 5 deletions MinimedKit/PumpEvents/AlarmClockReminderPumpEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,23 @@

import Foundation

public class AlarmClockReminderPumpEvent: PumpEvent {
public struct AlarmClockReminderPumpEvent: TimestampedPumpEvent {
public let length: Int
let timestamp: NSDateComponents
public let timestamp: NSDateComponents

public required init?(availableData: NSData, pumpModel: PumpModel) {
public init?(availableData: NSData, pumpModel: PumpModel) {
length = 7

guard length <= availableData.length else {
return nil
}

timestamp = TimeFormat.parse5ByteDate(availableData, offset: 2)
timestamp = NSDateComponents(pumpEventData: availableData, offset: 2)
}

public var dictionaryRepresentation: [String: AnyObject] {
return [
"_type": "AlarmClockReminder",
"timestamp": TimeFormat.timestampStr(timestamp),
]
}
}
9 changes: 4 additions & 5 deletions MinimedKit/PumpEvents/AlarmSensorPumpEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,23 @@

import Foundation

public class AlarmSensorPumpEvent: PumpEvent {
public struct AlarmSensorPumpEvent: TimestampedPumpEvent {
public let length: Int
let timestamp: NSDateComponents
public let timestamp: NSDateComponents

public required init?(availableData: NSData, pumpModel: PumpModel) {
public init?(availableData: NSData, pumpModel: PumpModel) {
length = 8

guard length <= availableData.length else {
return nil
}

timestamp = TimeFormat.parse5ByteDate(availableData, offset: 2)
timestamp = NSDateComponents(pumpEventData: availableData, offset: 2)
}

public var dictionaryRepresentation: [String: AnyObject] {
return [
"_type": "AlarmSensor",
"timestamp": TimeFormat.timestampStr(timestamp),
]
}
}
7 changes: 3 additions & 4 deletions MinimedKit/PumpEvents/BGReceivedPumpEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

import Foundation

public class BGReceivedPumpEvent: PumpEvent {
public struct BGReceivedPumpEvent: TimestampedPumpEvent {
public let length: Int
public let timestamp: NSDateComponents
public let amount: Int
public let meter: String

public required init?(availableData: NSData, pumpModel: PumpModel) {
public init?(availableData: NSData, pumpModel: PumpModel) {
length = 10

guard length <= availableData.length else {
Expand All @@ -25,15 +25,14 @@ public class BGReceivedPumpEvent: PumpEvent {
return Int(availableData[idx] as UInt8)
}

timestamp = TimeFormat.parse5ByteDate(availableData, offset: 2)
timestamp = NSDateComponents(pumpEventData: availableData, offset: 2)
amount = (d(1) << 3) + (d(4) >> 5)
meter = availableData.subdataWithRange(NSMakeRange(7, 3)).hexadecimalString
}

public var dictionaryRepresentation: [String: AnyObject] {
return [
"_type": "BGReceivedPumpEvent",
"timestamp": TimeFormat.timestampStr(timestamp),
"amount": amount,
"meter": meter,
]
Expand Down
7 changes: 3 additions & 4 deletions MinimedKit/PumpEvents/BasalProfileStartPumpEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@

import Foundation

public class BasalProfileStartPumpEvent: TimestampedPumpEvent {
public struct BasalProfileStartPumpEvent: TimestampedPumpEvent {
public let length: Int
public let timestamp: NSDateComponents
let rate: Double
let profileIndex: Int
let offset: Int


public required init?(availableData: NSData, pumpModel: PumpModel) {
public init?(availableData: NSData, pumpModel: PumpModel) {
length = 10

guard length <= availableData.length else {
Expand All @@ -27,7 +27,7 @@ public class BasalProfileStartPumpEvent: TimestampedPumpEvent {
return Int(availableData[idx] as UInt8)
}

timestamp = TimeFormat.parse5ByteDate(availableData, offset: 2)
timestamp = NSDateComponents(pumpEventData: availableData, offset: 2)
rate = Double(d(8)) / 40.0
profileIndex = d(1)
offset = d(7) * 30 * 1000 * 60
Expand All @@ -36,7 +36,6 @@ public class BasalProfileStartPumpEvent: TimestampedPumpEvent {
public var dictionaryRepresentation: [String: AnyObject] {
return [
"_type": "BasalProfileStart",
"timestamp": TimeFormat.timestampStr(timestamp),
"offset": offset,
"rate": rate,
"profileIndex": profileIndex,
Expand Down
9 changes: 4 additions & 5 deletions MinimedKit/PumpEvents/BatteryPumpEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,23 @@

import Foundation

public class BatteryPumpEvent: PumpEvent {
public struct BatteryPumpEvent: TimestampedPumpEvent {
public let length: Int
let timestamp: NSDateComponents
public let timestamp: NSDateComponents

public required init?(availableData: NSData, pumpModel: PumpModel) {
public init?(availableData: NSData, pumpModel: PumpModel) {
length = 7

guard length <= availableData.length else {
return nil
}

timestamp = TimeFormat.parse5ByteDate(availableData, offset: 2)
timestamp = NSDateComponents(pumpEventData: availableData, offset: 2)
}

public var dictionaryRepresentation: [String: AnyObject] {
return [
"_type": "Battery",
"timestamp": TimeFormat.timestampStr(timestamp),
]
}
}
64 changes: 42 additions & 22 deletions MinimedKit/PumpEvents/BolusNormalPumpEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,45 @@

import Foundation

public class BolusNormalPumpEvent: TimestampedPumpEvent {
public struct BolusNormalPumpEvent: TimestampedPumpEvent {

public enum BolusType: String {
case Normal
case Square
}

public let length: Int
public let timestamp: NSDateComponents
public var unabsorbedInsulinRecord: UnabsorbedInsulinPumpEvent?
public let amount: Double
public let programmed: Double
public let unabsorbedInsulinTotal: Double
public let bolusType: String
public let duration: Int

public required init?(availableData: NSData, pumpModel: PumpModel) {
public let type: BolusType
public let duration: NSTimeInterval

/*
It takes a MM pump about 40s to deliver 1 Unit while bolusing
See: http://www.healthline.com/diabetesmine/ask-dmine-speed-insulin-pumps#3
*/
private let deliveryUnitsPerMinute = 1.5

// The actual expected time of delivery, based on bolus speed
public var deliveryTime: NSTimeInterval {
if duration > 0 {
return duration
} else {
return NSTimeInterval(minutes: programmed / deliveryUnitsPerMinute)
}
}

public init?(availableData: NSData, pumpModel: PumpModel) {

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

func insulinDecode(a: Int, b: Int) -> Double {
return Double((a << 8) + b) / 40.0
func decodeInsulinFromBytes(bytes: [UInt8]) -> Double {
return Double(Int(bigEndianBytes: bytes)) / Double(pumpModel.strokesPerUnit)
}

if pumpModel.larger {
Expand All @@ -39,29 +60,28 @@ public class BolusNormalPumpEvent: TimestampedPumpEvent {
}

if pumpModel.larger {
timestamp = TimeFormat.parse5ByteDate(availableData, offset: 8)
amount = insulinDecode(d(3), b: d(4))
programmed = insulinDecode(d(1), b: d(2))
unabsorbedInsulinTotal = insulinDecode(d(5), b: d(6))
duration = d(7) * 30
timestamp = NSDateComponents(pumpEventData: availableData, offset: 8)
programmed = decodeInsulinFromBytes(availableData[1...2])
amount = decodeInsulinFromBytes(availableData[3...4])
unabsorbedInsulinTotal = decodeInsulinFromBytes(availableData[5...6])
duration = NSTimeInterval(minutes: 30 * doubleValueFromDataAtIndex(7))
} else {
timestamp = TimeFormat.parse5ByteDate(availableData, offset: 4)
amount = Double(d(2))/10.0
programmed = Double(d(1))/10.0
duration = d(3) * 30
timestamp = NSDateComponents(pumpEventData: availableData, offset: 4)
programmed = decodeInsulinFromBytes([availableData[1]])
amount = decodeInsulinFromBytes([availableData[2]])
duration = NSTimeInterval(minutes: 30 * doubleValueFromDataAtIndex(3))
unabsorbedInsulinTotal = 0
}
bolusType = duration > 0 ? "square" : "normal"
type = duration > 0 ? .Square : .Normal
}

public var dictionaryRepresentation: [String: AnyObject] {
var dictionary: [String: AnyObject] = [
"_type": "BolusNormal",
"amount": amount,
"programmed": programmed,
"type": bolusType,
"timestamp": TimeFormat.timestampStr(timestamp),
]
"type": type.rawValue,
]

if let unabsorbedInsulinRecord = unabsorbedInsulinRecord {
dictionary["appended"] = unabsorbedInsulinRecord.dictionaryRepresentation
Expand Down
Loading

0 comments on commit ede9e01

Please sign in to comment.