You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Health/range: estimators merged ahead of use never run in the app, and "full range" has three inconsistent definitions #122
FullRangeScaleEstimator (core/history/FullRangeScale.kt)`` has no caller in app/.
TeslaCommands.Charge.chargingMph has no caller. charge_rate_mph(_float) is parsed but never stored in BatterySample.
chargeProjection(samples, chargeRateMph, fullRangeMiles) is always called with the default arguments (CarScreen.kt#L531), so its miles-first branch never runs.
healthSummary(samples) is always called without epaRatedRangeMiles or newCapacityKwh (CarScreen.kt#L110), and nothing in the UI can set them. As a result RatedRangeEstimator and the SoH branch of EnergyDeltaEstimator never execute, and HealthFusion.fuse is only ever called with (null, null). The health card still promises "A state-of-health percentage appears once the car's factory range is set" (BatteryHealthCard.kt#L100-L104).``
Each of these has its own tests (FullRangeScaleTest, RatedRangeEstimatorTest, HealthFusionTest, parts of BatteryChartTest and HealthSummaryTest). Coverage therefore looks healthy, but those tests don't exercise anything the app actually does. The master plan calls the range backbone "Core landed", which is true of the code but misleading about the product.
"Full range" is computed three different ways
The same data can give three different answers:
FullRangeScale: intersection of brackets derived from integer-SOC rounding;
ChargeSession.fullRangeMiles in the app's health code: rated miles added ÷ SOC swing;
the single-sample fallback in healthSummary: ratedRange / (level / 100).
Robustness once it is wired
FullRangeScaleEstimator.estimate intersects brackets across all samples, with no window. Any real drift — degradation, a firmware rescale, temperature effects, all raised in docs/research/range-as-soc-signal.md — or a single outlier makes upper <= lower. From then on the estimator returns null permanently, and rejectsContradictorySamples tests for exactly that. The UI shouldn't depend on it until it uses a window (e.g. the last N sessions) or an outlier-tolerant fit.
FullRangeScaleEstimator now has callers in CarScreen.kt, DriveHistoryCard.kt, TripNotification.kt and HealthSummary.kt.
chargeProjection is called with fullRangeMiles = scale?.fullRangeMiles, so its miles-first branch runs.
Still open
healthSummary is still called without epaRatedRangeMiles or newCapacityKwh (CarScreen.kt:164), so the rated-range and SoH branches and HealthFusion with real inputs still never run.
TeslaCommands.Charge.chargingMph / charge_rate_mph has no app caller.
BatterySample.percent is still a pure alias of batteryLevel (BatteryHistory.kt:43).
Not verified: whether the three "full range" definitions and the unwindowed estimator are now consistent.
#333 is merged. It closes the "full range has three definitions" and "estimator never wired" points:
FullRangeScale stores one slope (milesPerPercent) and an offset. The range at a level comes from ratedMilesAt, and the range at 100% from milesAtFull. The Health card, the trip estimate, the past-trips card, the chart cursor and the charge projection all read those.
FullRangeScales fits each car once and shares the result with every card, the health summary and the trip notification.
The window and outlier rejection from earlier already cover the "returns null permanently" concern.
Still open in this issue: epaRatedRangeMiles and newCapacityKwh are never passed to healthSummary, so the state-of-health branch of EnergyDeltaEstimator and HealthFusion never run in the app, and the health card text promises a percentage it can't show. charge_rate_mph is parsed but never stored, so the miles-first branch of chargeProjection is only reached from tests. Next step is a decision on what to keep, listed in the project thread.
FullRangeScaleEstimator runs in the app (FullRangeScales), and its fit is a weighted line over level steps, so one outlier no longer makes it return null for good.
chargeRateMph is stored in BatterySample and drives the charge projection.
Activity
dzid26 commentedon Oct 21, 2026
Checked against main (8cbaab0) on 2026-10-21.
Done
FullRangeScaleEstimatornow has callers inCarScreen.kt,DriveHistoryCard.kt,TripNotification.ktandHealthSummary.kt.chargeProjectionis called withfullRangeMiles = scale?.fullRangeMiles, so its miles-first branch runs.Still open
healthSummaryis still called withoutepaRatedRangeMilesornewCapacityKwh(CarScreen.kt:164), so the rated-range and SoH branches andHealthFusionwith real inputs still never run.TeslaCommands.Charge.chargingMph/charge_rate_mphhas no app caller.BatterySample.percentis still a pure alias ofbatteryLevel(BatteryHistory.kt:43).Keeping this open for the remaining items.
Generated by Claude Code
dzid26 commentedon Oct 21, 2026
Update:
BatterySample.percent(the pure alias ofbatteryLevel) is removed, with callers moved tobatteryLevel(#322, merged as 239bb90).Generated by Claude Code
dzid26 commentedon Oct 21, 2026
#333 is merged. It closes the "full range has three definitions" and "estimator never wired" points:
FullRangeScalestores one slope (milesPerPercent) and an offset. The range at a level comes fromratedMilesAt, and the range at 100% frommilesAtFull. The Health card, the trip estimate, the past-trips card, the chart cursor and the charge projection all read those.FullRangeScalesfits each car once and shares the result with every card, the health summary and the trip notification.Still open in this issue:
epaRatedRangeMilesandnewCapacityKwhare never passed tohealthSummary, so the state-of-health branch ofEnergyDeltaEstimatorandHealthFusionnever run in the app, and the health card text promises a percentage it can't show.charge_rate_mphis parsed but never stored, so the miles-first branch ofchargeProjectionis only reached from tests. Next step is a decision on what to keep, listed in the project thread.Generated by Claude Code
dzid26 commentedon Oct 23, 2026
Closing as done, checked against
mainat 9162ac2:FullRangeScaleEstimatorruns in the app (FullRangeScales), and its fit is a weighted line over level steps, so one outlier no longer makes it return null for good.chargeRateMphis stored inBatterySampleand drives the charge projection.healthSummarynow gets the rated range from the new Edit car dialog (feat(app): edit car dialog with VIN, new-car range and capacity #354), so SoH shows. The health footer's promise only appears while it is missing.HealthFusion, the energy-delta SoH and the typed capacity were removed: SoH is the fitted range over the EPA rated range.BatterySample.percentalias and the stalevehicleIdKDoc are gone.Generated by Claude Code