USB-Meter / USB Meter / Model / Measurements.swift
Newer Older
126 lines | 3.752kb
Bogdan Timofte authored 2 weeks ago
1
//
2
//  Measurements.swift
3
//  USB Meter
4
//
5
//  Created by Bogdan Timofte on 07/05/2020.
6
//  Copyright © 2020 Bogdan Timofte. All rights reserved.
7
//
8

            
9
import Foundation
10
import CoreGraphics
11

            
12
class Measurements : ObservableObject {
13

            
14
    class Measurement : ObservableObject {
15
        struct Point : Identifiable , Hashable {
16
            var id : Int
17
            var timestamp: Date
18
            var value: Double
19
            func point() -> CGPoint {
20
                return CGPoint(x: timestamp.timeIntervalSince1970, y: value)
21
            }
22
        }
23

            
24
        var points: [Point] = []
25
        var context = ChartContext()
26

            
27
        func removeValue(index: Int) {
28
            points.remove(at: index)
29
            context.reset()
30
            for point in points {
31
                context.include( point: point.point() )
32
            }
33
            self.objectWillChange.send()
34
        }
35

            
36
        func addPoint(timestamp: Date, value: Double) {
37
            let newPoint = Measurement.Point(id: points.count, timestamp: timestamp, value: value)
38
            points.append(newPoint)
39
            context.include( point: newPoint.point() )
40
            self.objectWillChange.send()
41
        }
42

            
43
        func reset() {
44
            points.removeAll()
45
            context.reset()
46
            self.objectWillChange.send()
47
        }
Bogdan Timofte authored 2 weeks ago
48

            
49
        func trim(before cutoff: Date) {
50
            points = points
51
                .filter { $0.timestamp >= cutoff }
52
                .enumerated()
53
                .map { index, point in
54
                    Measurement.Point(id: index, timestamp: point.timestamp, value: point.value)
55
                }
56
            context.reset()
57
            for point in points {
58
                context.include(point: point.point())
59
            }
60
            self.objectWillChange.send()
61
        }
Bogdan Timofte authored 2 weeks ago
62
    }
63

            
64
    @Published var power = Measurement()
65
    @Published var voltage = Measurement()
66
    @Published var current = Measurement()
67

            
68
    private var lastPointTimestamp = 0
69

            
70
    private var itemsInSum: Double = 0
71
    private var powerSum: Double = 0
72
    private var voltageSum: Double = 0
73
    private var currentSum: Double = 0
Bogdan Timofte authored 2 weeks ago
74

            
75
    func reset() {
76
        power.reset()
77
        voltage.reset()
78
        current.reset()
79
        lastPointTimestamp = 0
80
        itemsInSum = 0
81
        powerSum = 0
82
        voltageSum = 0
83
        currentSum = 0
84
        self.objectWillChange.send()
85
    }
Bogdan Timofte authored 2 weeks ago
86

            
87
    func remove(at idx: Int) {
88
        power.removeValue(index: idx)
89
        voltage.removeValue(index: idx)
90
        current.removeValue(index: idx)
91
        self.objectWillChange.send()
92
    }
93

            
Bogdan Timofte authored 2 weeks ago
94
    func trim(before cutoff: Date) {
95
        power.trim(before: cutoff)
96
        voltage.trim(before: cutoff)
97
        current.trim(before: cutoff)
98
        self.objectWillChange.send()
99
    }
100

            
Bogdan Timofte authored 2 weeks ago
101

            
102

            
103
    func addValues(timestamp: Date, power: Double, voltage: Double, current: Double) {
104
        let valuesTimestamp = timestamp.timeIntervalSinceReferenceDate.intValue
105
        if lastPointTimestamp == 0 {
106
            lastPointTimestamp = valuesTimestamp
107
        }
108
        if lastPointTimestamp == valuesTimestamp {
109
            itemsInSum += 1
Bogdan Timofte authored 2 weeks ago
110
            powerSum += power
Bogdan Timofte authored 2 weeks ago
111
            voltageSum += voltage
112
            currentSum += current
113
        }
114
        else {
115
            self.power.addPoint( timestamp: timestamp, value: powerSum / itemsInSum )
116
            self.voltage.addPoint( timestamp: timestamp, value: voltageSum / itemsInSum )
117
            self.current.addPoint( timestamp: timestamp, value: currentSum / itemsInSum )
118
            lastPointTimestamp = valuesTimestamp
119
            itemsInSum = 1
120
            powerSum = power
121
            voltageSum = voltage
122
            currentSum = current
123
        }
124
        self.objectWillChange.send()
125
    }
126
}