Showing 5 changed files with 69 additions and 34 deletions
+19 -10
USB Meter/Model/Measurements.swift
@@ -281,6 +281,7 @@ class Measurements : ObservableObject {
281 281
     private var powerSum: Double = 0
282 282
     private var voltageSum: Double = 0
283 283
     private var currentSum: Double = 0
284
+    private var temperatureItemsInSum: Double = 0
284 285
     private var temperatureSum: Double = 0
285 286
     private var rssiSum: Double = 0
286 287
 
@@ -291,6 +292,7 @@ class Measurements : ObservableObject {
291 292
         powerSum = 0
292 293
         voltageSum = 0
293 294
         currentSum = 0
295
+        temperatureItemsInSum = 0
294 296
         temperatureSum = 0
295 297
         rssiSum = 0
296 298
     }
@@ -300,7 +302,9 @@ class Measurements : ObservableObject {
300 302
         self.power.addPoint(timestamp: pendingBucketTimestamp, value: powerSum / itemsInSum)
301 303
         self.voltage.addPoint(timestamp: pendingBucketTimestamp, value: voltageSum / itemsInSum)
302 304
         self.current.addPoint(timestamp: pendingBucketTimestamp, value: currentSum / itemsInSum)
303
-        self.temperature.addPoint(timestamp: pendingBucketTimestamp, value: temperatureSum / itemsInSum)
305
+        if temperatureItemsInSum > 0 {
306
+            self.temperature.addPoint(timestamp: pendingBucketTimestamp, value: temperatureSum / temperatureItemsInSum)
307
+        }
304 308
         self.rssi.addPoint(timestamp: pendingBucketTimestamp, value: rssiSum / itemsInSum)
305 309
         resetPendingAggregation()
306 310
         self.objectWillChange.send()
@@ -389,24 +393,20 @@ class Measurements : ObservableObject {
389 393
             existing: energy.points,
390 394
             persistedRangeUpperBound: persistedRangeUpperBound
391 395
         )
392
-        let preservedTemperatureTail = preservedTailPoints(
393
-            from: temperature.points,
394
-            after: persistedRangeUpperBound
395
-        )
396 396
         let preservedRssiTail = preservedTailPoints(
397 397
             from: rssi.points,
398 398
             after: persistedRangeUpperBound
399 399
         )
400 400
 
401 401
         restoreTrace(
402
-            "measurements-restore-merge session=\(session.id.uuidString) restored=p:\(restoredPowerPoints.count),v:\(restoredVoltagePoints.count),c:\(restoredCurrentPoints.count),e:\(restoredEnergyPoints.count) discontinuities=p:\(restoredPowerPoints.filter(\.isDiscontinuity).count),v:\(restoredVoltagePoints.filter(\.isDiscontinuity).count),c:\(restoredCurrentPoints.filter(\.isDiscontinuity).count),e:\(restoredEnergyPoints.filter(\.isDiscontinuity).count) merged=p:\(mergedPowerPoints.count),v:\(mergedVoltagePoints.count),c:\(mergedCurrentPoints.count),e:\(mergedEnergyPoints.count) tails=t:\(preservedTemperatureTail.count),r:\(preservedRssiTail.count) upperBound=\(persistedRangeUpperBound?.description ?? "nil")"
402
+            "measurements-restore-merge session=\(session.id.uuidString) restored=p:\(restoredPowerPoints.count),v:\(restoredVoltagePoints.count),c:\(restoredCurrentPoints.count),e:\(restoredEnergyPoints.count) discontinuities=p:\(restoredPowerPoints.filter(\.isDiscontinuity).count),v:\(restoredVoltagePoints.filter(\.isDiscontinuity).count),c:\(restoredCurrentPoints.filter(\.isDiscontinuity).count),e:\(restoredEnergyPoints.filter(\.isDiscontinuity).count) merged=p:\(mergedPowerPoints.count),v:\(mergedVoltagePoints.count),c:\(mergedCurrentPoints.count),e:\(mergedEnergyPoints.count) tails=r:\(preservedRssiTail.count) upperBound=\(persistedRangeUpperBound?.description ?? "nil")"
403 403
         )
404 404
 
405 405
         power.replacePoints(mergedPowerPoints)
406 406
         current.replacePoints(mergedCurrentPoints)
407 407
         voltage.replacePoints(mergedVoltagePoints)
408 408
         energy.replacePoints(mergedEnergyPoints)
409
-        temperature.replacePoints(preservedTemperatureTail)
409
+        temperature.resetSeries()
410 410
         rssi.replacePoints(preservedRssiTail)
411 411
 
412 412
         lastEnergyCounterValue = hasExistingBuffer ? preservedEnergyCounterValue : nil
@@ -577,7 +577,7 @@ class Measurements : ObservableObject {
577 577
         self.objectWillChange.send()
578 578
     }
579 579
 
580
-    func addValues(timestamp: Date, power: Double, voltage: Double, current: Double, temperature: Double, rssi: Double) {
580
+    func addValues(timestamp: Date, power: Double, voltage: Double, current: Double, temperature: Double?, rssi: Double) {
581 581
         let valuesTimestamp = timestamp.timeIntervalSinceReferenceDate.intValue
582 582
 
583 583
         if pendingBucketSecond == valuesTimestamp {
@@ -586,7 +586,10 @@ class Measurements : ObservableObject {
586 586
             powerSum += power
587 587
             voltageSum += voltage
588 588
             currentSum += current
589
-            temperatureSum += temperature
589
+            if let temperature {
590
+                temperatureItemsInSum += 1
591
+                temperatureSum += temperature
592
+            }
590 593
             rssiSum += rssi
591 594
             return
592 595
         }
@@ -599,7 +602,13 @@ class Measurements : ObservableObject {
599 602
         powerSum = power
600 603
         voltageSum = voltage
601 604
         currentSum = current
602
-        temperatureSum = temperature
605
+        if let temperature {
606
+            temperatureItemsInSum = 1
607
+            temperatureSum = temperature
608
+        } else {
609
+            temperatureItemsInSum = 0
610
+            temperatureSum = 0
611
+        }
603 612
         rssiSum = rssi
604 613
     }
605 614
 
+11 -3
USB Meter/Model/Meter.swift
@@ -818,7 +818,11 @@ class Meter : NSObject, ObservableObject, Identifiable {
818 818
         updateChargeRecord(at: dataDumpRequestTimestamp)
819 819
         captureLiveMeasurements(at: dataDumpRequestTimestamp, in: measurements)
820 820
         if chargeRecordState != .waitingForStart {
821
-            captureLiveMeasurements(at: dataDumpRequestTimestamp, in: chargeRecordMeasurements)
821
+            captureLiveMeasurements(
822
+                at: dataDumpRequestTimestamp,
823
+                in: chargeRecordMeasurements,
824
+                includesTemperature: false
825
+            )
822 826
         }
823 827
         appData.observeChargeSnapshot(from: self, observedAt: dataDumpRequestTimestamp)
824 828
 //        DispatchQueue.global(qos: .userInitiated).asyncAfter( deadline: .now() + 0.33 ) {
@@ -1064,7 +1068,11 @@ class Meter : NSObject, ObservableObject, Identifiable {
1064 1068
         }
1065 1069
     }
1066 1070
 
1067
-    private func captureLiveMeasurements(at timestamp: Date, in destination: Measurements) {
1071
+    private func captureLiveMeasurements(
1072
+        at timestamp: Date,
1073
+        in destination: Measurements,
1074
+        includesTemperature: Bool = true
1075
+    ) {
1068 1076
         if supportsRecordingView {
1069 1077
             destination.captureEnergyValue(
1070 1078
                 timestamp: timestamp,
@@ -1084,7 +1092,7 @@ class Meter : NSObject, ObservableObject, Identifiable {
1084 1092
             power: power,
1085 1093
             voltage: voltage,
1086 1094
             current: current,
1087
-            temperature: displayedTemperatureValue,
1095
+            temperature: includesTemperature ? displayedTemperatureValue : nil,
1088 1096
             rssi: Double(btSerial.averageRSSI)
1089 1097
         )
1090 1098
     }
+36 -20
USB Meter/Views/Meter/Components/MeasurementChartView.swift
@@ -166,6 +166,7 @@ struct MeasurementChartView: View {
166 166
     let showsRangeSelector: Bool
167 167
     let rebasesEnergyToVisibleRangeStart: Bool
168 168
     let extendsTimelineToPresent: Bool
169
+    let showsTemperatureSeries: Bool
169 170
     let rangeSelectorConfiguration: MeasurementChartRangeSelectorConfiguration?
170 171
 
171 172
     @EnvironmentObject private var measurements: Measurements
@@ -223,6 +224,7 @@ struct MeasurementChartView: View {
223 224
         showsRangeSelector: Bool = true,
224 225
         rebasesEnergyToVisibleRangeStart: Bool = false,
225 226
         extendsTimelineToPresent: Bool = true,
227
+        showsTemperatureSeries: Bool = true,
226 228
         rangeSelectorConfiguration: MeasurementChartRangeSelectorConfiguration? = nil
227 229
     ) {
228 230
         self.sizing = sizing
@@ -232,6 +234,7 @@ struct MeasurementChartView: View {
232 234
         self.showsRangeSelector = showsRangeSelector
233 235
         self.rebasesEnergyToVisibleRangeStart = rebasesEnergyToVisibleRangeStart
234 236
         self.extendsTimelineToPresent = extendsTimelineToPresent
237
+        self.showsTemperatureSeries = showsTemperatureSeries
235 238
         self.rangeSelectorConfiguration = rangeSelectorConfiguration
236 239
     }
237 240
 
@@ -351,24 +354,35 @@ struct MeasurementChartView: View {
351 354
     }
352 355
 
353 356
     var body: some View {
354
-        switch sizing {
355
-        case .provided:
356
-            chartBody
357
-        case .embedded:
358
-            let chartWidth = max(embeddedWidth, 1)
359
-            chartBody
360
-                .frame(maxWidth: .infinity, alignment: .topLeading)
361
-                .frame(height: Self.embeddedContentHeight(width: chartWidth, showsRangeSelector: showsRangeSelector))
362
-                .background(
363
-                    GeometryReader { geometry in
364
-                        Color.clear.preference(key: EmbeddedWidthKey.self, value: geometry.size.width)
357
+        Group {
358
+            switch sizing {
359
+            case .provided:
360
+                chartBody
361
+            case .embedded:
362
+                let chartWidth = max(embeddedWidth, 1)
363
+                chartBody
364
+                    .frame(maxWidth: .infinity, alignment: .topLeading)
365
+                    .frame(height: Self.embeddedContentHeight(width: chartWidth, showsRangeSelector: showsRangeSelector))
366
+                    .background(
367
+                        GeometryReader { geometry in
368
+                            Color.clear.preference(key: EmbeddedWidthKey.self, value: geometry.size.width)
369
+                        }
370
+                    )
371
+                    .onPreferenceChange(EmbeddedWidthKey.self) { width in
372
+                        guard width > 0, abs(width - embeddedWidth) > 0.5 else { return }
373
+                        embeddedWidth = width
365 374
                     }
366
-                )
367
-                .onPreferenceChange(EmbeddedWidthKey.self) { width in
368
-                    guard width > 0, abs(width - embeddedWidth) > 0.5 else { return }
369
-                    embeddedWidth = width
370
-                }
375
+            }
371 376
         }
377
+        .onAppear(perform: resetHiddenTemperatureDisplay)
378
+        .onChange(of: showsTemperatureSeries) { _ in
379
+            resetHiddenTemperatureDisplay()
380
+        }
381
+    }
382
+
383
+    private func resetHiddenTemperatureDisplay() {
384
+        guard !showsTemperatureSeries, displayTemperature else { return }
385
+        displayTemperature = false
372 386
     }
373 387
 
374 388
     @ViewBuilder
@@ -665,10 +679,12 @@ struct MeasurementChartView: View {
665 679
                 }
666 680
             }
667 681
 
668
-            seriesToggleButton(title: "Temp", isOn: displayTemperature, condensedLayout: condensedLayout) {
669
-                displayTemperature.toggle()
670
-                if displayTemperature && displayVoltage && displayCurrent {
671
-                    displayCurrent = false
682
+            if showsTemperatureSeries {
683
+                seriesToggleButton(title: "Temp", isOn: displayTemperature, condensedLayout: condensedLayout) {
684
+                    displayTemperature.toggle()
685
+                    if displayTemperature && displayVoltage && displayCurrent {
686
+                        displayCurrent = false
687
+                    }
672 688
                 }
673 689
             }
674 690
         }
+1 -0
USB Meter/Views/Meter/Tabs/ChargeRecord/MeterChargeRecordTabView.swift
@@ -1404,6 +1404,7 @@ struct MeterChargeRecordContentView: View {
1404 1404
                 showsRangeSelector: hasRangeSelector,
1405 1405
                 rebasesEnergyToVisibleRangeStart: true,
1406 1406
                 extendsTimelineToPresent: false,
1407
+                showsTemperatureSeries: false,
1407 1408
                 rangeSelectorConfiguration: hasRangeSelector
1408 1409
                     ? MeasurementChartRangeSelectorConfiguration(
1409 1410
                         keepAction: MeasurementChartSelectionAction(
+2 -1
USB Meter/Views/Meter/Tabs/ChargeRecord/SessionTrimEditorView.swift
@@ -134,7 +134,8 @@ struct SessionTrimEditorView: View {
134 134
                         sizing: .provided(size: geo.size, compact: true),
135 135
                         timeRange: fullStart...fullEnd,
136 136
                         showsRangeSelector: false,
137
-                        rebasesEnergyToVisibleRangeStart: false
137
+                        rebasesEnergyToVisibleRangeStart: false,
138
+                        showsTemperatureSeries: false
138 139
                     )
139 140
 
140 141
                     // Dimmed region before trimStart