TempTrack-iOS/TempTrack/Bluetooth/DeviceInfo.swift
2023-06-14 17:52:43 +02:00

117 lines
3.9 KiB
Swift

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 numberOfStoredMeasurements: Int
/// The measurements since device start
let totalNumberOfMeasurements: Int
/// The interval between measurements (in seconds)
let measurementInterval: Int
let nextMeasurement: Date
let sensor0: TemperatureSensor?
let sensor1: TemperatureSensor?
// MARK: Device time
/**
The number of seconds the device has been powered on
*/
let numberOfSecondsRunning: Int
let deviceStartTime: Date
let hasDeviceStartTimeSet: Bool
let wakeupReason: DeviceWakeCause
// MARK: Storage
let storageSize: Int
/// The maximum number of bytes which can be requested
let transferBlockSize: Int
var storageFillRatio: Double {
Double(numberOfRecordedBytes) / Double(storageSize)
}
var storageFillPercentage: Int {
Int((storageFillRatio * 100).rounded())
}
var clockOffset: TimeInterval {
// Measurements are performed on device start (-1) and also count next measurement (+1)
let nextMeasurementTime = deviceStartTime.adding(seconds: totalNumberOfMeasurements * measurementInterval)
return nextMeasurement.timeIntervalSince(nextMeasurementTime)
}
var calculatedDeviceStartTime: Date {
let runtime = totalNumberOfMeasurements * measurementInterval
return nextMeasurement.adding(seconds: -runtime)
}
}
extension DeviceInfo {
init(info: Data) throws {
var data = info
let date = Date().nearestSecond
self.receivedDate = date
self.numberOfRecordedBytes = try data.decodeTwoByteInteger()
self.nextMeasurement = date.adding(seconds: try data.decodeTwoByteInteger())
self.measurementInterval = try data.decodeTwoByteInteger()
self.numberOfStoredMeasurements = try data.decodeTwoByteInteger()
self.totalNumberOfMeasurements = try data.decodeFourByteInteger()
self.transferBlockSize = try data.decodeTwoByteInteger()
self.storageSize = try data.decodeTwoByteInteger()
let secondsSincePowerOn = try data.decodeFourByteInteger()
self.numberOfSecondsRunning = secondsSincePowerOn
let deviceStartTimeSeconds = try data.decodeFourByteInteger()
self.sensor0 = try data.decodeSensor()
self.sensor1 = try data.decodeSensor()
self.wakeupReason = .init(rawValue: try data.getByte()) ?? .WAKEUP_UNDEFINED
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
}
}
}
extension DeviceInfo {
static var mock: DeviceInfo {
.init(
receivedDate: Date(),
numberOfRecordedBytes: 123,
numberOfStoredMeasurements: 234,
totalNumberOfMeasurements: 345,
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)),
numberOfSecondsRunning: 20,
deviceStartTime: .now.addingTimeInterval(-20755),
hasDeviceStartTimeSet: true,
wakeupReason: .WAKEUP_EXT0,
storageSize: 10000,
transferBlockSize: 180)
}
}