Add basic storage, temperature history display
This commit is contained in:
@ -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)
|
||||
}
|
||||
|
||||
|
@ -3,4 +3,6 @@ import Foundation
|
||||
protocol TemperatureDataTransferDelegate: AnyObject {
|
||||
|
||||
func didReceiveRecording(_ measurement: TemperatureMeasurement)
|
||||
|
||||
func saveAfterTransfer()
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user