diff --git a/G7SensorKit/Messages/G7GlucoseMessage.swift b/G7SensorKit/Messages/G7GlucoseMessage.swift index e0594a3..2aac30a 100644 --- a/G7SensorKit/Messages/G7GlucoseMessage.swift +++ b/G7SensorKit/Messages/G7GlucoseMessage.swift @@ -10,8 +10,8 @@ import Foundation import LoopKit public struct G7GlucoseMessage: SensorMessage, Equatable { - //public let status: UInt8 - //public let sequence: UInt32 + /// Nonzero when the sensor has no current reading, e.g. 0x80 from a failed sensor; glucose is then nil. + public let status: UInt8 public let glucose: UInt16? public let predicted: UInt16? public let glucoseIsDisplayOnly: Bool @@ -84,9 +84,7 @@ public struct G7GlucoseMessage: SensorMessage, Equatable { return nil } - guard data[1] == 00 else { - return nil - } + status = data[1] messageTimestamp = data[2..<6].toInt() @@ -95,7 +93,7 @@ public struct G7GlucoseMessage: SensorMessage, Equatable { age = data[10..<12].to(UInt16.self) let glucoseData = data[12..<14].to(UInt16.self) - if glucoseData != 0xffff { + if glucoseData != 0xffff, status == 0 { glucose = glucoseData & 0xfff glucoseIsDisplayOnly = (data[18] & 0x10) > 0 } else { @@ -104,7 +102,7 @@ public struct G7GlucoseMessage: SensorMessage, Equatable { } let predictionData = data[16..<18].to(UInt16.self) - if predictionData != 0xffff { + if predictionData != 0xffff, status == 0 { predicted = predictionData & 0xfff } else { predicted = nil @@ -112,7 +110,7 @@ public struct G7GlucoseMessage: SensorMessage, Equatable { algorithmState = AlgorithmState(rawValue: data[14]) - if data[15] == 0x7f { + if data[15] == 0x7f || status != 0 { trend = nil } else { trend = Double(Int8(bitPattern: data[15])) / 10 @@ -125,6 +123,6 @@ public struct G7GlucoseMessage: SensorMessage, Equatable { extension G7GlucoseMessage: CustomDebugStringConvertible { public var debugDescription: String { - return "G7GlucoseMessage(glucose:\(String(describing: glucose)), sequence:\(sequence) glucoseIsDisplayOnly:\(glucoseIsDisplayOnly) state:\(String(describing: algorithmState)) messageTimestamp:\(messageTimestamp) age:\(age), data:\(data.hexadecimalString))" + return "G7GlucoseMessage(status:\(status) glucose:\(String(describing: glucose)), sequence:\(sequence) glucoseIsDisplayOnly:\(glucoseIsDisplayOnly) state:\(String(describing: algorithmState)) messageTimestamp:\(messageTimestamp) age:\(age), data:\(data.hexadecimalString))" } } diff --git a/G7SensorKitTests/G7GlucoseMessageTests.swift b/G7SensorKitTests/G7GlucoseMessageTests.swift index 5d61445..dc5cafa 100644 --- a/G7SensorKitTests/G7GlucoseMessageTests.swift +++ b/G7SensorKitTests/G7GlucoseMessageTests.swift @@ -127,6 +127,21 @@ final class G7GlucoseMessageTests: XCTestCase { XCTAssertEqual(907385, message.glucoseTimestamp) } + func testFailedSensorStatusStillReportsAlgorithmState() { + // A failed sensor keeps answering with status 0x80 and its last reading, 103 mg/dL from 2.7 h earlier. + let data = Data(hexadecimalString: "4e80856f0a00f6010001f32567001b02670000")! + let message = G7GlucoseMessage(data: data)! + XCTAssertEqual(0x80, message.status) + XCTAssertEqual(.known(.transmitterFailed), message.algorithmState) + XCTAssertTrue(message.algorithmState.sensorFailed) + XCTAssertNil(message.glucose) + XCTAssertNil(message.predicted) + XCTAssertNil(message.trend) + XCTAssertEqual(683909, message.messageTimestamp) + XCTAssertEqual(9715, message.age) + XCTAssertEqual(502, message.sequence) + } + func testBackfill() { let data = Data(hexadecimalString: "cf5802008f00060f10")! let message = G7BackfillMessage(data: data)!