The session duration was displaying incorrect values (e.g., 8 hours instead of ~1 hour) because it was relying on the meter's internal recordingDuration counter, which can be unreliable or return stale values from previous sessions. Changed effectiveDuration calculation to: - Use timestamp-based duration (endedAt/lastObservedAt - startedAt) as the primary source - Validate meter counter against timestamp duration with 5% tolerance - Only use meter counter if it's consistent with timestamp calculation - Fall back to timestamp duration if meter counter differs significantly This ensures session durations are always calculated from reliable time values, while still allowing the more precise meter counter when available and trustworthy.
@@ -705,7 +705,24 @@ struct ChargeSessionSummary: Identifiable, Hashable {
|
||
| 705 | 705 |
if isTrimmed {
|
| 706 | 706 |
return max(effectiveTrimEnd.timeIntervalSince(effectiveTrimStart), 0) |
| 707 | 707 |
} |
| 708 |
- return meterObservedDuration ?? duration |
|
| 708 |
+ |
|
| 709 |
+ // Use timestamp-based duration as primary source; only use meter counter if it's consistent |
|
| 710 |
+ let timestampDuration = duration |
|
| 711 |
+ |
|
| 712 |
+ if let meterDuration = meterObservedDuration {
|
|
| 713 |
+ // Allow 5% tolerance for meter counter vs timestamp calculation |
|
| 714 |
+ let tolerance = timestampDuration * 0.05 |
|
| 715 |
+ let lower = timestampDuration - tolerance |
|
| 716 |
+ let upper = timestampDuration + tolerance |
|
| 717 |
+ |
|
| 718 |
+ // If meter duration is within tolerance range, use it (more precise) |
|
| 719 |
+ // Otherwise fall back to timestamp-based duration |
|
| 720 |
+ if meterDuration >= lower && meterDuration <= upper {
|
|
| 721 |
+ return meterDuration |
|
| 722 |
+ } |
|
| 723 |
+ } |
|
| 724 |
+ |
|
| 725 |
+ return timestampDuration |
|
| 709 | 726 |
} |
| 710 | 727 |
|
| 711 | 728 |
var effectiveOrMeasuredEnergyWh: Double {
|