Add basic storage, temperature history display

This commit is contained in:
Christoph Hagen
2023-06-08 09:52:20 +02:00
parent 002eb11dc1
commit 147cd6a306
22 changed files with 843 additions and 211 deletions

View File

@ -78,6 +78,7 @@ final class TemperatureDataTransfer {
func completeTransfer() {
processBytes()
delegate?.saveAfterTransfer()
}
private func addRelative(byte: UInt8) {
@ -98,7 +99,7 @@ final class TemperatureDataTransfer {
if measurement.sensor1.isValid {
lastRecording.sensor1 = measurement.sensor1
}
lastRecording.date = measurement.date
lastRecording.id = measurement.id
delegate?.didReceiveRecording(measurement)
}

View File

@ -3,4 +3,6 @@ import Foundation
protocol TemperatureDataTransferDelegate: AnyObject {
func didReceiveRecording(_ measurement: TemperatureMeasurement)
func saveAfterTransfer()
}

View File

@ -6,14 +6,87 @@ struct TemperatureMeasurement: Identifiable {
var sensor1: TemperatureValue
var date: Date
var id: Int
var id: Int {
Int(date.timeIntervalSince1970.rounded())
var date: Date {
get {
Date(seconds: id)
}
set {
id = newValue.seconds
}
}
var secondsAgo: Int {
Int(date.timeIntervalSinceNow.rounded())
var secondsToNow: Int {
Date().seconds - id
}
var maximumValue: Double? {
guard let s0 = sensor0.optionalValue else {
return sensor1.optionalValue
}
guard let s1 = sensor1.optionalValue else {
return nil
}
return max(s0, s1)
}
var minimumValue: Double? {
guard let s0 = sensor0.optionalValue else {
return sensor1.optionalValue
}
guard let s1 = sensor1.optionalValue else {
return nil
}
return min(s0, s1)
}
}
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()
}
}
@ -28,19 +101,6 @@ private extension TemperatureValue {
}
}
private extension TemperatureMeasurement {
init(t0: Double?, t1: Double?, secs: Int) {
self.sensor0 = .init(value: t0)
self.sensor1 = .init(value: t1)
self.date = Date().addingTimeInterval(TimeInterval(secs-3600))
}
init(t0: Double?, t1: Double?, min: Int) {
self.init(t0: t0, t1: t1, secs: min * 60)
}
}
extension TemperatureMeasurement {
static let mockData: [TemperatureMeasurement] = {
@ -106,8 +166,13 @@ extension TemperatureMeasurement {
(15.5, 25.0),
(15.0, 25.0),
]
let seconds = Date().seconds
return temps.enumerated().map {
TemperatureMeasurement(t0: $0.element.0, t1: $0.element.1, min: $0.offset)
TemperatureMeasurement(
sensor0: .init(value: $0.element.0),
sensor1: .init(value: $0.element.1),
id: seconds + $0.offset * 60)
}
}()
}

View File

@ -60,35 +60,3 @@ extension TemperatureSensor {
self.date = Date().addingTimeInterval(-TimeInterval(secondsAgo))
}
}
extension Date {
var timePassedText: String {
let secs = Int(-timeIntervalSinceNow.rounded())
guard secs > 1 else {
return "Now"
}
guard secs >= 60 else {
return "\(secs) seconds ago"
}
let minutes = secs / 60
guard minutes > 1 else {
return "1 minute ago"
}
guard minutes >= 60 else {
return "\(minutes) minutes ago"
}
let hours = minutes / 60
guard hours > 1 else {
return "1 hour ago"
}
guard hours >= 60 else {
return "\(hours) hours ago"
}
let days = hours / 24
guard days > 1 else {
return "1 day ago"
}
return "\(days) days ago"
}
}

View File

@ -16,6 +16,18 @@ enum TemperatureValue {
}
}
var byte: UInt8 {
switch self {
case .notFound:
return 0
case .invalidMeasurement:
return 1
case .value(let double):
let value = Int(double + 40) * 2
return UInt8(clamping: value)
}
}
var optionalValue: Double? {
if case .value(let val) = self {
return val
@ -41,3 +53,18 @@ enum TemperatureValue {
}
}
}
extension TemperatureValue: Codable {
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let byte = try container.decode(UInt8.self)
self.init(byte: byte)
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(byte)
}
}