USB-Meter / USB Meter / Views / Meter / RecordingView.swift
Newer Older
168 lines | 8.24kb
Bogdan Timofte authored 2 weeks ago
1
//
2
//  RecordingView.swift
3
//  USB Meter
4
//
5
//  Created by Bogdan Timofte on 09/03/2020.
6
//  Copyright © 2020 Bogdan Timofte. All rights reserved.
7
//
8

            
9
import SwiftUI
10

            
11
struct RecordingView: View {
12

            
Bogdan Timofte authored 2 weeks ago
13
    @Binding var visibility: Bool
Bogdan Timofte authored 2 weeks ago
14
    @EnvironmentObject private var usbMeter: Meter
15

            
16
    var body: some View {
Bogdan Timofte authored 2 weeks ago
17
        NavigationView {
18
            ScrollView {
19
                VStack(spacing: 16) {
Bogdan Timofte authored 2 weeks ago
20
                    VStack(alignment: .leading, spacing: 8) {
21
                        HStack {
22
                            Text("Charge Record")
23
                                .font(.system(.title3, design: .rounded).weight(.bold))
24
                            Spacer()
25
                            Text(usbMeter.chargeRecordStatusText)
26
                                .font(.caption.weight(.bold))
27
                                .foregroundColor(usbMeter.chargeRecordStatusColor)
28
                                .padding(.horizontal, 10)
29
                                .padding(.vertical, 6)
30
                                .meterCard(
31
                                    tint: usbMeter.chargeRecordStatusColor,
32
                                    fillOpacity: 0.18,
33
                                    strokeOpacity: 0.24,
34
                                    cornerRadius: 999
35
                                )
36
                        }
37
                        Text("App-side charge accumulation based on the stop-threshold workflow.")
38
                            .font(.footnote)
39
                            .foregroundColor(.secondary)
Bogdan Timofte authored 2 weeks ago
40
                    }
41
                    .frame(maxWidth: .infinity)
Bogdan Timofte authored 2 weeks ago
42
                    .padding(18)
43
                    .meterCard(tint: .pink, fillOpacity: 0.18, strokeOpacity: 0.24)
Bogdan Timofte authored 2 weeks ago
44

            
45
                    HStack(alignment: .top) {
46
                        VStack(alignment: .leading, spacing: 10) {
47
                            Text("Capacity")
48
                            Text("Energy")
49
                            Text("Duration")
Bogdan Timofte authored 2 weeks ago
50
                            Text("Stop Threshold")
Bogdan Timofte authored 2 weeks ago
51
                        }
52
                        Spacer()
53
                        VStack(alignment: .trailing, spacing: 10) {
Bogdan Timofte authored 2 weeks ago
54
                            Text("\(usbMeter.chargeRecordAH.format(decimalDigits: 3)) Ah")
55
                            Text("\(usbMeter.chargeRecordWH.format(decimalDigits: 3)) Wh")
56
                            Text(usbMeter.chargeRecordDurationDescription)
57
                            Text("\(usbMeter.chargeRecordStopThreshold.format(decimalDigits: 2)) A")
Bogdan Timofte authored 2 weeks ago
58
                        }
Bogdan Timofte authored 2 weeks ago
59
                        .monospacedDigit()
Bogdan Timofte authored 2 weeks ago
60
                    }
Bogdan Timofte authored 2 weeks ago
61
                    .font(.footnote.weight(.semibold))
62
                    .padding(18)
63
                    .meterCard(tint: .pink, fillOpacity: 0.14, strokeOpacity: 0.20)
Bogdan Timofte authored 2 weeks ago
64

            
Bogdan Timofte authored 2 weeks ago
65
                    if usbMeter.chargeRecordTimeRange != nil {
66
                        VStack(alignment: .leading, spacing: 12) {
67
                            HStack {
68
                                Text("Charge Curve")
Bogdan Timofte authored 2 weeks ago
69
                                    .font(.headline)
Bogdan Timofte authored 2 weeks ago
70
                                Spacer()
71
                                Button("Reset Graph") {
72
                                    usbMeter.resetChargeRecordGraph()
73
                                }
Bogdan Timofte authored 2 weeks ago
74
                                .foregroundColor(.red)
Bogdan Timofte authored 2 weeks ago
75
                            }
Bogdan Timofte authored 2 weeks ago
76
                            MeasurementChartView(timeRange: usbMeter.chargeRecordTimeRange)
77
                                .environmentObject(usbMeter.measurements)
78
                                .frame(minHeight: 220)
79
                            Text("Reset Graph clears the current charge-record session and removes older shared samples that are no longer needed for this curve.")
80
                                .font(.footnote)
81
                                .foregroundColor(.secondary)
Bogdan Timofte authored 2 weeks ago
82
                        }
Bogdan Timofte authored 2 weeks ago
83
                        .padding(18)
84
                        .meterCard(tint: .blue, fillOpacity: 0.14, strokeOpacity: 0.20)
Bogdan Timofte authored 2 weeks ago
85
                    }
86

            
87
                    VStack(alignment: .leading, spacing: 12) {
88
                        Text("Stop Threshold")
Bogdan Timofte authored 2 weeks ago
89
                            .font(.headline)
Bogdan Timofte authored 2 weeks ago
90
                        Slider(value: $usbMeter.chargeRecordStopThreshold, in: 0...0.30, step: 0.01)
91
                        Text("The app starts accumulating when current rises above this threshold and stops when it falls back to or below it.")
Bogdan Timofte authored 2 weeks ago
92
                            .font(.footnote)
93
                            .foregroundColor(.secondary)
Bogdan Timofte authored 2 weeks ago
94
                        Button("Reset") {
95
                            usbMeter.resetChargeRecord()
96
                        }
97
                        .frame(maxWidth: .infinity)
Bogdan Timofte authored 2 weeks ago
98
                        .padding(.vertical, 10)
99
                        .meterCard(tint: .orange, fillOpacity: 0.16, strokeOpacity: 0.22, cornerRadius: 14)
100
                        .buttonStyle(.plain)
Bogdan Timofte authored 2 weeks ago
101
                    }
Bogdan Timofte authored 2 weeks ago
102
                    .padding(18)
103
                    .meterCard(tint: .orange, fillOpacity: 0.14, strokeOpacity: 0.20)
Bogdan Timofte authored 2 weeks ago
104

            
105
                    if usbMeter.supportsDataGroupCommands || usbMeter.recordedAH > 0 || usbMeter.recordedWH > 0 || usbMeter.recordingDuration > 0 {
106
                        VStack(alignment: .leading, spacing: 12) {
107
                            Text("Meter Totals")
Bogdan Timofte authored 2 weeks ago
108
                                .font(.headline)
Bogdan Timofte authored 2 weeks ago
109
                            HStack(alignment: .top) {
110
                                VStack(alignment: .leading, spacing: 10) {
111
                                    Text("Capacity")
112
                                    Text("Energy")
113
                                    Text("Duration")
114
                                    Text("Meter Threshold")
115
                                }
116
                                Spacer()
117
                                VStack(alignment: .trailing, spacing: 10) {
118
                                    Text("\(usbMeter.recordedAH.format(decimalDigits: 3)) Ah")
119
                                    Text("\(usbMeter.recordedWH.format(decimalDigits: 3)) Wh")
120
                                    Text(usbMeter.recordingDurationDescription)
121
                                    if usbMeter.supportsRecordingThreshold {
122
                                        Text("\(usbMeter.recordingTreshold.format(decimalDigits: 2)) A")
123
                                    } else {
124
                                        Text("Read-only")
125
                                    }
126
                                }
Bogdan Timofte authored 2 weeks ago
127
                                .monospacedDigit()
Bogdan Timofte authored 2 weeks ago
128
                            }
Bogdan Timofte authored 2 weeks ago
129
                            .font(.footnote.weight(.semibold))
Bogdan Timofte authored 2 weeks ago
130
                            Text("These values are reported by the meter for the active data group.")
131
                                .font(.footnote)
132
                                .foregroundColor(.secondary)
133
                            if usbMeter.supportsDataGroupCommands {
134
                                Button("Reset Active Group") {
135
                                    usbMeter.clear()
136
                                }
137
                                .frame(maxWidth: .infinity)
Bogdan Timofte authored 2 weeks ago
138
                                .padding(.vertical, 10)
139
                                .meterCard(tint: .red, fillOpacity: 0.16, strokeOpacity: 0.22, cornerRadius: 14)
140
                                .buttonStyle(.plain)
Bogdan Timofte authored 2 weeks ago
141
                            }
142
                        }
Bogdan Timofte authored 2 weeks ago
143
                        .padding(18)
144
                        .meterCard(tint: .teal, fillOpacity: 0.14, strokeOpacity: 0.20)
Bogdan Timofte authored 2 weeks ago
145
                    }
Bogdan Timofte authored 2 weeks ago
146
                }
147
                .padding()
Bogdan Timofte authored 2 weeks ago
148
            }
Bogdan Timofte authored 2 weeks ago
149
            .background(
150
                LinearGradient(
151
                    colors: [.pink.opacity(0.14), Color.clear],
152
                    startPoint: .topLeading,
153
                    endPoint: .bottomTrailing
154
                )
155
                .ignoresSafeArea()
156
            )
Bogdan Timofte authored 2 weeks ago
157
            .navigationBarTitle("Charge Record", displayMode: .inline)
Bogdan Timofte authored 2 weeks ago
158
            .navigationBarItems(trailing: Button("Done") { visibility.toggle() })
Bogdan Timofte authored 2 weeks ago
159
        }
Bogdan Timofte authored 2 weeks ago
160
        .navigationViewStyle(StackNavigationViewStyle())
Bogdan Timofte authored 2 weeks ago
161
    }
162
}
163

            
164
struct RecordingView_Previews: PreviewProvider {
165
    static var previews: some View {
Bogdan Timofte authored 2 weeks ago
166
        RecordingView(visibility: .constant(true))
Bogdan Timofte authored 2 weeks ago
167
    }
168
}