Skip to content

Commit 29c0595

Browse files
atulmguptaCopilot
andauthored
feat(analysis): physics ledger, science lab and Grafana dashboards (#113)
* feat(grafana): day-log, physics honesty, ledger, fleet-ops, outage, science dashboards 16 new boards (14 system, 1 infra, 1 science) closing the coverage gaps in grafana/DASHBOARD-COVERAGE.md: day-log spine, physics cockpit/ledger, charge honesty, vampire watts, firmware epochs, black-box 90s, range disagreement, fleet ops, outage autobiography, pack-capacity proxy, site energy, charging/cabin thermal, phase-42 pipeline, science lab inputs. Conventions: SI queries with settings-backed converters, unique teslasync- UIDs, $vehicle_id templating, honesty text per board, no fake series. Science board shows API input counts only (fits stay in the API). Home links the new UIDs; provisioning + sync map gain the science folder; SLO catalog gains physics_ledger_availability + science_lab_availability. * feat(analysis): harden physics ledger and science lab Add canonical analysis services and complete shared UI panels, enforce scientific evidence boundaries, and correct Grafana observations and SLO artifacts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(ci): respect handler ratchet and recognize optional config bindings Move analysis transport to its own v1 subpackage and teach config parity to recognize optional float bindings with a regression test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(ci): stabilize rolling dates in visual snapshots Scope the Playwright fixed clock to visual cases while preserving shared browser seeding and running timers. Keep existing snapshots and tolerances unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 878b14e commit 29c0595

137 files changed

Lines changed: 19480 additions & 78 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docker-compose.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ services:
4646
- TESLA_API_BASE_URL=${TESLA_API_BASE_URL:-https://fleet-api.prd.na.vn.cloud.tesla.com}
4747
- TESLA_API_DAILY_BUDGET_USD=${TESLA_API_DAILY_BUDGET_USD:-0.30}
4848
- TESLA_API_COMMAND_RESERVE_USD=${TESLA_API_COMMAND_RESERVE_USD:-0.05}
49+
- TESLASYNC_VEHICLE_MASS_KG=${TESLASYNC_VEHICLE_MASS_KG:-}
50+
- TESLASYNC_VEHICLE_CDA_M2=${TESLASYNC_VEHICLE_CDA_M2:-}
51+
- TESLASYNC_VEHICLE_CRR=${TESLASYNC_VEHICLE_CRR:-}
52+
- TESLASYNC_TIRE_RECOMMENDED_KPA=${TESLASYNC_TIRE_RECOMMENDED_KPA:-}
53+
- TESLASYNC_SCIENCE_WEATHER_ENABLED=${TESLASYNC_SCIENCE_WEATHER_ENABLED:-false}
4954
- WORKER_POLL_INTERVAL=${WORKER_POLL_INTERVAL:-30s}
5055
- TESLASYNC_LOG_LEVEL=${LOG_LEVEL:-error}
5156
- FLEET_TELEMETRY_ENABLED=${FLEET_TELEMETRY_ENABLED:-false}

docs/features/catalogue-tesla-physics.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ Sidebar group **Tesla Physics**. In the app, expand this section in the left nav
44

55
| Screen | Path | What it does | When empty |
66
| ------ | ---- | ------------ | ---------- |
7-
| Physics hub | `/tesla-only` | Fifteen Tesla physics views Tesla app and TeslaMate cannot own. | Renders an empty state when no data is available — the page is not hidden. |
7+
| Physics hub | `/tesla-only` | Tesla physics views Tesla app and TeslaMate cannot own. | Renders an empty state when no data is available — the page is not hidden. |
8+
| Physics Ledger | `/tesla-only/ledger` | VIN-scoped energy/force solver: predicted vs measured, unexplained residual, unknown budget. | Shows unknown honestly when signals are missing; never zero-fills. |
9+
| Science Lab | `/science` | Rest-voltage and apparent-resistance proxies, conditional regression fits, thermal transients, weather correlations, tire models, and generated analysis reports. | Unsupported fits stay unknown. CIs and holdouts are shown only when computed; these are not causal experiments. |
810
| Three Clocks | `/tesla-only/clocks` | Event, ingest, and display time. Ingest stays unknown if not stored. | Renders an empty state when no data is available — the page is not hidden. |
911
| Life Tape | `/tesla-only/life-tape` | Every second is Park, Neutral, Drive, Charge, or Unknown — not GPS. | Renders an empty state when no data is available — the page is not hidden. |
1012
| Contradiction Court | `/tesla-only/contradictions` | Gear=P with speed is a contradiction. Complete still latched is not. | Renders an empty state when no data is available — the page is not hidden. |
@@ -21,4 +23,38 @@ Sidebar group **Tesla Physics**. In the app, expand this section in the left nav
2123
| Nervous System | `/tesla-only/nervous-system` | BMS, Gear, latch, and trip meters: alive, silent, or contradicting. | Renders an empty state when no data is available — the page is not hidden. |
2224
| Range Disagreement | `/tesla-only/range` | Rated, typical, ideal, and energy remaining. Never a true range. | Shows unknown/empty honestly when signals are missing. |
2325

26+
## Analysis boundaries
27+
28+
New HTTP routes use `internal/handler/v1/analysis` and the `physicssvc` / `sciencesvc`
29+
application services. The ledger uses recorded intervals, exposes gaps and row
30+
caps, and does not reconcile partial telemetry against a complete session.
31+
Explicit `Disconnected` state, not latch release, denotes unplugging.
32+
Energy/motion integrations reject seed-only values and observations older than
33+
two minutes instead of treating forward-filled power as a fresh measurement.
34+
35+
Science fits use the latest contiguous firmware epoch. Voltage/current steps
36+
must be timestamp-aligned; seed-only freshness is unknown. Rest-end voltage is
37+
not proven equilibrium OCV, and pack resistance is not cell resistance.
38+
Thermal fits do not bridge separate Park episodes, active heating, long gaps,
39+
or drifting ambient conditions, and require observed zero HVAC power.
40+
Tire uncertainty is a model sensitivity band,
41+
not a calibrated 95% confidence interval.
42+
43+
**The broader science loop is not fully implemented:** throughput/rest exposure
44+
does not identify separate cycle/calendar aging; generated notebook rows are
45+
not persisted reproducible experiments; not every model has independent-day
46+
holdouts or correlation-robust uncertainty. The UI must not imply otherwise.
47+
Grafana exposes observations and model inputs, not persisted solver fits.
48+
Charging throughput describes returned, completed sessions contained in the
49+
requested window, not lifetime exposure. It remains unknown when session energy
50+
is missing, unbounded, invalid, or capped; equivalent cycles use the explicitly
51+
labeled assumed reference capacity. Rest exposure is limited to the fitted
52+
firmware epoch and must not be treated as the same coverage as session throughput.
53+
54+
Weather joins are disabled by default. Set
55+
`TESLASYNC_SCIENCE_WEATHER_ENABLED=true` (Helm:
56+
`physics.weatherEnabled: true`) only after accepting that drive-start
57+
coordinates will be sent to Open-Meteo. Archive density uses surface pressure.
58+
Without this opt-in, weather remains explicitly unavailable.
59+
2460
[← All groups](./catalogue.md)

grafana/DASHBOARD-COVERAGE.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# TeslaSync Grafana Dashboard Coverage
2+
3+
Source of truth for operators: repo JSON + `python scripts/sync_grafana_dashboards.py`.
4+
Helm only ships SLO/RUM dashboards (`helm/teslasync/files/grafana/dashboards/`); everything
5+
below lives in `grafana/dashboards/{system,infra,science}/` and is provisioned via
6+
`grafana/provisioning/dashboards/dashboards.yml` (compose) or the sync script (production).
7+
8+
Conventions: queries are SI (`_m`, `_mps`, `_wh`, `_w`, `_kpa`, `°C` as stored).
9+
Display conversion happens in panel units or the settings-backed SQL converters
10+
(`convert_distance_m`, `convert_speed_mps`, `convert_pressure_pa`, `convert_temp`).
11+
No `_mi/_mph/_kwh` columns in new SQL.
12+
13+
## Current inventory (77 dashboards — do not clone or duplicate UIDs)
14+
15+
The base inventory below contains 61 dashboards; the coverage table records
16+
the 16 additions (14 system, one infra, one science).
17+
18+
### System (`TeslaSync - System`, 59 files; 45 base files below)
19+
20+
| File | UID | Title |
21+
| ---- | --- | ----- |
22+
| alerts-notifications.json | teslasync-alerts-notifications | Alerts & Notifications |
23+
| anomaly-detection.json | teslasync-anomaly-detection | Anomaly Detection |
24+
| battery-cells.json | teslasync-battery-cells | Battery Cells |
25+
| battery-degradation.json | teslasync-battery-degradation | Battery Degradation |
26+
| battery-health.json | teslasync-battery-health | Battery Health |
27+
| charging-curve.json | teslasync-charging-curve | Charging Curve |
28+
| charging-driving-correlation.json | teslasync-charging-driving | Charging vs Driving |
29+
| charging-heatmap.json | teslasync-charging-heatmap | Charging Heatmap |
30+
| charging-sessions.json | teslasync-charging-sessions | Charging Sessions |
31+
| charging-stats.json | teslasync-charging-stats | Charging Analytics |
32+
| charging.json | teslasync-charging | Charging History |
33+
| climate-hvac.json | teslasync-climate-hvac | Climate & HVAC |
34+
| comfort-media.json | teslasync-comfort-media | Comfort & Media |
35+
| compare.json | teslasync-compare | Change Delta Stats |
36+
| cost-analysis.json | teslasync-cost-analysis | Cost Analysis |
37+
| drive-detail.json | teslasync-drive-detail | Drive Detail |
38+
| drive-score.json | teslasync-drive-score | Drive Scores |
39+
| drives.json | teslasync-drives | Drive History |
40+
| drivetrain-thermal.json | teslasync-drivetrain-thermal | Drivetrain Thermal |
41+
| driving-dynamics.json | teslasync-driving-dynamics | Driving Dynamics |
42+
| efficiency.json | teslasync-efficiency | Driving Efficiency |
43+
| energy-flow.json | teslasync-energy-flow | Energy Flow |
44+
| fleet-overview.json | teslasync-fleet-overview | Fleet Overview |
45+
| home.json | teslasync-home | Home |
46+
| locations.json | teslasync-locations | Visited Locations |
47+
| mileage.json | teslasync-mileage | Mileage |
48+
| motor-performance.json | teslasync-motor-performance | Motor Performance |
49+
| projected-range.json | teslasync-projected-range | Range Projection |
50+
| quick-stats.json | teslasync-quick-stats | Quick Stats |
51+
| regen-efficiency.json | teslasync-regen-efficiency | Regen Efficiency |
52+
| route-efficiency.json | teslasync-route-efficiency | Route Efficiency |
53+
| security-access.json | teslasync-security-access | Security & Access |
54+
| sleep-efficiency.json | teslasync-sleep-efficiency | Sleep Efficiency |
55+
| software-updates.json | teslasync-software-updates | Software Updates |
56+
| speed-profile.json | teslasync-speed-profile | Speed Profile |
57+
| statistics.json | teslasync-statistics | Monthly Statistics |
58+
| system-health.json | teslasync-system-health | System Health |
59+
| timeline.json | teslasync-timeline | State Timeline |
60+
| tire-pressure.json | teslasync-tire-pressure | Tire Pressure |
61+
| trips.json | teslasync-trips | Trip History |
62+
| true-cost.json | teslasync-true-cost | True Cost |
63+
| vampire-drain.json | teslasync-vampire-drain | Vampire Drain (%/hr, BatteryLevel) |
64+
| vehicle-intelligence.json | teslasync-vehicle-intelligence | Vehicle Intelligence |
65+
| vehicle-overview.json | teslasync-vehicle-overview | Vehicle Overview |
66+
| weekly-digest.json | teslasync-weekly-digest | Weekly Digest |
67+
68+
### Infra (`TeslaSync - Infra`, 17 files; 16 base files below)
69+
70+
| File | UID | Title |
71+
| ---- | --- | ----- |
72+
| api-performance.json | teslasync-infra-api-perf | API Performance |
73+
| auth-deep-dive.json | teslasync-infra-auth-deep-dive | OAuth Initiation Deep-Dive |
74+
| cep-rule-engine.json | teslasync-infra-cep | Rules Engine |
75+
| critical-flows.json | teslasync-infra-critical-flows | Critical Flow Latency |
76+
| db-tesla-breakdown.json | teslasync-infra-db-tesla-breakdown | DB & Tesla API Span Breakdown |
77+
| fleet-telemetry.json | teslasync-infra-fleet-telemetry | Fleet Telemetry Server |
78+
| infrastructure.json | teslasync-infra-health | Infrastructure Health |
79+
| mqtt-pipeline-traces.json | teslasync-infra-mqtt-pipeline-traces | MQTT Pipeline Trace View |
80+
| observability-self-health.json | teslasync-infra-otel-self-health | Observability Self-Health |
81+
| service-graph.json | teslasync-infra-service-graph | Service Graph & Dependencies |
82+
| service-red.json | teslasync-infra-service-red | Service RED |
83+
| sessions-business.json | teslasync-infra-sessions | Sessions & Business Metrics |
84+
| slo-burn.json | teslasync-infra-slo-burn | SLO / Error Budget Board |
85+
| sse-realtime.json | teslasync-infra-sse | SSE & Real-Time |
86+
| telemetry-pipeline.json | teslasync-infra-telemetry | Telemetry Pipeline |
87+
| trace-explorer.json | teslasync-infra-trace-explorer | Trace Explorer |
88+
89+
### Helm-only (link, do not clone)
90+
91+
SLO per-endpoint boards (`slo-*.json`), `frontend-rum-overview.json`,
92+
`frontend-synthetic-journeys.json`.
93+
94+
## Gap table (app domain → Grafana)
95+
96+
| App path / domain | Existing Grafana JSON | Gap → action |
97+
| ----------------- | --------------------- | ------------ |
98+
| `/day-log` day log / FSM spine | `timeline.json` (state timeline only) | **NEW** `system/day-log.json`: event counts by field/day, gap hours, caps |
99+
| Tesla Physics cockpit (`/tesla-only/clocks`, gear) || **NEW** `system/physics-cockpit.json`: Gear/ChargeState/latch enums from `signal_log` |
100+
| Physics ledger (`/tesla-only/ledger`) || **NEW** `system/physics-ledger.json`: timestamp-aligned electrical observations with actual elapsed integration and a separate labeled aero illustration. This is **not** the configured app solver or its full unexplained residual. |
101+
| Charge honesty (`/tesla-only/charge-port`) | `charging-curve.json` (curve only) | **NEW** `system/charge-honesty.json`: phase durations, Complete→Disconnected dwell |
102+
| Vampire watts | `vampire-drain.json` (%/hr only) | **NEW** `system/vampire-watts.json`: watts from EnergyRemaining Wh deltas (existing file is %-based, left untouched) |
103+
| Firmware epochs (`/tesla-only/firmware-epochs`) | `software-updates.json` (update events) | **NEW** `system/firmware-epochs.json`: efficiency/residual by Version (correlation honesty) |
104+
| Black box 90s (`/tesla-only/black-box`) || **NEW** `system/black-box-90s.json`: high-rate speed/power before Park/unplug |
105+
| Range disagreement (`/tesla-only/range`) | `projected-range.json` (projection) | **NEW** `system/range-disagreement.json`: rated/typical/ideal spread, never one true series |
106+
| Fleet ops / utilization | `fleet-overview.json` (fleet totals) | **NEW** `system/fleet-ops.json`: reservations, assignments, cost centers from fleet tables |
107+
| Outage autobiography | — (infra has traces) | **NEW** `system/outage-autobiography.json`: last-event-time vs broker, gaps |
108+
| Pack capacity proxy | `battery-degradation.json` (SOH product) | **NEW** `system/pack-capacity-proxy.json`: Wh proxy + n, no SOH% |
109+
| Site energy (solar/Powerwall) | `energy-flow.json` (vehicle flow) | **NEW** `system/site-energy.json` from `tesla_energy_history`/`tesla_energy_sites` |
110+
| Ownership tariffs/invoices | `true-cost.json`, `cost-analysis.json` | **EXTEND in place only if needed**; new `system/ownership-cost.json` skipped — tariff tables feed cost honesty note in `site-energy`/true-cost scope (see below) |
111+
| Charging thermal tax / interruptions | `charging-stats.json` (analytics) | **NEW** `system/charging-thermal.json`: pack temp vs power, interruption counts |
112+
| Cabin thermal / preconditioning | `climate-hvac.json` (HVAC state) | **NEW** `system/cabin-thermal.json`: soak/cooldown τ inputs, precondition Wh |
113+
| Science Lab (`/science`) || **NEW** `science/lab-inputs.json`: electrochem brick-spread and aligned VI observations, thermal/TPMS rows and consumption-vs-ambient inputs. Fits remain in `GET /science/*` (`internal/app/sciencesvc`); weather and notebook reports are generated per request, not stored. Input counts are not counts of qualified experiments. |
114+
| Phase-42 pipeline (infra) | `telemetry-pipeline.json`, `fleet-telemetry.json` | **NEW** `infra/phase42-pipeline.json`: writer failures vs codec, normalize throughput, L1/L2 lag, FSM ticks |
115+
| Frontend RUM | helm `frontend-rum-*.json` | Link only, no clone |
116+
| Time machine / twin-lab || **Deferred**: no counterfactual tables on branch; no stub |
117+
| SLOs for new APIs | helm `slo-*.json` (generated) | `physics_ledger_availability` and `science_lab_availability` include generated recording rules, burn alerts, and dashboards. Regenerate with `cmd/slogen` when the catalog changes. |
118+
| Ops home | `system/home.json` | **EXTEND**: links to new UIDs |
119+
120+
## Ownership-cost decision
121+
122+
`true-cost.json` + `cost-analysis.json` already cover measured cost. Tariff/invoice
123+
tables (`utility_tariffs`, `charging_invoices`) are operator-configured, not
124+
measured telemetry — a separate `ownership-cost.json` would duplicate true-cost
125+
scope. Tariff-unknown honesty is noted in `site-energy.json` instead. No new file.

0 commit comments

Comments
 (0)