feat: new dashboard that shows available temperatures historical - #5457
feat: new dashboard that shows available temperatures historical#5457slayer01 wants to merge 6 commits into
Conversation
✅ Deploy Preview for teslamate ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Thank you for your contribution, Daniel. And congratulations on creating your first ever PR on GitHub! From a user`s perspective, I can see the benefit of this dashboard. As a maintainer, I love that you have already added a screenshot and the relevant link in readme. May I ask you to review the dashboard, @swiffer? I can't see anything related to performance, but I'd be happy to be proved wrong and see your magic there as well. :-) |
|
Seems to be hardcoded to celsius only? |
There was a problem hiding this comment.
Thanks for this contribution — a multi-day temperature history is a real gap in the default set (Overview is “now”, Drive Details is per-drive). Screenshot + docs update are appreciated.
A few change requests before we can merge:
1. Units (temp_unit / convert_celsius)
All panels hardcode Grafana unit celsius, axis labels °C, and Celsius thresholds. Please follow the existing pattern (Overview, Efficiency, Projected Range, Drive Details, …):
- Hidden template var
temp_unitfromsettings.unit_of_temperature - Wrap values with
convert_celsius(..., '$temp_unit') - Make field units / thresholds / axis labels unit-aware (°F must not keep 10/25/30/40 thresholds)
2. Dashboard shell (consistency)
Please align with other provisioned dashboards:
base_url(settings.base_url)- Header links: TeslaMate →
${base_url:raw}+ Dashboards dropdown (tagtesla) car_idas elsewhere
3. Drop / replace the “Distribution” heatmap
The heatmap counts raw positions samples. Logging is much denser while driving than when parked, so this is sampling-biased (same class of issue we handle carefully on Charge Level) and is easy to misread as “time at temperature.”
It also doesn’t answer a clear user question that the history + extremes don’t already cover.
Prefer: a daily outside-temp candlestick (or equivalent band):
| Field | Source |
|---|---|
| high | max |
| low | min |
| open | p15 (e.g. percentile_cont(0.15)) |
| close | p85 |
Compute on time-debiased inputs (e.g. average into fixed bins first, then daily aggregates)—not raw row counts. Days with no samples can simply have no candle.
4. Structure from a user perspective
Suggested focus for this dashboard:
- At a glance — last inside/outside + outside min/max (stats only; see §5)
- Hero — inside & outside over time; optional driver setpoint while
is_climate_on - Daily ambient envelope — candlestick (§3)
- Optional secondary — outside while charging; keep light
Passenger setpoint is usually redundant with driver; one setpoint series is enough.
5. Stats and how to draw “mostly complete” history
Last-value stats: Prefer graphMode: none and a dedicated last reading (ORDER BY date DESC LIMIT 1), as on Overview. Avoid graphMode: area sparklines over long, sparse ranges — they look patchy and don’t add much next to the hero chart.
Main history timeseries: Aim for real data that still reads as continuous when the car was actually reporting:
- Aggregate with
$__timeGroup/date_binonly where samples exist (avg of temps in the bucket). Avoid filling every interval in the range with NULL — that turns a normal 30d view into a comb of tiny segments. - Set Connect null values → Threshold (not Always). e.g. connect gaps shorter than ~30–60 minutes (or ~1–2×
$__interval), and break the line for longer sleeps/offline periods. TodayspanNulls: truedraws multi-day slopes through periods with no readings. - Prefer not carrying outdoor temp forward across long gaps (LOCF); a visible break is more honest than inventing overnight ambient.
That combination stays faithful to the log while keeping the chart readable for “mostly complete” awake/driving stretches.
6. Query reuse / cost
Several panels re-scan positions for overlapping stats (last, min/max, history, heatmap). Prefer one or few shared queries + transformations / shared query results for last, min/max, history, and daily aggregates—cheaper and less drift between panels. Avoid shipping every raw position row for long ranges (30d default).
Happy to re-review after a revision. Happy to help iterate on the daily candlestick or connect-threshold if useful.
🤖 Assisted by Grok 4.5 (xAI) via Grok Build (planning, review drafting).
…hboards Review feedback teslamate-org#1 and teslamate-org#2 of PR teslamate-org#5457: - add hidden temp_unit variable (settings.unit_of_temperature) and wrap all temperature values in convert_celsius(); unit is carried in the field names ([°C]/[°F]) like in the other provisioned dashboards - drop Celsius-specific value thresholds (not convertible per unit) and the hardcoded °C axis labels; add decimals: 1 - add base_url variable, TeslaMate header link and Dashboards dropdown to match the other provisioned dashboards Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
✅ Deploy Preview for teslamate ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
…stick Review feedback teslamate-org#3 of PR teslamate-org#5457: the frequency heatmap counted raw positions samples, which over-weights driving (dense logging) vs parking and reads misleadingly as "time at temperature". Replace it with a daily candlestick computed on time-debiased inputs: readings are first averaged into fixed 15-minute bins, then aggregated per day (wick = min/max, body = 15th-85th percentile). Days without samples have no candle. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ro chart Review feedback teslamate-org#5 of PR teslamate-org#5457 plus iteration on the setpoint display: - last-value stats fetch the single latest reading (ORDER BY date DESC LIMIT 1) instead of scanning the whole selected range, and drop the patchy area sparkline (graphMode: none) - history chart breaks its lines on gaps longer than 1h (insertNulls) instead of interpolating through sleep/offline periods; short gaps still connect (spanNulls threshold); rows without any temperature reading no longer create empty buckets - fold the driver setpoint into the main history chart as a thin dashed step line and remove the separate climate setpoints panel (passenger setpoint dropped as redundant); charging panel widens to full width Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…processes Review feedback teslamate-org#6 of PR teslamate-org#5457: - the two min/max stats now share a single positions scan: the outside panel computes all four values, the inside panel consumes its result via a dashboard (shared query) datasource - the charging panel reads the pre-aggregated charging_processes.outside_temp_avg (one row per charge) instead of joining and grouping raw charges samples; drawn as points with a dotted trend line - combined with the LIMIT-1 last-value stats and the setpoint folded into the history query, the dashboard is down to three range scans over positions (min/max, history, daily candlestick) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Thanks for the thorough review! Addressed in the latest commits:
Screenshot updated to the reworked layout. Of course, happy to make further changes if needed. |
There was a problem hiding this comment.
Thanks a lot for the thorough rework, Daniel — what I said when you opened this PR still stands, and you've since proven it: you took on every single point of @swiffer's detailed review and addressed the core of all of them — units, dashboard shell, the candlestick replacing the heatmap, shared queries. That's more than many seasoned contributors manage in one revision.
A few things surfaced in my final pass — one blocker, a couple of fixes, and some polish. Don't be discouraged by the list; most of these are subtle TeslaMate-specifics you couldn't have known, and I'm happy to help with any of them.
Blocking (CI will fail and is failing)
- The two "last value" queries need
ideal_battery_range_km IS NOT NULL. We have a schema-contract test (test/teslamate/grafana/dashboard_queries_test.exs) that requires this predicate on everyFROM positions … ORDER BY date DESC LIMIT 1query — it's what makes our partial index from #5438 usable; without it each tile scans the car's entire position history. Easiest fix: copy the Overview pattern (overview.json), which adds the predicate plusdate >= (TIMEZONE('UTC', NOW()) - INTERVAL '60m')— the freshness bound also makes a week-old reading render as "No data" instead of posing as the current temperature.
Should be fixed before merge
-
Daily candles are cut at UTC midnight.
date_trunc('day', bin)truncates in the server timezone while the dashboard renders in browser time — for a user at UTC+10 every candle spans 10:00–10:00 local and the overnight minimum lands in the wrong day. Please use the repo's 3-arg pattern, e.g.date_trunc('day', timezone('UTC', date), '$__timezone')(seestatistics.json/drive-stats.json, documented in our development docs - Queries involving timestamp columns). -
The main history panel goes blank at long ranges. With
insertNulls: 3600000+spanNulls: 3600000, once$__intervalexceeds 1 h (roughly ≥ 6-month ranges), a break is inserted between every pair of buckets and can never be re-connected — combined withshowPoints: "never"the chart renders essentially nothing. The 30d default hides this, so it's easy to miss in testing. One option that scales with zoom: dropinsertNulls, use$__timeGroup(date, $__interval, NULL)to null-fill only truly empty buckets, and keep thespanNullsthreshold — @swiffer, you had the clearest picture here, what combination would you go for? -
Please export the JSON through the bundled Grafana (13.1.3 atm, "Save JSON to file", as described in our development docs - Making Changes to Grafana Dashboards). The file is currently hand-formatted with
pluginVersion: "13.0.1+security-01"and a custom uid — the next re-export round-trip would rewrite the whole file and bury real changes in a formatting diff.
Polish (quick wins)
README.mdlists all bundled dashboards alphabetically — please addTemperaturesbetween Statistics and Timeline.- Candlestick colors: with open = p15 and close = p85,
close >= openalways holds, so every candle renders "up"/red — a fixed single color would be more honest (red reads as "hot" on a temperature chart). - The four stat tiles use
unit: "none"while the graphs use"degree"— using"degree"like the Overview temperature stats gives the tiles the ° suffix too.
One design question (no action needed from you yet)
The driver setpoint is now drawn whenever the car reports data, including while climate is off — a parked car draws a continuous setpoint line while the cabin drifts to ambient. Your reasoning for dropping the is_climate_on filter (line collapsing to dots at 30d) makes sense to me; @swiffer, are you fine keeping it as is, perhaps renaming the series to make clear it's the reported setting rather than active conditioning?
The dashboard fills a real gap in our default set and is very close now. Thanks for sticking with it through the review rounds — hope we'll see more contributions from you after this one! 🧡
🤖 Review drafted with Claude Code (Fable 5 high) — sponsored by Claude for Open Source
|
Hey @slayer01, Some minor changes for the Daily Candles, see the screenshot for what i would suggest to change in addition:
New tooltip text:
Why the coverage line was added How it is placed
|



Add a Grafana dashboard with a historical overview of all temperatures logged by TeslaMate: