diff --git a/G7SensorKit/G7CGMManager/G7CGMManager.swift b/G7SensorKit/G7CGMManager/G7CGMManager.swift index 096f018..3fdc27b 100644 --- a/G7SensorKit/G7CGMManager/G7CGMManager.swift +++ b/G7SensorKit/G7CGMManager/G7CGMManager.swift @@ -113,8 +113,8 @@ public class G7CGMManager: CGMManager { } public var lifetime: TimeInterval { - if let sessionLength = state.extendedVersion?.sessionDuration { - return sessionLength - gracePeriod + if let sessionLength = state.extendedVersion?.sessionLength { + return sessionLength - G7Sensor.gracePeriod } else { return G7Sensor.defaultLifetime } @@ -124,10 +124,6 @@ public class G7CGMManager: CGMManager { state.extendedVersion?.warmupDuration ?? G7Sensor.defaultWarmupDuration } - public var gracePeriod: TimeInterval { - state.extendedVersion?.gracePeriodDuration ?? G7Sensor.defaultGracePeriod - } - public var sensorExpiresAt: Date? { guard let activatedAt = sensorActivatedAt else { return nil @@ -139,7 +135,7 @@ public class G7CGMManager: CGMManager { guard let activatedAt = sensorActivatedAt else { return nil } - return activatedAt.addingTimeInterval(lifetime + gracePeriod) + return activatedAt.addingTimeInterval(lifetime + G7Sensor.gracePeriod) } @@ -316,7 +312,7 @@ extension G7CGMManager: G7SensorDelegate { date: activatedAt, type: .sensorStart, deviceIdentifier: name, - expectedLifetime: lifetime + gracePeriod, + expectedLifetime: lifetime + G7Sensor.gracePeriod, warmupPeriod: warmupDuration ) delegate.notify { delegate in diff --git a/G7SensorKit/G7CGMManager/G7Sensor.swift b/G7SensorKit/G7CGMManager/G7Sensor.swift index c3bf75a..b7c7023 100644 --- a/G7SensorKit/G7CGMManager/G7Sensor.swift +++ b/G7SensorKit/G7CGMManager/G7Sensor.swift @@ -66,7 +66,7 @@ public enum G7SensorLifecycleState { public final class G7Sensor: G7BluetoothManagerDelegate { public static let defaultLifetime = TimeInterval(hours: 10 * 24) public static let defaultWarmupDuration = TimeInterval(minutes: 27) - public static let defaultGracePeriod = TimeInterval(hours: 12) + public static let gracePeriod = TimeInterval(hours: 12) public weak var delegate: G7SensorDelegate? @@ -279,12 +279,12 @@ public final class G7Sensor: G7BluetoothManagerDelegate { delegateQueue.async { self.delegate?.sensor(self, didReceive: extendedVersionMessage) self.needsVersionInfo = false + self.delegate?.sensor(self, logComms: response.hexadecimalString) } } case .backfillFinished: flushBackfillBuffer() default: - self.delegate?.sensor(self, logComms: response.hexadecimalString) break } } diff --git a/G7SensorKit/Messages/ExtendedVersionMessage.swift b/G7SensorKit/Messages/ExtendedVersionMessage.swift index 2ed9c4d..cf7510c 100644 --- a/G7SensorKit/Messages/ExtendedVersionMessage.swift +++ b/G7SensorKit/Messages/ExtendedVersionMessage.swift @@ -10,18 +10,19 @@ import Foundation import LoopKit public struct ExtendedVersionMessage: SensorMessage, Equatable { - public let sessionDuration: TimeInterval + public let sessionLength: TimeInterval public let warmupDuration: TimeInterval public let algorithmVersion: UInt32 public let hardwareVersion: UInt8 - public let gracePeriodDuration: TimeInterval + public let maxLifetimeDays: UInt16 public let data: Data init?(data: Data) { self.data = data - // 52 00 c0d70d00 5406 00020404 ff 0c00 + // 10-day: 52 00 c0d70d00 5406 00020404 ff 0c00 + // 15-day: 52 00 406f1400 880e 00010a04 ff 1100 guard data.starts(with: .extendedVersionTx) else { return nil @@ -31,16 +32,16 @@ public struct ExtendedVersionMessage: SensorMessage, Equatable { return nil } - sessionDuration = TimeInterval(data[2..<6].to(UInt32.self)) + sessionLength = TimeInterval(data[2..<6].to(UInt32.self)) warmupDuration = TimeInterval(data[6..<8].to(UInt16.self)) algorithmVersion = data[8..<12].to(UInt32.self) hardwareVersion = data[12] - gracePeriodDuration = TimeInterval(hours: Double(data[13..<15].to(UInt16.self))) + maxLifetimeDays = data[13..<15].to(UInt16.self) } } extension ExtendedVersionMessage: CustomDebugStringConvertible { public var debugDescription: String { - return "ExtendedVersionMessage(sessionDuration:\(sessionDuration), warmupDuration:\(warmupDuration) algorithmVersion:\(algorithmVersion) hardwareVersion:\(hardwareVersion) gracePeriodDuration:\(gracePeriodDuration))" + return "ExtendedVersionMessage(sessionLength:\(sessionLength), warmupDuration:\(warmupDuration) algorithmVersion:\(algorithmVersion) hardwareVersion:\(hardwareVersion) maxLifetimeDays:\(maxLifetimeDays))" } } diff --git a/G7SensorKitTests/ExtendedVersionMessageTests.swift b/G7SensorKitTests/ExtendedVersionMessageTests.swift index 97bf0d3..f991b40 100644 --- a/G7SensorKitTests/ExtendedVersionMessageTests.swift +++ b/G7SensorKitTests/ExtendedVersionMessageTests.swift @@ -15,10 +15,21 @@ final class ExtendedVersionMessageTests: XCTestCase { let data = Data(hexadecimalString: "5200c0d70d00540600020404ff0c00")! let message = ExtendedVersionMessage(data: data)! - XCTAssertEqual(10.5, message.sessionDuration.hours / 24) + XCTAssertEqual(10.5, message.sessionLength.hours / 24) XCTAssertEqual(27, message.warmupDuration.minutes) XCTAssertEqual(67371520, message.algorithmVersion) XCTAssertEqual(255, message.hardwareVersion) - XCTAssertEqual(12, message.gracePeriodDuration.hours) + XCTAssertEqual(12, message.maxLifetimeDays) + } + + func test15DayMessage() { + let data = Data(hexadecimalString: "5200406f1400880e00010a04ff1100")! + let message = ExtendedVersionMessage(data: data)! + + XCTAssertEqual(15.5, message.sessionLength.hours / 24) + XCTAssertEqual(62, message.warmupDuration.minutes) + XCTAssertEqual(67764480, message.algorithmVersion) + XCTAssertEqual(255, message.hardwareVersion) + XCTAssertEqual(17, message.maxLifetimeDays) } } diff --git a/G7SensorKitUI/G7CGMManager/G7CGMManager+UI.swift b/G7SensorKitUI/G7CGMManager/G7CGMManager+UI.swift index 877d68e..fe8fa5d 100644 --- a/G7SensorKitUI/G7CGMManager/G7CGMManager+UI.swift +++ b/G7SensorKitUI/G7CGMManager/G7CGMManager+UI.swift @@ -117,7 +117,7 @@ extension G7CGMManager: CGMManagerUI { return nil } let remaining = max(0, endTime.timeIntervalSinceNow) - return G7LifecycleProgress(percentComplete: 1-(remaining/gracePeriod), progressState: .critical) + return G7LifecycleProgress(percentComplete: 1-(remaining/G7Sensor.gracePeriod), progressState: .critical) case .expired: return G7LifecycleProgress(percentComplete: 1, progressState: .critical) default: diff --git a/G7SensorKitUI/Views/G7SettingsView.swift b/G7SensorKitUI/Views/G7SettingsView.swift index 66ff2f4..ea71de9 100644 --- a/G7SensorKitUI/Views/G7SettingsView.swift +++ b/G7SensorKitUI/Views/G7SettingsView.swift @@ -71,7 +71,7 @@ struct G7SettingsView: View { HStack { Text(LocalizedString("Grace Period End", comment: "title for g7 settings row showing sensor grace period end time")) Spacer() - Text(timeFormatter.string(from: activatedAt.addingTimeInterval(viewModel.lifetime + viewModel.gracePeriod))) + Text(timeFormatter.string(from: activatedAt.addingTimeInterval(viewModel.lifetime + G7Sensor.gracePeriod))) .foregroundColor(.secondary) } } diff --git a/G7SensorKitUI/Views/G7SettingsViewModel.swift b/G7SensorKitUI/Views/G7SettingsViewModel.swift index 424a0ae..14f19b7 100644 --- a/G7SensorKitUI/Views/G7SettingsViewModel.swift +++ b/G7SensorKitUI/Views/G7SettingsViewModel.swift @@ -24,7 +24,6 @@ class G7SettingsViewModel: ObservableObject { @Published private(set) var lastConnect: Date? @Published private(set) var lifetime: TimeInterval @Published private(set) var warmupDuration: TimeInterval - @Published private(set) var gracePeriod: TimeInterval @Published private(set) var latestReadingTimestamp: Date? @Published var uploadReadings: Bool = false { didSet { @@ -67,7 +66,6 @@ class G7SettingsViewModel: ObservableObject { self.displayGlucosePreference = displayGlucosePreference self.lifetime = cgmManager.lifetime self.warmupDuration = cgmManager.warmupDuration - self.gracePeriod = cgmManager.gracePeriod updateValues() self.cgmManager.addStateObserver(self, queue: DispatchQueue.main) @@ -126,7 +124,7 @@ class G7SettingsViewModel: ObservableObject { guard let value = progressValue, value > 0 else { return 0 } - return 1 - value / gracePeriod + return 1 - value / G7Sensor.gracePeriod case .sensorExpired, .sensorFailed: return 1 }