2023-06-03 08:15:00 +02:00
|
|
|
import Foundation
|
|
|
|
|
|
|
|
struct DeviceInfo {
|
|
|
|
|
|
|
|
let receivedDate: Date
|
|
|
|
|
|
|
|
/// The number of bytes recorded by the tracker
|
|
|
|
let numberOfRecordedBytes: Int
|
|
|
|
|
|
|
|
/// The number of measurements already performed
|
|
|
|
let numberOfMeasurements: Int
|
|
|
|
|
|
|
|
/// The interval between measurements (in seconds)
|
|
|
|
let measurementInterval: Int
|
|
|
|
|
|
|
|
let nextMeasurement: Date
|
|
|
|
|
|
|
|
let sensor0: TemperatureSensor?
|
|
|
|
|
|
|
|
let sensor1: TemperatureSensor?
|
|
|
|
|
2023-06-08 09:52:20 +02:00
|
|
|
// MARK: Device time
|
2023-06-03 08:15:00 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
The number of seconds the device has been powered on
|
|
|
|
*/
|
2023-06-08 09:52:20 +02:00
|
|
|
let numberOfSecondsRunning: Int
|
|
|
|
|
|
|
|
let deviceStartTime: Date
|
|
|
|
|
|
|
|
let hasDeviceStartTimeSet: Bool
|
|
|
|
|
|
|
|
// MARK: Storage
|
|
|
|
|
|
|
|
let storageSize: Int
|
|
|
|
|
|
|
|
/// The maximum number of bytes which can be requested
|
|
|
|
let transferBlockSize: Int
|
2023-06-03 08:15:00 +02:00
|
|
|
|
|
|
|
var storageFillRatio: Double {
|
|
|
|
Double(numberOfRecordedBytes) / Double(storageSize)
|
|
|
|
}
|
|
|
|
|
|
|
|
var storageFillPercentage: Int {
|
|
|
|
Int((storageFillRatio * 100).rounded())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension DeviceInfo {
|
|
|
|
|
2023-06-08 09:52:20 +02:00
|
|
|
static var size = 42
|
2023-06-03 08:15:00 +02:00
|
|
|
|
|
|
|
init?(info: Data) {
|
|
|
|
guard info.count == DeviceInfo.size else {
|
|
|
|
print("Invalid info size \(info.count)")
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
let data = Array(info)
|
|
|
|
self.receivedDate = Date()
|
|
|
|
self.numberOfRecordedBytes = .init(high: data[1], low: data[0])
|
|
|
|
let secondsUntilNextMeasurement = UInt16(high: data[3], low: data[2])
|
|
|
|
self.nextMeasurement = Date().addingTimeInterval(Double(secondsUntilNextMeasurement))
|
|
|
|
self.measurementInterval = .init(high: data[5], low: data[4])
|
|
|
|
self.numberOfMeasurements = .init(high: data[7], low: data[6])
|
|
|
|
self.transferBlockSize = .init(high: data[9], low: data[8])
|
|
|
|
let secondsSincePowerOn = Int(uint32: data[13], data[12], data[11], data[10])
|
2023-06-08 09:52:20 +02:00
|
|
|
self.numberOfSecondsRunning = secondsSincePowerOn
|
2023-06-03 08:15:00 +02:00
|
|
|
self.sensor0 = .init(address: Array(data[16..<24]), valueByte: data[14], secondsAgo: UInt16(high: data[33], low: data[32]))
|
|
|
|
self.sensor1 = .init(address: Array(data[24..<32]), valueByte: data[15], secondsAgo: UInt16(high: data[35], low: data[34]))
|
|
|
|
self.storageSize = .init(high: data[37], low: data[36])
|
2023-06-08 09:52:20 +02:00
|
|
|
let deviceStartTimeSeconds = Int(uint32: data[41], data[40], data[39], data[38])
|
|
|
|
if deviceStartTimeSeconds != 0 {
|
|
|
|
self.hasDeviceStartTimeSet = true
|
|
|
|
self.deviceStartTime = Date(seconds: deviceStartTimeSeconds)
|
|
|
|
} else {
|
|
|
|
self.hasDeviceStartTimeSet = false
|
|
|
|
self.deviceStartTime = Date(seconds: Date().seconds - secondsSincePowerOn) // Round to nearest second
|
|
|
|
}
|
2023-06-03 08:15:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private extension UInt16 {
|
|
|
|
|
|
|
|
init(high: UInt8, low: UInt8) {
|
|
|
|
self = UInt16(high) << 8 + UInt16(low)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private extension Int {
|
|
|
|
|
|
|
|
init(uint32 byte0: UInt8, _ byte1: UInt8, _ byte2: UInt8, _ byte3: UInt8) {
|
|
|
|
self = (Int(byte0) << 24) | (Int(byte1) << 16) | (Int(byte2) << 8) | Int(byte3)
|
|
|
|
}
|
|
|
|
|
|
|
|
init(high: UInt8, low: UInt8) {
|
|
|
|
self = Int(high) << 8 + Int(low)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension DeviceInfo {
|
|
|
|
|
|
|
|
static var mock: DeviceInfo {
|
|
|
|
.init(
|
|
|
|
receivedDate: Date(),
|
|
|
|
numberOfRecordedBytes: 123,
|
|
|
|
numberOfMeasurements: 234,
|
|
|
|
measurementInterval: 60,
|
|
|
|
nextMeasurement: .now.addingTimeInterval(5),
|
|
|
|
sensor0: .init(address: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08], value: .value(21.0), date: .now.addingTimeInterval(-2)),
|
|
|
|
sensor1: .init(address: [0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09], value: .value(19.0), date: .now.addingTimeInterval(-4)),
|
2023-06-08 09:52:20 +02:00
|
|
|
numberOfSecondsRunning: 20,
|
|
|
|
deviceStartTime: .now.addingTimeInterval(-1000),
|
|
|
|
hasDeviceStartTimeSet: false,
|
|
|
|
storageSize: 10000,
|
|
|
|
transferBlockSize: 180)
|
2023-06-03 08:15:00 +02:00
|
|
|
}
|
|
|
|
}
|