Newer Older
148 lines | 7.254kb
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

            
Bogdan Timofte authored a week ago
45
                    RecordingMetricsTableView(
46
                        labels: ["Capacity", "Energy", "Duration", "Stop Threshold"],
47
                        values: [
48
                            "\(usbMeter.chargeRecordAH.format(decimalDigits: 3)) Ah",
49
                            "\(usbMeter.chargeRecordWH.format(decimalDigits: 3)) Wh",
50
                            usbMeter.chargeRecordDurationDescription,
51
                            "\(usbMeter.chargeRecordStopThreshold.format(decimalDigits: 2)) A"
52
                        ]
53
                    )
Bogdan Timofte authored 2 weeks ago
54
                    .padding(18)
55
                    .meterCard(tint: .pink, fillOpacity: 0.14, strokeOpacity: 0.20)
Bogdan Timofte authored 2 weeks ago
56

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

            
79
                    VStack(alignment: .leading, spacing: 12) {
80
                        Text("Stop Threshold")
Bogdan Timofte authored 2 weeks ago
81
                            .font(.headline)
Bogdan Timofte authored 2 weeks ago
82
                        Slider(value: $usbMeter.chargeRecordStopThreshold, in: 0...0.30, step: 0.01)
83
                        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
84
                            .font(.footnote)
85
                            .foregroundColor(.secondary)
Bogdan Timofte authored 2 weeks ago
86
                        Button("Reset") {
87
                            usbMeter.resetChargeRecord()
88
                        }
89
                        .frame(maxWidth: .infinity)
Bogdan Timofte authored 2 weeks ago
90
                        .padding(.vertical, 10)
91
                        .meterCard(tint: .orange, fillOpacity: 0.16, strokeOpacity: 0.22, cornerRadius: 14)
92
                        .buttonStyle(.plain)
Bogdan Timofte authored 2 weeks ago
93
                    }
Bogdan Timofte authored 2 weeks ago
94
                    .padding(18)
95
                    .meterCard(tint: .orange, fillOpacity: 0.14, strokeOpacity: 0.20)
Bogdan Timofte authored 2 weeks ago
96

            
97
                    if usbMeter.supportsDataGroupCommands || usbMeter.recordedAH > 0 || usbMeter.recordedWH > 0 || usbMeter.recordingDuration > 0 {
98
                        VStack(alignment: .leading, spacing: 12) {
99
                            Text("Meter Totals")
Bogdan Timofte authored 2 weeks ago
100
                                .font(.headline)
Bogdan Timofte authored a week ago
101
                            RecordingMetricsTableView(
102
                                labels: ["Capacity", "Energy", "Duration", "Meter Threshold"],
103
                                values: [
104
                                    "\(usbMeter.recordedAH.format(decimalDigits: 3)) Ah",
105
                                    "\(usbMeter.recordedWH.format(decimalDigits: 3)) Wh",
106
                                    usbMeter.recordingDurationDescription,
107
                                    usbMeter.supportsRecordingThreshold ? "\(usbMeter.recordingTreshold.format(decimalDigits: 2)) A" : "Read-only"
108
                                ]
109
                            )
Bogdan Timofte authored 2 weeks ago
110
                            Text("These values are reported by the meter for the active data group.")
111
                                .font(.footnote)
112
                                .foregroundColor(.secondary)
113
                            if usbMeter.supportsDataGroupCommands {
114
                                Button("Reset Active Group") {
115
                                    usbMeter.clear()
116
                                }
117
                                .frame(maxWidth: .infinity)
Bogdan Timofte authored 2 weeks ago
118
                                .padding(.vertical, 10)
119
                                .meterCard(tint: .red, fillOpacity: 0.16, strokeOpacity: 0.22, cornerRadius: 14)
120
                                .buttonStyle(.plain)
Bogdan Timofte authored 2 weeks ago
121
                            }
122
                        }
Bogdan Timofte authored 2 weeks ago
123
                        .padding(18)
124
                        .meterCard(tint: .teal, fillOpacity: 0.14, strokeOpacity: 0.20)
Bogdan Timofte authored 2 weeks ago
125
                    }
Bogdan Timofte authored 2 weeks ago
126
                }
127
                .padding()
Bogdan Timofte authored 2 weeks ago
128
            }
Bogdan Timofte authored 2 weeks ago
129
            .background(
130
                LinearGradient(
131
                    colors: [.pink.opacity(0.14), Color.clear],
132
                    startPoint: .topLeading,
133
                    endPoint: .bottomTrailing
134
                )
135
                .ignoresSafeArea()
136
            )
Bogdan Timofte authored 2 weeks ago
137
            .navigationBarTitle("Charge Record", displayMode: .inline)
Bogdan Timofte authored 2 weeks ago
138
            .navigationBarItems(trailing: Button("Done") { visibility.toggle() })
Bogdan Timofte authored 2 weeks ago
139
        }
Bogdan Timofte authored 2 weeks ago
140
        .navigationViewStyle(StackNavigationViewStyle())
Bogdan Timofte authored 2 weeks ago
141
    }
142
}
143

            
144
struct RecordingView_Previews: PreviewProvider {
145
    static var previews: some View {
Bogdan Timofte authored 2 weeks ago
146
        RecordingView(visibility: .constant(true))
Bogdan Timofte authored 2 weeks ago
147
    }
148
}