TempTrack-iOS/TempTrack/Temperature/TemperatureMeasurement.swift

197 lines
4.7 KiB
Swift
Raw Normal View History

2023-06-03 08:15:00 +02:00
import Foundation
struct TemperatureMeasurement: Identifiable {
2023-06-03 08:15:00 +02:00
var sensor0: TemperatureValue
var sensor1: TemperatureValue
2023-06-11 21:57:07 +02:00
/// The seconds since 1970
var id: Int
var date: Date {
get {
Date(seconds: id)
}
set {
id = newValue.seconds
}
}
var secondsToNow: Int {
2023-06-11 21:57:07 +02:00
id - Date().seconds
}
var maximumValue: Double? {
guard let s0 = sensor0.optionalValue else {
return sensor1.optionalValue
}
guard let s1 = sensor1.optionalValue else {
2023-06-14 17:52:43 +02:00
return s0
}
return max(s0, s1)
}
var minimumValue: Double? {
guard let s0 = sensor0.optionalValue else {
return sensor1.optionalValue
}
guard let s1 = sensor1.optionalValue else {
2023-06-14 17:52:43 +02:00
return s0
}
return min(s0, s1)
}
2023-06-14 17:52:43 +02:00
var averageValue: Double? {
guard let s0 = sensor0.optionalValue else {
return sensor1.optionalValue
}
guard let s1 = sensor1.optionalValue else {
return s0
}
return (s0 + s1) / 2
}
var displayText: String {
guard let averageValue else {
return "-"
}
return String(format: "%.1f °C", averageValue)
}
}
extension TemperatureMeasurement {
init(sensor0: TemperatureValue, sensor1: TemperatureValue, date: Date) {
self.sensor0 = sensor0
self.sensor1 = sensor1
self.id = date.seconds
}
}
extension TemperatureMeasurement: Codable {
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
self.sensor0 = .init(byte: try container.decode(UInt8.self))
self.sensor1 = .init(byte: try container.decode(UInt8.self))
self.id = try container.decode(Int.self)
}
func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(sensor0.byte)
try container.encode(sensor1.byte)
try container.encode(id)
}
}
extension TemperatureMeasurement: Comparable {
static func < (lhs: TemperatureMeasurement, rhs: TemperatureMeasurement) -> Bool {
lhs.id < rhs.id
}
static func == (lhs: TemperatureMeasurement, rhs: TemperatureMeasurement) -> Bool {
lhs.id == rhs.id
}
}
extension Array where Element == TemperatureMeasurement {
func maximumValue() -> Double? {
compactMap { $0.maximumValue }.max()
}
func minimumValue() -> Double? {
compactMap { $0.minimumValue }.min()
}
}
private extension TemperatureValue {
init(value: Double?) {
if let value {
self = .value(value)
} else {
self = .notFound
}
}
}
extension TemperatureMeasurement {
static let mockData: [TemperatureMeasurement] = {
let temps: [(Double?, Double?)] = [
(20, 14),
(20, 13.5),
(20.5, 13.5),
(20.5, 13.5),
(21, 14),
(21, 14),
(nil, 14.5),
(nil, 14),
(nil, 14.5),
(nil, 14),
(nil, 14),
(nil, 14.5),
(nil, 15),
(5.0, 15),
(4.5, 15.5),
(4.5, 16),
(4.0, 16.5),
(3.0, 17),
(3.0, 19),
(2.5, 20),
(2.5, 20.5),
(2.0, 20.5),
(1.0, 20.5),
(0.5, 20.5),
(0.0, 20),
(0.0, 20),
(-1.0, 21.0),
(-0.5, 21.0),
(-3.0, 21.0),
(-3.5, 20.5),
(-4.0, 20.5),
(-5.0, 20.0),
(-5.0, nil),
(-5.5, nil),
(-5.0, nil),
(-5.5, nil),
(-6.0, nil),
(-5.0, nil),
(nil, nil),
(nil, nil),
(nil, nil),
(-5.0, nil),
(-4.5, nil),
(-4.0, 23.0),
(5.0, 24.0),
(7.0, 25.0),
(8.0, 25.5),
(8.5, 25.5),
(10.0, 25.5),
(10.5, 24.0),
(10.5, 24.0),
(10.5, 24.5),
(12.0, 23.5),
(12.5, 24.0),
(12.0, 23.5),
(14.0, 24.0),
(15.0, 25.0),
(15.0, 25.0),
(15.5, 25.0),
(15.0, 25.0),
]
let seconds = Date().seconds
return temps.enumerated().map {
TemperatureMeasurement(
sensor0: .init(value: $0.element.0),
sensor1: .init(value: $0.element.1),
2023-06-11 21:57:07 +02:00
id: seconds + ($0.offset - temps.count) * 60)
}
}()
2023-06-03 08:15:00 +02:00
}