Skip to content

fix(dashboard): check the day distance counter against the odometer - #575

Open
joszz wants to merge 5 commits into
mainfrom
fix/day-distance-lifetime-counter
Open

joszz wants to merge 5 commits into
mainfrom
fix/day-distance-lifetime-counter

Conversation

@joszz

@joszz joszz commented Nov 8, 2026 •

Copy link
Copy Markdown
Owner

Refs #573

Problem

On the reporter's 2026 MG HS PHEV the Dist. today card showed 288.9 mi with the odometer at 289 mi, on a day the car was not driven. The gateway passes mileageOfDay through as is (it only drops a value above the odometer), so this car fills the "day" counter with the distance since delivery.

Fix

GetMergedLatestAsync (behind /status, the widget and the SignalR broadcast) now checks the counter against the odometer:

  • A counter above the odometer's gain over the last two days (+2 km tolerance) cannot be a day counter. The odometer's gain since midnight replaces it.
  • Two days, not one, so a counter that still holds yesterday's total just after midnight (before the car resets it) is left alone.
  • With no reading from before the window (fresh install), the first odometer reading is the starting point.
  • A sane counter costs one extra indexed query, and the result is cached as before.

The efficiency cards and the electric share use the same value, so they are corrected too.

Contains #574 (and #572)

This branch carries the commits from #574 (which include #572's), so the preview pr-<this PR> holds every fix for this reporter: #571, #570 and #573. pr-574 stays up, so the reporter can switch between the two. When the reporter confirms, merge this PR on its own and close #574 (#572 is already closed). No database changes.

Tests

DayDistanceTests: the helper, plus the merged snapshot for a lifetime counter, a fresh install, a sane counter and yesterday's total just after midnight. Full backend suite green (1563 passed, 19 Postgres-only skipped).

🤖 Generated with Claude Code

@joszz joszz added the test-build Publish pr-<number> preview images for testers label Nov 8, 2026
joszz added a commit that referenced this pull request Nov 8, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

Preview build pr-575

Images for this pull request are published, built from f84d271 (version 0.15.1-preview.0.12.pr.575, shown in the footer).
Every push here replaces them. Closing the pull request or removing the test-build label deletes them.

Important

Update to the latest release (0.15.0) first if you run an older version, as a normal update. The preview is built on top of it, the database warning on this comment compares with it, and going back means going back to it.
Switch where you always run GarageStack: the same folder, Portainer stack or Unraid container. Compose names the database volume after the folder or stack, so starting from anywhere else runs on a new, empty database.
Don't use docker compose down -v or docker volume prune while testing. A backup first never hurts.

All-in-one or Unraid: change the image to

ghcr.io/joszz/garagestack:pr-575

Docker Compose with the published images (your own compose file with garagestack-api, garagestack-worker and garagestack-frontend): change the tag of those three images to pr-575, then

docker compose pull
docker compose up -d

Docker Compose from a clone of this repository, in the clone's folder on main:

git pull
PREVIEW_TAG=pr-575 docker compose -f docker-compose.yml -f docker-compose.preview.yml up -d

With the bundled database, put --profile bundled-postgres after docker compose, as you do for a normal start.

To pin this exact build rather than follow the pull request, use pr-575-f84d271 as the tag.

Going back: change the image back to the latest release, 0.15.0. latest works too, but it follows main, so it can hold changes that are not released yet, database ones included. From a clone, run docker compose up -d --build in the same folder.

Step by step: Testing a preview build.

joszz and others added 5 commits November 9, 2026 14:13
…s capacity is set

MG's API scales the state of charge by a nominal 72.5 kWh pack, and the
gateway only replaces that for the BEV series it has a table entry for.
A PHEV with a pack of about 23 kWh showed 68.9 of 72.5 kWh at 95%.
Only a BEV now falls back to the gateway's capacity; every other car
needs HV_BATTERY_CAPACITY_KWH for kWh figures.

Refs #571

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ds no range

On some plug-in hybrids the Electric Range card never showed (#570). It
needs electricRangeKm, which only came from drivetrain/range, and the
gateway publishes that topic only when the car's fuelRangeElec holds 1 or
more. A car that leaves it at 0 never sends it.

The gateway also publishes drivetrain/hybrid_electrical_range, the BMS's
own estimate (bmsEstdElecRng, in km). It was skipped as a repeat of the
other topic. It now maps to the same column. The gateway sends it with the
charge status, before drivetrain/range in the same poll, so both merge into
one row and drivetrain/range still wins on a car that sends both. No
migration, so it can go out as a preview build.

While editing the layout, a card that is shown but has no data now says
"Hidden until your car reports this", so it no longer vanishes on Done
without a word. The card description no longer claims a range of zero is
never reported, since the BMS estimate does send 0.

The handler tests share one in-memory setup for the end-to-end MQTT cases.

Refs #570

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Charging session card showed "2507.1 kW · 900 min" on a plug-in hybrid
charging at about 4 kW with 15 minutes to go (#570). The gateway publishes
obc/powerSinglePhase and obc/powerThreePhase in W and
drivetrain/remainingChargingTime in seconds (its Home Assistant discovery
says so, unchanged since at least 0.9.0). Everything read them as kW and
minutes, the Homepage widget docs included. The Worker now stores kW and
minutes, which fixes the cards, the level details and the widget at once.

The card also always preferred the three-phase figure. Both are worked out
from the same charger voltage and current, so one of them is wrong: on a
single-phase charger the three-phase figure reads about 58% of the truth.
chargerPowerKw picks the one closest to the HV battery's own charging
power, and keeps the three-phase figure without it, as before.

Refs #570

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A 2026 MG HS plug-in hybrid fills the "mileage of the day" counter with
the distance since delivery, so the Dist. today card showed the odometer.
The merged latest snapshot now compares the counter with the odometer's
gain over the last two days. A counter beyond it is replaced by the
odometer's gain since midnight. Two days, so a counter that still holds
yesterday's total just after midnight is left alone.

Refs #573

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Spanish locale landed on main (#568) without dashboard.cardWithoutData, which broke the
type-check and the pr-574 image build. Also follows the reworded electric range description.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@joszz
joszz force-pushed the fix/day-distance-lifetime-counter branch from f8715d0 to f84d271 Compare November 9, 2026 13:13
@joszz joszz closed this Nov 9, 2026
@joszz
joszz deleted the fix/day-distance-lifetime-counter branch November 9, 2026 13:20
@joszz
joszz restored the fix/day-distance-lifetime-counter branch November 9, 2026 13:22
@joszz joszz reopened this Nov 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test-build Publish pr-<number> preview images for testers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant