diff --git a/Sources/CombustionBLE/BleData/ProbeTemperatures.swift b/Sources/CombustionBLE/BleData/ProbeTemperatures.swift index 463b2ef..8322e0f 100644 --- a/Sources/CombustionBLE/BleData/ProbeTemperatures.swift +++ b/Sources/CombustionBLE/BleData/ProbeTemperatures.swift @@ -31,6 +31,10 @@ public struct ProbeTemperatures: Equatable { /// Array of probe temperatures. /// Index 0 is the tip sensor, 7 is the handle (ambient) sensor. public let values: [Double] + + public init(values: [Double]) { + self.values = values + } } extension ProbeTemperatures { diff --git a/Sources/CombustionBLE/Device.swift b/Sources/CombustionBLE/Device.swift index 1717005..36c4318 100644 --- a/Sources/CombustionBLE/Device.swift +++ b/Sources/CombustionBLE/Device.swift @@ -69,6 +69,10 @@ public class Device : ObservableObject { public init(identifier: UUID) { self.identifier = identifier.uuidString } + + func updateDeviceStale() { + stale = Date().timeIntervalSince(lastUpdateTime) > Constants.STALE_TIMEOUT + } } extension Device { @@ -106,11 +110,6 @@ extension Device { DeviceManager.shared.connectToDevice(self) } } - - func updateDeviceStale() { - stale = Date().timeIntervalSince(lastUpdateTime) > Constants.STALE_TIMEOUT - } - } diff --git a/Sources/CombustionBLE/Probe.swift b/Sources/CombustionBLE/Probe.swift index 77893d5..7ce386c 100644 --- a/Sources/CombustionBLE/Probe.swift +++ b/Sources/CombustionBLE/Probe.swift @@ -33,7 +33,9 @@ public class Probe : Device { /// Probe serial number @Published public private(set) var serialNumber: UInt32 - @Published public private(set) var currentTemperatures: ProbeTemperatures + @Published public private(set) var currentTemperatures: ProbeTemperatures? + @Published public private(set) var instantReadTemperature: Double? + @Published public private(set) var minSequenceNumber: UInt32? @Published public private(set) var maxSequenceNumber: UInt32? @@ -61,22 +63,46 @@ public class Probe : Device { /// Stores historical values of probe temperatures public private(set) var temperatureLog : ProbeTemperatureLog = ProbeTemperatureLog() + /// Time at which probe instant read was last updated + internal var lastInstantRead: Date? + public init(_ advertising: AdvertisingData, RSSI: NSNumber, identifier: UUID) { serialNumber = advertising.serialNumber id = advertising.id color = advertising.color - currentTemperatures = advertising.temperatures super.init(identifier: identifier) updateWithAdvertising(advertising, RSSI: RSSI) } + + override func updateDeviceStale() { + // Clear instantReadTemperature if its been longer than timeout since last update + if let lastInstantRead = lastInstantRead, + Date().timeIntervalSince(lastInstantRead) > Constants.INSTANT_READ_STALE_TIMEOUT { + instantReadTemperature = nil + } + + super.updateDeviceStale() + } } extension Probe { + private enum Constants { + /// Instant read is considered stale after 5 seconds + static let INSTANT_READ_STALE_TIMEOUT = 5.0 + } + + func updateWithAdvertising(_ advertising: AdvertisingData, RSSI: NSNumber) { - currentTemperatures = advertising.temperatures + if(advertising.mode == .Normal) { + currentTemperatures = advertising.temperatures + } + else if(advertising.mode == .InstantRead ){ + updateInstantRead(advertising.temperatures.values[0]) + } + rssi = RSSI.intValue lastUpdateTime = Date() @@ -84,19 +110,22 @@ extension Probe { /// Updates the Device based on newly-received DeviceStatus message. Requests missing records. func updateProbeStatus(deviceStatus: DeviceStatus) { - - currentTemperatures = deviceStatus.temperatures minSequenceNumber = deviceStatus.minSequenceNumber maxSequenceNumber = deviceStatus.maxSequenceNumber id = deviceStatus.id color = deviceStatus.color - // Log the temperature data point for "Normal" status updates if(deviceStatus.mode == .Normal) { + currentTemperatures = deviceStatus.temperatures + + // Log the temperature data point for "Normal" status updates temperatureLog.appendDataPoint(dataPoint: LoggedProbeDataPoint.fromDeviceStatus(deviceStatus: deviceStatus)) } + else if(deviceStatus.mode == .InstantRead ){ + updateInstantRead(deviceStatus.temperatures.values[0]) + } // Check for missing records if let missingSequence = temperatureLog.firstMissingIndex(sequenceRangeStart: deviceStatus.minSequenceNumber, @@ -123,22 +152,27 @@ extension Probe { logResponse)) } + private func updateInstantRead(_ instantReadValue: Double) { + lastInstantRead = Date() + instantReadTemperature = instantReadValue + } + /////////////////////// // Current value functions /////////////////////// - /// Gets the current temperature of the sensor at the specified index. - /// - param index: Index of temperature value (0-7) + /// Converts the specified temperature to Celsius or Fahrenheit /// - param celsius: True for celsius, false for fahrenheit /// - returns: Requested temperature value - public func currentTemperature(index: Int, celsius: Bool) -> Double? { - let result = currentTemperatures.values[index] + static public func temperatureInCelsius(_ temperature: Double?, celsius: Bool) -> Double? { + guard let temperature = temperature else { return nil } + if !celsius { // Convert to fahrenheit - return fahrenheit(celsius: result) + return fahrenheit(celsius: temperature) } - return result + return temperature } }