feat: classify offline charges using newly geofence charge_type hint#5330
feat: classify offline charges using newly geofence charge_type hint#5330finikwashere wants to merge 3 commits into
Conversation
When a car charges in a location with no internet (underground garage,
gym, etc.), TeslaMate synthesises the charging session from the last
known state before going offline and the first state after reconnecting.
All charge rows for that session have NULL charger_phases and
fast_charger_present, so every Grafana dashboard query that uses
CASE WHEN NULLIF(mode() within group (order by charger_phases),0) IS NULL
THEN 'DC' ELSE 'AC' END
incorrectly labels the session as DC.
This commit introduces a fallback mechanism:
1. DB migration: add a nullable charge_type column (AC | DC) to the
geofences table.
2. GeoFence schema/changeset: expose the new field so TeslaMate can
read and write it.
3. Geofence UI: add a 'Default charge type' dropdown (Auto-detect /
AC / DC) to the geofence edit form.
4. Grafana dashboards (charges, charging-stats, battery-health, trip):
replace the two-way CASE with a three-tier priority:
a. charger_phases IS NOT NULL → AC (normal online session)
b. fast_charger_present = true → DC (online DC session w/o phases)
c. geofence.charge_type IS NOT NULL → use the configured hint
d. fallback → DC
The fix applies at query time, so all existing historical data is
corrected retroactively without any SQL UPDATE.
Fixes teslamate-org#4401
✅ Deploy Preview for teslamate ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Thanks for your contribution.
This is not the best practice for changing historical charging types. It is okay to change them if they were offline, but otherwise, the correct data may become corrupted. |
Should it be optional, triggered by the user after upgrade? |
Not sure, there might be some confusion here in how this was documented. The wording implies that we change (correct) the database at query time. "correct" would mean we write new values to the database. That would be bad, queries have to remain read only. My grafana only has read only access to the database. But my reading of the queries seems to indicate that they are read only and do not change any data. Or am I totally confused here? |
|
I strongly suspect the tests will need fixing... |
- Fix geofence_live_test.exs: two pattern-matches on .field.is-horizontal now account for the new charge_type row (5 → 6 fields) - Add missing gettext strings to default.pot and all 17 active locale po files (ca, da, de, es, fi, fr, it, ja, ko, nb, nl, sv, th, tr, uk, zh_Hans, zh_Hant) for: Default charge type, Auto-detect, AC, DC, and the offline charging fallback help text
|
Apologies for the confusion. On "corrects all past charging sessions"** (@brianmay): Grafana queries are read-only, and this is what the SQL here also does. The wording in the PR description was misleading. What I meant is:
The new CASE
WHEN NULLIF(mode() within group (order by charger_phases), 0) IS NOT NULL THEN 'AC' -- online AC session
WHEN bool_or(fast_charger_present) = true THEN 'DC' -- online DC session
WHEN MAX(g.charge_type::text) IS NOT NULL THEN MAX(g.charge_type::text) -- offline fallback
ELSE 'DC'
ENDSo for any session that was online during charging (i.e. |
Our 26-line heex insertion (Default charge type section) shifted all existing gettext calls below line 118 in form.html.heex by 26 lines. Update the stale #: references in default.pot: :124 (Back) → :150 :128 (Save) → :154 :129 (Saving...) → :155 :155 (Charging Costs) → :181 :163 (ngettext sessions) → :189 :174 (Continue) → :200 :177 (Add costs ...) → :203 Fixes mix gettext.extract --check-up-to-date CI failure.
Problem
Closes #4401
When a car charges in a location with no internet (underground garage, gym, etc.), TeslaMate synthesises the charging session from the last known state before going offline and the first state after reconnecting. All
chargesrows for that session haveNULLcharger_phasesandfast_charger_present, so every Grafana dashboard query that uses:incorrectly labels the session as DC — even for a plain home AC wallbox.
Affected dashboards: Charges, Charging Stats, Battery Health, Trip (9 SQL queries total).
Solution
Introduce an optional Default charge type hint on Geofences (AC / DC / auto-detect). The Grafana SQL falls back to it only when it cannot determine the type from live telemetry.
Priority order in the new CASE expression
charger_phases IS NOT NULL→ AC (normal online session)fast_charger_present = true→ DC (online DC session without phase data)geofence.charge_type IS NOT NULL→ use configured hint (offline sessions at known locations)Changes
priv/repo/migrations/20260510111557_add_charge_type_to_geofences.exscharge_type varcharcolumn togeofenceslib/teslamate/locations/geo_fence.excharge_typeEcto.Enum field and include in changesetlib/teslamate_web/live/geofence_live/form.html.heexgrafana/dashboards/charges.jsongrafana/dashboards/charging-stats.jsongrafana/dashboards/battery-health.jsongrafana/dashboards/trip.jsonWhy this fixes existing data retroactively
The fix is applied at query time in Grafana. No
UPDATEto historical rows is needed — settingcharge_type = 'AC'on a geofence immediately corrects all past charging sessions at that location.Testing
Tested on a live TeslaMate instance with an underground home garage (no cell reception during charging). Before the fix every Home charge showed as DC. After setting
charge_type = 'AC'on the Home geofence, all historical home charges immediately show as AC while Supercharger and public DC fast-charger sessions remain correctly classified as DC.