github teslamate-org/teslamate v4.3.0

3 hours ago

The vehicle display order can now be edited on the settings page, a new dashboard shows historical temperatures, and we use the latest Grafana (13.2.2).
When a car is assigned to the Tesla account while TeslaMate is running, you no longer need to restart TeslaMate: a reload button starts logging the car.
The geo-fence links in the Grafana dashboards now open in the same tab, so the Back button returns to the dashboard and the Grafana URL is detected automatically again.

Under the hood, this release adds a self-verifying black-box characterization suite: recorded API sequences replay through the real vehicle state machine, and everything that leaves the system — database rows, MQTT messages, and the vehicle's interactions with the streaming API and its supervisor — is compared against known-good results with 93.9 % coverage.
It is the basis for the upcoming rework of the state machine and the Rust rewrite, and writing it already uncovered three bugs, all fixed in this release (#5656, #5684, #5693). Five more findings (#5699, #5714, #5716, #5718, #5742) sit in code the rework replaces, so they are fixed there instead of patched twice.

Note for Home Assistant MQTT discovery users: TeslaMate no longer re-runs the discovery migration on every restart, which briefly removed and recreated entities. Instead it clears the former per-entity topics and republishes the device config; Home Assistant logs one harmless "conflicting MQTT discovery message" warning per legacy topic after each restart, entities are untouched.
Upgrading directly from 4.1.x no longer preserves entity registry customizations — see the docs.

To make your TeslaMate experience even better, we have made 120 improvements.

Enjoy!

New features

  • feat(webview): make the vehicle display order editable on the settings page (#5741 - @wooter)
  • feat(web): explain why no vehicle is logged and offer a reload button that starts loggers for vehicles added to the Tesla account, instead of requiring a restart (#5710 - @JakobLichterfeld)
  • feat(web): show the copyright, license and no-warranty notice in the footer, with the NOTICE and LICENSE of the running version (#5779 - @JakobLichterfeld)

Improvements and bug fixes

  • fix(vehicle): cancel an update with the logged update row instead of the API payload, which crashed the vehicle process and left the update open forever (#5664 - @JakobLichterfeld)
  • fix(web): remove stray brace from the direction arrow SVG path, which made Safari log a parse error on every position update (#5665 - @JakobLichterfeld)
  • refactor(vehicle): route the vehicle's view of time through a clock seam (#5688 - @JakobLichterfeld)
  • refactor(vehicle): date timestamp-less state rows through the clock seam (#5689 - @JakobLichterfeld)
  • fix(vehicle): keep logging when the car reports an outdated timestamp after being offline or asleep — previously the vehicle process crashed on every poll and the state stayed stuck (#5692 - @JakobLichterfeld)
  • feat: use Grafana 13.2.1 (#5694 - @swiffer)
  • fix(mqtt): stop re-running the Home Assistant discovery migration on every restart (#5685 - @nebhale)
  • fix(vehicle): keep the published state start time from jumping backwards after charging, updating or driving (#5706 - @JakobLichterfeld)
  • fix(web): pin the size of Leaflet's SVG overlay so the vehicle arrow and geofence circle stay on the map at any Safari page zoom (#5666 - @JakobLichterfeld)
  • fix(grafana): open the TeslaMate header link in a new tab so it works when Grafana and TeslaMate share an origin (#5626 - @misenhower)
  • fix(web): make the Back button return to the Grafana dashboard and detect the Grafana URL despite origin-only referrers (#5709 - @JakobLichterfeld)
  • refactor(vehicle): simplify the state machine: plain atom states, DB records moved into the state data (#5259 - @brianmay, @JakobLichterfeld)
  • feat: use Grafana 13.2.2 (#5744 - @swiffer)
  • fix(web): send the referrer and show the OpenStreetMap attribution on map tiles, so tiles load behind reverse proxies that set a stricter referrer policy such as same-origin or no-referrer and TeslaMate complies with the OSM tile usage policy (#5765 - @JakobLichterfeld)
  • fix(web): show VIN and trim tooltips below the car title on mobile, so they no longer get cut off at the left edge (#5774 - @JakobLichterfeld)
  • legal: add NOTICE and state AGPL-3.0-or-later consistently (#5777 - @JakobLichterfeld)
  • legal: rewrite the trademark policy with definitions and an exhaustive list of permitted uses (#5777 - @JakobLichterfeld)
  • fix(auth): no longer follow redirects when refreshing the token, so the refresh token and the fleet token are never sent to another host (#5781 - @JakobLichterfeld)
  • fix(auth): tell rejected tokens apart from every other refresh failure, so the sign-in page names the actual cause (#5781 - @JakobLichterfeld)
  • fix(web): report a sign-in that exits instead of crashing the sign-in page (#5781 - @JakobLichterfeld)
  • fix(auth): keep credentials out of the log, even on the debug level (#5782 - @JakobLichterfeld)
  • feat(web): skip the modal animation when the system asks for reduced motion, with own fade and scale CSS (#5784 - @JakobLichterfeld)
  • fix(geocoder): fill the address fields by Nominatim's address ranks (#5785 - @JakobLichterfeld)
  • legal: declare copyright and license of every file in REUSE.toml and check REUSE compliance in CI (#5789 - @JakobLichterfeld)
  • legal: add the MIT notice to NOTICE for earlier contributions the relicensing does not cover (#5789 - @JakobLichterfeld)
  • style: spell the name as TeslaMate throughout, including the creator of GPX exports (#5798 - @JakobLichterfeld)
  • fix(docker): start with a PostgreSQL that is reachable only through its Unix socket (#5800 - @JakobLichterfeld)

Build, CI, internal

  • test: add characterization harness replaying API fixtures against persisted rows and MQTT (#5653 - @JakobLichterfeld)
  • test(characterization): convert driving scenarios to characterization fixtures (#5654 - @JakobLichterfeld)
  • test(characterization): convert charging scenarios to characterization fixtures (#5655 - @JakobLichterfeld)
  • test(characterization): convert updating scenarios to characterization fixtures. Pins the update-cancel crash (#5656) that mock-based tests could not see (#5658 - @JakobLichterfeld)
  • test(characterization): convert streaming scenarios to characterization fixtures (#5668 - @JakobLichterfeld)
  • fix(test): give the error_event selftest a settled terminal cycle (#5670 - @JakobLichterfeld)
  • fix(test): move the offline-resume scenario off the 15-minute boundary (#5681 - @JakobLichterfeld)
  • test(characterization): enforce the two-call-terminal limit (#5683 - @JakobLichterfeld)
  • test(characterization): convert suspend_logging scenarios to characterization fixtures (#5687 - @JakobLichterfeld)
  • test(characterization): run replays on a scenario clock, retire timebase (#5690 - @JakobLichterfeld)
  • test(characterization): pin the stale-timestamp resume crash (#5691 - @JakobLichterfeld)
  • test(characterization): convert suspend scenarios to characterization fixtures (#5695 - @JakobLichterfeld)
  • test(characterization): convert summary scenarios to characterization fixtures (#5696 - @JakobLichterfeld)
  • test(characterization): convert vehicle scenarios to characterization fixtures, add the update_car_settings call (#5697 - @JakobLichterfeld)
  • test(characterization): convert the remaining vehicle scenarios — resume_logging and summary calls, expect_halt, seed positions, Vehicles stand-in (#5698 - @JakobLichterfeld)
  • test(characterization): pin charge samples without charger_power (#5700 - @JakobLichterfeld)
  • test(characterization): pin stream connect/disconnect and the supervisor kill as golden interactions (#5704 - @JakobLichterfeld)
  • test(characterization): name the scenario event behind a mismatch on a dated row (#5705 - @JakobLichterfeld)
  • build(deps): bump browserslist from 4.28.2 to 4.28.9 in /website (#5707)
  • build(deps): bump fast-uri from 3.1.5 to 3.1.7 in /website (#5686)
  • build(deps): bump http-proxy-middleware from 2.0.9 to 2.0.10 in /website (#5708)
  • build(deps): update flake.lock (#5659)
  • build(deps): bump the actions-deps group across 4 directories with 8 updates (#5679)
  • build(deps): bump phoenix from 1.8.9 to 1.8.13 (#5672)
  • build(deps): bump postgrex from 0.22.3 to 0.22.4 (#5673)
  • build(deps-dev): bump sass from 1.102.0 to 1.103.1 in /assets (#5674)
  • build(deps-dev): bump esbuild from 0.28.1 to 0.28.2 in /assets (#5675)
  • build(deps): bump castore from 1.0.20 to 1.0.21 (#5676)
  • build(deps): bump srtm from 0.8.0 to 0.9.0 (#5677)
  • build(deps): bump phoenix_live_view from 1.2.8 to 1.2.11 (#5678)
  • test(characterization): pin the pre-online check of the streaming API (#5712 - @JakobLichterfeld)
  • test(characterization): pin the suspended state's resume, usage and inactive-stream paths (#5713 - @JakobLichterfeld)
  • test(characterization): pin vehicle identification — model, trim and marketing name from vehicle_config and VIN (#5715 - @JakobLichterfeld)
  • test(characterization): pin payload edge cases — charge defaults of the offline charge inference and stream frames against a merged or timestamp-less last response (#5717 - @JakobLichterfeld)
  • test(characterization): pin the power-usage suspend guard and service mode across an idle suspend (#5719 - @JakobLichterfeld)
  • test(characterization): pin generic API errors while driving, charging and on the manual suspend fetch, the asleep/offline transitions and the polling doubling after resume_logging (#5723 - @JakobLichterfeld)
  • build(deps): bump @swc/html from 1.15.46 to 1.16.2 in /website (#5720)
  • build(deps): bump colord from 2.9.3 to 2.10.0 in /website (#5721)
  • build(deps): bump js-yaml from 4.3.1 to 4.3.2 in /website (#5724)
  • build(deps): bump svgo from 3.3.4 to 3.3.5 in /website (#5725)
  • build(deps): bump joi from 17.13.4 to 17.13.7 in /website (#5726)
  • test(characterization): pin settings toggles during charging and while parked; the harness call seam serves stream connect and disconnect (#5727 - @JakobLichterfeld)
  • test(characterization): pin a charge inside a geofence — geofence_id, per-kWh cost and the geofence topic (#5736 - @JakobLichterfeld)
  • test(characterization): pin a drive in import mode — no address lookup, halt on import_complete (#5737 - @JakobLichterfeld)
  • test(characterization): add the too_many_request error form, seed.updates and per-scenario Home Assistant discovery to the harness, with first users (#5740 - @JakobLichterfeld)
  • test(characterization): pin the reconnecting stream controls and the missing stream after a service visit (#5743 - @JakobLichterfeld)
  • test(vehicle): make the store-position interval configurable and lock the state-machine field lifecycle with regression tests (#5259 - @JakobLichterfeld)
  • refactor: move the Elixir application to elixir/, so the repository root is prepared for the Rust core next to it; tooling, CI and docs point at the new path (#5745 - @JakobLichterfeld)
  • chore(ci): fix the shellcheck and untrusted-input findings from actionlint (#5759 - @JakobLichterfeld)
  • fix(ci): apply the OCI labels to the Grafana images (#5761 - @JakobLichterfeld)
  • fix(ci): pass the build action inputs through env and expressions (#5762 - @JakobLichterfeld)
  • build(deps): bump react and react-dom from 19.2.8 to 19.3.0 in /website (#5751)
  • build(deps): bump nanoid from 3.3.16 to 3.3.19 in /website (5760)
  • build(deps): bump the actions-deps group across 4 directories with 7 updates (#5758)
  • build(deps): bump elixir from 1.20.2-otp-29 to 1.20.3-otp-29 (#5747)
  • build(deps-dev): bump sass from 1.103.1 to 1.104.1 in /elixir/assets (#5749)
  • build(deps): bump @geoman-io/leaflet-geoman-free from 2.20.0 to 2.20.1 in /elixir/assets (5750)
  • build(deps-dev): bump phoenix_live_reload from 1.6.2 to 1.7.0 in /elixir (#5753)
  • build(deps-dev): bump credo from 1.7.18 to 1.7.19 in /elixir (#5755)
  • build(deps): bump ecto_sql from 3.13.5 to 3.14.0 in /elixir (#5757)
  • build(deps): update flake.lock (#5728)
  • feat(rust): add the Rust core skeleton under rust/ — crate, CI with path routing, Nix package and devenv toolchain (#5703 - @brianmay, @JakobLichterfeld)
  • build(rust): choose Tokio as the async runtime (#5772 - @brianmay)
  • build(deps): bump tzdata from 1.1.4 to 1.2.1 in /elixir (#5771)
  • build(deps): remove unused hackney lock entries after tzdata 1.2.1 (#5771 - @JakobLichterfeld)
  • build(deps): bump tesla from 1.20.0 to 1.21.3 in /elixir (#5767)
  • build(deps): bump phoenix_live_view from 1.2.11 to 1.2.12 in /elixir (#5768)
  • build(deps-dev): bump dialyxir from 1.4.7 to 1.4.8 in /elixir (#5769)
  • build(deps): bump tortoise311 from 0.12.2 to 0.12.3 in /elixir (#5770)
  • fix(test): restart cars_id_seq at suite start so smallint cars.id never overflows across local runs (#5773 - @JakobLichterfeld)
  • build: ship NOTICE and LICENSE in both images and both Nix packages, and declare AGPL-3.0-or-later in the Nix metadata (#5778 - @JakobLichterfeld)
  • build(deps): bump image-size from 2.0.2 to 2.0.4 in /website (#5783)
  • test(geocoder): pin which address label fills which field, and in which order (#5785 - @JakobLichterfeld)
  • test(geocoder): pin the address fields of 19 recorded Nominatim addresses (#5785 - @JakobLichterfeld)
  • build: stop building the Grafana image for ARMv7, which is no longer supported (#5788 - @JakobLichterfeld)
  • build(deps): update flake.lock (#5790)
  • feat(rust): read the configuration from environment variables and take the version from the VERSION file (#5776 - @brianmay, @JakobLichterfeld)
  • fix(nix): trim the VERSION file for the Elixir package, so a trailing newline no longer ends up in its name (#5776 - @JakobLichterfeld)
  • fix(test): mask TeslaMate's version in the discovery goldens, so a release no longer breaks the characterization tests (#5802 - @JakobLichterfeld)

Dashboards

  • feat(grafana): add total period to the Statistics dashboard for one aggregated row over the selected time range (#5680 - @micku7zu)
  • fix(grafana): count asleep/offline states that cross a parking boundary in the vampire drain standby time (#5729 - @rewse)
  • fix(grafana): fall back to the neighbourhood where an address has no city (#5785 - @JakobLichterfeld)
  • feat(grafana): add a new dashboard showing historical temperatures (#5457 - @slayer01)

Translations

  • fix(i18n): translate the import page, the car summary, the car order setting and the validation errors into German (#5786 - @JakobLichterfeld)

Documentation

  • docs: add AI-assisted contribution policy and Grafana dashboard notes (#5578 - @swiffer)
  • docs(faq): explain how to add a car that shows up in the Tesla account after start-up and reorder the entries (#5766 - @JakobLichterfeld)
  • docs: declare MQTT the only supported integration surface; database and web routes are internal (#5775 - @JakobLichterfeld)
  • docs: list the web interface languages with their English fallback, and show the Trendshift ranking under Popularity (#5780 - @JakobLichterfeld)
  • docs: state that the image SBOM lists only the Debian packages and the Erlang and Elixir runtime, and why (#5787 - @JakobLichterfeld)
  • docs: remove the outdated entity relationship model from the development docs (#5801 - @JakobLichterfeld)

complete changelog

Don't miss a new teslamate release

NewReleases is sending notifications on new releases.