2023-06-03 08:15:00 +02:00
|
|
|
import Foundation
|
|
|
|
import SFSafeSymbols
|
|
|
|
|
|
|
|
struct TemperatureSensor {
|
|
|
|
|
|
|
|
let address: [UInt8]
|
|
|
|
|
|
|
|
let value: TemperatureValue
|
|
|
|
|
|
|
|
let date: Date
|
|
|
|
|
|
|
|
var optionalValue: Double? {
|
|
|
|
value.optionalValue
|
|
|
|
}
|
|
|
|
|
|
|
|
var hexAddress: String {
|
|
|
|
String(format: "%02X %02X %02X %02X %02X %02X %02X %02X",
|
|
|
|
address[0], address[1], address[2], address[3],
|
|
|
|
address[4], address[5], address[6], address[7])
|
|
|
|
}
|
|
|
|
|
|
|
|
var temperatureIcon: SFSymbol {
|
|
|
|
TemperatureSensor.temperatureIcon(optionalValue)
|
|
|
|
}
|
|
|
|
|
|
|
|
var temperatureText: String {
|
|
|
|
value.text
|
|
|
|
}
|
|
|
|
|
|
|
|
var updateText: String {
|
2023-06-13 17:14:57 +02:00
|
|
|
date.shortTimePassedText
|
2023-06-03 08:15:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static func temperatureIcon(_ temp: Double?) -> SFSymbol {
|
|
|
|
guard let temp else {
|
|
|
|
return .thermometerMediumSlash
|
|
|
|
}
|
|
|
|
guard temp > 0 else {
|
|
|
|
return .thermometerSnowflake
|
|
|
|
}
|
|
|
|
guard temp > 15 else {
|
|
|
|
return .thermometerLow
|
|
|
|
}
|
|
|
|
guard temp > 25 else {
|
|
|
|
return .thermometerMedium
|
|
|
|
}
|
|
|
|
return .thermometerHigh
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension TemperatureSensor {
|
|
|
|
|
|
|
|
init?(address: [UInt8], valueByte: UInt8, secondsAgo: UInt16) {
|
|
|
|
guard address.contains(where: { $0 != 0 }) else {
|
|
|
|
// Empty address
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
self.address = address
|
|
|
|
self.value = .init(byte: valueByte)
|
|
|
|
self.date = Date().addingTimeInterval(-TimeInterval(secondsAgo))
|
|
|
|
}
|
|
|
|
}
|
2023-06-13 17:14:57 +02:00
|
|
|
|
|
|
|
extension Data {
|
|
|
|
|
|
|
|
mutating func decodeSensor() throws -> TemperatureSensor? {
|
|
|
|
guard count >= 11 else {
|
|
|
|
throw DeviceInfoError.missingData
|
|
|
|
}
|
|
|
|
let address = Array(self[startIndex..<startIndex+8])
|
|
|
|
removeFirst(8)
|
|
|
|
let temperatureByte = removeFirst()
|
|
|
|
let time = try decodeUInt16()
|
|
|
|
return .init(address: address, valueByte: temperatureByte, secondsAgo: time)
|
|
|
|
}
|
|
|
|
}
|