VW Group Connect v5.0.0
Home Assistant integration for Audi · VW · Škoda · SEAT · CUPRA · Porsche · VW US/CA.
What's new in this release / Was ist neu in diesem Release
- Volkswagen Companion (ADB): VW app 4.6.4 mapping, controls, more reads and safety gates. Developed against a Tiguan eHybrid (reads verified on the car) in gszigethy/vwgroup-connect-ha (fork releases 4.11.0-1 to 4.13.0-4, plus the fixes from this PR's review; PR numbers below refer to that repository). Thanks @gszigethy; app captures from @plainmad (Mk8 Golf GTE), @kgroshert (ID.4, e-up!) and @WEZANGO (CUPRA Born) (#968). Functional and technical design: docs/COMPANION.md.
Hinzugefügt / Added
- Your car can tell you when a trailer is hooked up. Two Audis reported the tow-hitch
module's own verdict on whether something is attached, and there was nowhere for it to go:
the integration had no trailer field at all, so this is a new reading rather than one that
was being dropped. Both cars happened to report "nothing attached", so the wording for the
opposite case is taken from the pair rather than seen on a car, and anything the module
says that is neither of the two leaves the sensor unknown instead of telling you the
trailer is off. People build automations on this one, and a confident wrong "no trailer"
is worse than no reading. The sensor appears only on cars that report the field. Thanks
@heldenbariton-ship-it and @marcus-stem (#1798, #1802). - Four new readings for the remaining life of each wheel's tyre pressure sensor. Five
Audi owners reported the same four diagnostic values on every poll, the largest group in
the backlog, and not one of them was ever read. The reason was the shape of the payload:
it arrives encoded, and the decoder expected a document inside it, while these four send
a plain number. They are decoded now, one per wheel. On four of the five cars the value
the car sends is the byte that means "not available", so those cars get no sensor at all
rather than four sensors reading 255, and the one car that sends a real value gets its
four. The portal documents neither a unit nor a meaning for them, so they are unitless
and off by default, exactly like the other tyre values whose unit the portal leaves open.
Thanks @zdimic1, @N85UK, @derschneewolf, @heldenbariton-ship-it and @marcus-stem (#1767). - A charge level and an electric range from a one time export now reach your car. The
15 minute feed and the one time export name the same readings differently, and the
integration only ever knew the feed's names: of the seventeen charge level names it looks
for, exactly one appears in the portal's own catalogue of export fields, and of the range
names, none at all. So a reporter whose Audi delivers its charge level only in the export
watched the import report success while his car still had no battery entity at all, because
the flag that decides whether a car gets electric entities is derived from exactly those
readings. The export's own spellings are now read, for the charge level and for the electric
range. It still only fills what the feed left empty, a value the car could not report is
still dropped rather than published, and the 12 V starter battery is deliberately kept out
of it, since it sits one letter from the traction pack in the same catalogue. Charging
sessions out of the file are not read as current state either: this car's export holds
eleven of them, and a session's charge level is not the car's charge level now. Thanks
@placidcasual98, who ran every test asked of him and whose negative results are what pinned
this down (#1403).
Reads from the VW app
The Companion channel drives the VW app on a spare Android phone over ADB and reads what the app shows. All reads are phone navigation only and never wake the car. Labels are matched against the installed app's own string table, so the reads work in any app language; the English and German patterns stay as the fallback.
- Overview, every poll:
- Battery level, separate from the charge limit.
- Electric range, and petrol range on plug-in hybrids, which also enables the combustion sensors.
- Charging state, read as a state ("Currently charging") (gszigethy#7).
- Lock and climate tiles (gszigethy#11).
- Last vehicle sync: when the car last sent the app data, from the app's "Synchronised … ago" line. It counts any reason the car sent data, only moves forward, and starts from the last known time after a restart or reload (gszigethy#79).
- App request status: Available or Restricted. A request-limit pause still running after a restart shows as Restricted straight away.
- Charge sheet:
- Charge limit, power, speed and remaining time. Spelled-out hours are counted ("One hour and 40 minutes" = 100 min) (gszigethy#39).
- Charging Mode sensor, from the range sheet's charging method (gszigethy#13). It becomes unavailable 24 h after its last read (gszigethy#90).
- Air Conditioning sheet:
- Whether climatisation is running, window heating, remaining time, target and outside temperature.
- Climate mode: whether the app's Start starts the air conditioning or the window heating, shown as the climate entity's preset (a sensor in Read-only Mode).
- Air Conditioning Settings:
- Climate at unlock, automatic window heating, air conditioning on battery.
- Climate zones front left and front right.
- Vehicle Health Report:
- Odometer, and service and oil-service due in days and in km. Miles are converted (gszigethy#8).
- Warnings: active, count and the categories that carry one (gszigethy#14).
- Vehicle Settings: Automatically release AC connector (gszigethy#9).
- Departure times (opt-in): each timer's time, on/off, weekdays and Repeat (gszigethy#15, gszigethy#42).
- Charging locations (opt-in): up to five locations from the app's Departure times screen (gszigethy#85).
- For each location: the name, whether the car is parked there, the number of active departure times, its three charging timers (on/off, time, days), and two AC settings (reduced charging current, automatically release connector).
- Sensors for the number of locations and the current location.
- Read-only; it never changes a setting.
- A location's two charge-level sliders can't be read: the app draws their values without any readable text.
- A Departure times screen that shows no locations, as the app does while the car's request limit is reached, leaves the last values in place.
- A location deleted in the car stays in the app, and in these entities, until the app is closed and restarted; a vehicle sync does not refresh the list (gszigethy#97).
- Driving data (opt-in): the last trip and the trip since charging or refuelling. Covers distance, consumption, average speed and driving time; miles are converted (gszigethy#16).
- Parking position (opt-in), read from the share preview.
Read switches
Each deeper read is a switch on the VW Group Connect Settings device: charge detail, Vehicle Health & Settings, climate detail, climate settings, parking position, departure times, charging locations and driving data (gszigethy#18, gszigethy#85).
- A change applies on the next poll, without a restart.
- Turning a read off drops the values it supplied.
- The switches are also available in Read-only Mode.
Controls
Every control is refused:
- in Read-only Mode;
- on an app version not verified for commands (currently 4.6.4);
- within 60 s of the previous command;
- while the car's request limit is paused.
Every control starts from the overview and checks the result on screen.
| Control | Behaviour | PRs |
|---|---|---|
| Start / Stop charging | Taps the charge sheet's Start or Stop. A greyed-out Start is never pressed. | gszigethy#49 |
| Charge limit | 50–100 % in 10 % steps. Moves the Settings slider and presses Save only when the screen shows exactly the requested value; otherwise cancels. | gszigethy#49 |
| Climate entity | On/off, target temperature 15.5–30 °C (LO–HI) and the presets Air conditioning and Window heating. While off, the preset and temperature are held in Home Assistant, survive a restart and send nothing. Turning on sets the app's mode picker and dial, reads both back, and presses Start only if they match; turning off is the app's single Stop. Window heating is one-shot, as in the app: after a run the preset returns to Air conditioning. The preset cannot change while climate runs. A dial changed in the app updates the entity. | gszigethy#40, gszigethy#64, gszigethy#103 |
| Temperature change on a running climate | While the air conditioning runs, a change moves the dial of the Air Conditioning sheet and reads it back; the app sends the new temperature to the car. One step is a tap on the next label, 1 °C is one slow drag. A change takes at most two moves (2 °C, two car requests); a larger change is refused before anything moves. With the climate off, or on window heating alone, a change is stored for the next Start. | gszigethy#73, gszigethy#76 |
| Climate Settings switches | Auxiliary air conditioning, automatic window heating, zone front left and front right. Taps Save and reads the page back; a value already in place sends nothing. | gszigethy#41 |
Departure timers (switch, time and set_departure_timer)
| On/off, time, days and Repeat. A timer is found by its content, not its row; two timers with the same time are refused. Saves only when the page shows exactly what was asked. | gszigethy#42, gszigethy#55 |
| Refresh vehicle data button | Taps vehicle Settings → Synchronise now, then re-reads the app after 3 minutes. A refused sync is reported at once. | gszigethy#25 |
| Refresh app screen data button | Re-reads the app's screens now; the car is not asked for new data. With Refresh vehicle data and Reset companion connection it sits in the device's Configuration section, as all three maintain the data rather than operate the car. Cloud entries keep Refresh Data. | gszigethy#101 |
| Vehicle sync interval | Runs Synchronise now on a timer. Off by default, minimum 60 min. The interval counts from the newest of the last sync attempt, the car's last data and the last command tap, so a car that sent data on its own (for example while driven) gets no extra tap. After a restart an overdue sync runs at once; a recent one is never repeated. Each sync wakes the car. | gszigethy#54, gszigethy#100 |
Charge limit, automatic window heating, climate at unlock and the climate zones sit in the device's Controls section; cloud entries keep the charge limit in Configuration (gszigethy#102).
Lock and unlock are deliberately not offered. They would need the S-PIN over ADB, the slider has no reliable target, and a wrong tap risks the opposite command or an S-PIN lockout (gszigethy#36).
VW app 4.6.4
VW app 4.6.4 is supported (gszigethy#28, gszigethy#37). Reads also accept newer app builds (gszigethy#31). Commands run only on builds verified for them (gszigethy#51).
Geändert / Changed
- The "volkswagen.de read channel needs re-login" notice now says which car it means. If you run more than one vehicle, two accounts produced two identical notices and nothing distinguished them, so you could not tell which password belonged to which. The notice carries the last six characters of the car's VIN now — the same short form the logs and the diagnostics download already use, never the full identifier. Thanks @kalwados (#1843).
- Some cars that the legacy MBB host turns away now get their service list from the EU-DP
host. When the legacy host answers401 gw.error.authentication, the operationList is now
requested once from the EU-DP host before the car is marked "no legacy". That list is used
only if it parses and contains services; an empty or error body records the verdict exactly
as before. Read-only: commands stay hidden for these cars and are refused before any S-PIN
step, because the S-PIN host has not been checked yet. Diagnostics show such cars under
mbb_eudp_oplist, and the debug log names the host each service points to (#1766). - Car request budget:
- The car's "Too many requests" and "Request limit reached" alerts are recognised in any app language.
- Either alert always pauses commands for 12 h, even when it appears late. The pause and the 60 s command gap survive a restart (gszigethy#50).
- The pause ends early once the car sends new data: when the overview's sync time is later than the alert, or the Driving data tile shows a new trip, controls and Synchronise now work again and App request status returns to Available. The alerts themselves say that starting the car makes everything available again (gszigethy#96).
- Screen reads continue during the pause; only commands wait.
- The battery level is read from the charge sheet during the pause, when the overview hides it.
- A sync never probes through a backend "too many requests" pause (gszigethy#54).
- Synchronise now is opt-in. It is off by default and never turned on by an upgrade. An interval you set yourself is kept (gszigethy#54).
- Read cadence:
- Detail-screen reads follow the poll slider (gszigethy#38).
- A command no longer triggers a re-read of every screen.
- The Air Conditioning sheet and its Settings are read on one walk (gszigethy#6).
- Driving data, the parking position, charging locations and Vehicle Health are read only when they can have changed (gszigethy#80, gszigethy#85): driving data and the parking position when a trip has ended or the car sent new data and the range dropped; Vehicle Health when the car sent new data (the Synchronised … ago time moved and then stood still for 10 minutes); charging locations on a trip change. All are also read on the first poll after a start, when their switch is turned on, every 12 hours, on Refresh data and after Force vehicle refresh. Vehicle Settings (the charge limit) is still read on every poll.
- Faster phone navigation:
- Fewer screen dumps per walk.
- One ADB shell call per dump.
- Shorter waits after a tap or BACK.
- Stale values: health, parking, driving, charging-location and Charging Mode values become unavailable after 24 h without a successful read (gszigethy#59, gszigethy#90).
- Startup: setup no longer waits for the first app-screen read; that read runs in the background (gszigethy#44).
- Reloads: a reload waits for a running walk to finish (gszigethy#60). Wake/sleep and close-app options apply without a reload (gszigethy#59).
- App prompts: the Google Maps consent is accepted only during the parking read (gszigethy#56). The app's rating prompt is closed with BACK, never answered (gszigethy#29).
- App string table: fetched only when the app version changes. Without it, commands and sync are refused unless the UI language can be confirmed (gszigethy#58).
- One entity per value (breaking only on a Volkswagen Companion entry with Read-only Mode off, the one place these removals happen):
- The read-only sensor and binary sensor that repeated a control's value are removed. This covers climate at unlock, window heating, the zones, climatisation, charging, charge target and the departure timers.
- The app's own target temperature and start mode readings are shown by the climate entity (gszigethy#65, gszigethy#103).
- Climate runs from the climate entity alone: use its on/off instead of a climate switch. No 4.x release created that switch on a Companion entry, so no 4.x upgrade loses one — setup only clears a leftover registry entry from the single much older release that did (gszigethy#103). Entities ARE removed by this group; the bullets above say which.
- Cloud-only diagnostics removed from companion entries: push event, API observer findings and wake count today (gszigethy#66).
- Data source label: shows the companion transport (
companion_adb) instead of "Volkswagen EU (WeConnect ID)" (gszigethy#67). - Companion entity ids carry "adb" (for example
sensor.tiguan_adb_battery_level, named "Tiguan Battery Level"), so companion and EU Data Act entities can be told apart. Existing entity ids are unchanged (gszigethy#68, gszigethy#81). - The vehicle sync warning is translated. The note that each sync wakes the car appears in every supported language.
- Relay errors are reported only as fixed codes, never as free text from the phone.
- Release documentation corrected (
RELEASE_PROCESS.mdand the CI prose):
the prescribed changelog heading format was one no parser accepts, the
coverage gate was quoted with stale values in three places, and eight links
pointed at a file that no longer exists.
Behoben / Fixed
-
The diagnostics now say when one of the extra read channels dropped out. If the
volkswagen.dechannel or the EU Data Act portal fails during a poll, the integration keeps
going on the others, which is right. Until now it kept going silently: the skip was written
only to a debug log, so a downloaded diagnostics file could not tell you whether a channel had
fallen over or had simply found nothing that round. Those two look identical from the outside
and have different causes, and the download now distinguishes them per channel.This matters beyond tidiness. When every extra channel drops out, the rule that stops an older
batch reading from outranking a live one has nothing to compare and does not run — so a value
can look stale for a reason that was, until now, invisible in the file. If you report an
unexpected reading, the answer should be in the diagnostics you attach rather than cost you a
round of "please switch on debug logging first".The per-channel lines describe the poll the file was taken on and nothing earlier: a channel you
switch off stops claiming an outcome instead of leaving its last one behind, on every kind of
entry. Worth saying because the entries alongside them do not work that way — those are written
when a read is attempted and stay put when it is not, so a reading there cannot be dated from the
file. One exception, so you are not misled by it: if you switch off the last of your extra read
channels, that final set of per-channel lines stays in the file until the integration restarts. -
The "sign in again" notice no longer sends an Audi owner to a door the manufacturer
locked. When a passwordless entry's session expires, the notice told everyone to choose
Reauthenticate and scan the sign-in code again. For Audi that cannot work: Volkswagen
switched off the app sign-in that brand used, so the code sign-in refuses to start and the
reauth lands on a banner saying so. @ratclma reported hitting exactly that, after following
this advice from us, which is how it was found.The sign-in prompt now reads the brand and the kind of sign-in the entry actually stored.
Where the code sign-in still works it hands off to it as before. Where the manufacturer
retired it, the prompt asks for your email address and password instead, and attaches them to
the existing entry, so its history, its settings, its entity names and any extra channels you
had set up all survive. The email field is deliberately left empty: these entries store an
internal account identifier rather than an address, and a pre-filled box would invite you to
type only a password, which is the one thing that cannot work.This is fixed in the sign-in prompt rather than in the repair notice on purpose. Home
Assistant opens that prompt by itself whenever the session has expired, so a notice pointing
elsewhere would have left the dead end reachable without you clicking anything.The first round of this stopped the integration guessing on its own. Such an entry no
longer attempts, unprompted and in the background, the email-and-password sign-in it has
no stored password for — which had been putting the
account's internal identifier in the email field once an hour for seven hours, and
reporting the refusal as a portal action the car in question could not even use. It now
says the session expired and gives up after two failed rounds instead of retrying hourly,
the same rule Porsche entries have had since 4.7.8.Two further defects in the same notice went with it: its title said "VW Group" instead of
naming the brand, and although it told you to go and do something, it offered no Repair button
at all. Both notices have one now
(#1813). -
A car whose service list comes from the read-only host keeps its remote commands blocked
even right after a restart. That block was already there and already correct, but it was
checked a moment too early: the integration looked at its own note of which cars are affected
before the step that writes that note, so on the first command after a restart the note was
still empty and the block did not catch. The entity for the command stays hidden either way,
so this only mattered to someone calling the service directly from an automation, and only
until the first data refresh of that session. It is checked again at the right moment now.
The reason it is worth a separate fix rather than a footnote: what gets lost when the block
misses is an attempt at your vehicle PIN, and the car locks the PIN after a few wrong ones.
Groundwork and the original block are @fschulte2812's (#1807). -
Your tyre pressures show their decimal again. The portal sends a value like 2.8 bar, and
every tyre-pressure sensor was showing 2. The number was being read as a whole number and the
fraction thrown away, on all four corners and the spare, in the actual, the target and the
deviation readings alike. They are measurements with one decimal and are read as such now.
Rounding would have been the same mistake wearing a different hat, since 2.8 bar is not 3 bar.
A car that reports whole units instead of bar is unaffected.
The half nobody could see from the outside was worse. The sensor that tells you whether your
car measures each tyre individually or only estimates it reads the same numbers, and the field
catalogue uses 1 to mean "no reading available". Throwing the fraction away turned every
pressure between 1 and 2 bar into exactly 1, so a car with one soft tyre was reported as not
measuring its tyres at all. That is the moment the reading matters most, and it now reads as
the measurement it is. Thanks @Kolbi, who quoted the raw value straight from the portal
response (#1819). -
Your car is no longer told it is a model it isn't. An Audi e-tron 55 from 2019 was
informed by the integration that it is "an MEB / ID-family car (ID.3/4/5/7, Enyaq, Born,
Q4)". It is not one, and its owner said so. The notice was built from the backend's
refusal and not from any check of the car: when the durable Car-Net login answers
"Unknown user", the integration concluded the car must be an ID. That answer only says
the car is not registered in the old Car-Net system, which is the expected case for ID
and MEB models and equally what an older car answers once the brand has moved it off
that system. The outcome was right, since the refusal is real and commands genuinely
cannot be sent, but the explanation sent people looking for an answer that does not
exist. The notice and the setup message now say what the refusal actually tells us.
German and English are corrected; the other languages still carry the old wording until
a native speaker gets to them. Thanks @jocke-w (#1809). -
An error report now says what the backend actually answered. A report reached the
tracker saying only that a request had failed with a 400, which is not something anyone
can act on: a 400 can mean an expired subscription, a passing backend problem, or a
mistake in what the integration sent, and only the answer's own text separates those. The
text was being read and then dropped, because the part of the code that writes the report
deliberately keeps it out of the message to avoid putting a VIN in a log. It is now
included in the report, masked the same way as everything else in it. A failure that
repeats is also no longer twenty copies of itself: the report keeps one entry with a count
of how often it happened, so the rest of the history survives and anyone reading it can
see how persistent the problem is. Thanks @moltke69 (#1808). -
Three cars stop reporting the same three fields on every poll. A VW and two CUPRA
sent a companion value that says whether a reading next to it can be trusted. It is not a
reading itself, so it was never going to become a sensor showing you the word "VALID",
but nothing used it either, which is why it kept being offered as something new. It is
used now for what it is: it decides whether the reading beside it counts, it is kept in
the diagnostics so nothing is hidden, and it no longer comes back on the next poll. Every
value seen so far says the reading is valid, so nothing changes on your car unless the
portal itself ever says otherwise. Thanks @tertius1, @StoneH74 and @Thunderhawk2001
(#1797, #1803, #1795). -
A value filled in from a one time export now says when the car captured it. The sensors
fed by the 15 minute feed carry the car's own capture time and whether that time belongs to
the reading or to the file it came in. The ones filled in by the import carried neither, so
there was no way to tell whether an imported door state was from this morning or from three
days ago. The cause was that the two pieces of bookkeeping are stored next to the readings
rather than on them, and the import skipped them on any car that already had a live feed.
Imported values now carry their own capture time where the export supplied one, and say
plainly that the age is the file's where it did not. A live reading keeps its own time and is
still never overwritten. Thanks @kmeinderink, who measured the missing attributes and then
said which half of the problem actually mattered to him, which is what made this small
instead of large. -
The one time export now identifies this project to the portal, like the rest of the
integration already did. The portal's operator asked that requests to their domain carry a
name, so they can attribute traffic and report a problem back to whoever causes it. We did
that, but only for the login and the dataset download: the one time export and the automatic
data request lived in their own module and still went out anonymously, including the two
requests that actually create a data request on the portal. That is not only a courtesy. On
9 October the portal answered logins with an error for hours purely on the strength of a
header, so unidentified requests were exposed to exactly that kind of gate. Every request
from that module now carries the name, and the headers it already sent are kept rather than
replaced. -
The clear message when the car's gateway refuses a command now actually appears. The last
release announced that a command refused on its final leg would explain itself instead of
surfacing a raw 403. It did not. The check looked for the gateway's own words in the error's
message, and that message is deliberately stripped of the response body so that logging or
re-raising it cannot leak your car's identifier. The words were therefore never in it, both
explanations were unreachable, and a reporter who tested the release still got the bare 403.
The same mistake sat on the locked-S-PIN detection in two other places, where it cost the one
message that tells you what to do about it. All three now read the response body, and the
decision lives in a single function that the tests call directly instead of re-implementing
it, because the old test did re-implement it and passed against code that could not run.
Thanks @panther7 for testing the release and reporting that commands still failed (#584). -
An electric car no longer loses its battery entities a quarter of an hour after they
appear. The snapshot the integration keeps carries a charge level and a range forward when
a poll does not report them, but it did not carry the flag that says the car HAS a battery,
and that flag is what decides whether the electric entities exist at all. So a car whose
charge level had been filled in from a one time export kept the number and lost the flag on
the very next feed snapshot, and the entities disappeared again with their own values sitting
right there. The flag is now worked out again from the readings that survived, through the
same single rule the rest of the integration uses, and only ever upward: a car that reports
fuel as well as charge stays a hybrid rather than being turned into an EV, and a car we know
nothing about stays unclassified instead of being called electric. A plug in hybrid also
stops losing the word hybrid on every poll that omits the flags. -
A charge level the car could not report is no longer published as a reading. When a car
cannot report its charge level it sends a placeholder number instead, and we put that
straight on the battery sensor: a car that said "no reading" showed up as 255 % charged. The
sensor feeds Home Assistant's long term statistics, so the nonsense was written into your
history as well. Anything outside 0 to 100 is now treated as no reading and left empty,
which is what the integration already did for one of the other charge level sources but
never for this one. 0 % and 100 % are of course still real readings, and a car that reported
nothing valid no longer looks like it has a battery at all. -
A petrol or diesel car no longer reads as an electric one. The one time export names its
own engine type and we were throwing that away, so a car whose own file said petrol had its
fuel range copied onto the electric range sensor and was marked as an EV. The engine type is
now read and the range lands on the combustion sensor where it belongs. The plug in hybrids
whose two ranges were swapped back in an earlier release are deliberately untouched by this,
and there are tests to keep them that way. -
A connected charging cable no longer says "not connected". The portal writes the plug
state as a long protocol word and the check only understood the short form, so a plugged in
car was told its cable was out, as a definite no rather than an honest unknown. The value a
car sends when it cannot report the plug at all was being turned into a "no" too, and now
stays unknown. Thanks @placidcasual98, whose own export is what showed this (#1403). -
The charge limit from a one time export is read again. The field name we were looking for
had a capital letter that the portal's own catalogue never uses, so no real export could
match it. -
The privacy note on an automatic report no longer reads as covering the file you attach
yourself. What the integration generates is masked, and that has not changed: the vehicle
identifier in a report is cut to its last six characters and a model name that turns out to be
an identifier is left out entirely. But that promise prints directly above the box you drag a
file into, and a data export downloaded from the portal is named with your full vehicle
identifier, so people have been attaching one without realising. Six of the open reports carry
one that way. The note now says plainly that your own attachments are not covered, and suggests
renaming the file first. -
A refused lock or unlock now explains itself, like a refused climate command already did.
The last release added a clear message for a command the car's gateway turns down on its final
step, and credited the reporter who worked it out. His own command was locking, and that path
never received the message: it had no handler on that step at all, so he would have seen the
same bare error a third time. Both paths now share one classification, so they cannot disagree
about what you are told, and the specific code his car returns is recognised as well, which
means we no longer have to ask anyone for a description the integration does not print. Thanks
@panther7 for testing the release and saying it still failed, and @Joassens, whose instrumented
logs are what made the messages possible in the first place (#584). -
The stale-data warning no longer tells you to re-request your data sharing. The portal's
operator has asked that nobody file further data requests while they work through a backlog,
because it does not speed anything up and can put you further back in the queue. Our warning
had been advising exactly that, in all twelve languages. It now points at re-adding the channel
instead, and in English it says plainly that empty or unchanged downloads are a hold-up on the
portal's side rather than yours. The other eleven languages have the bad advice removed; the
added explanation follows in a later pass rather than being machine-translated into an
instruction nobody here can check. -
Missing entities when the car is also in an EU Data Act entry.
- Battery, range, charging and lock entities from the companion were dropped as duplicates.
- Companion entities now have their own unique ids (
{vin}_companion_{key}). A one-time migration keeps the existing entity ids and history (gszigethy#47).
-
No stuck charging values after a reload. A screen read still running while the entry unloaded could create the charging power, charging speed, remaining time and vehicle status sensors on the unloading entry, where they kept their last value and blocked the reloaded entry's own sensors. A read that finishes during an unload now creates nothing (gszigethy#83).
-
Commands for a car in several entries go to the entry that can send them (gszigethy#48).
-
An idle car no longer reads as climate on. The running state now comes from the Start/Stop button.
-
The walk back recognises the 4.3.2 overview and no longer presses BACK out of the app.
-
A broken ADB connection ("Broken pipe") is reopened on the next read (gszigethy#27).
-
Climate:
- The dial is walked only when its labels show °C; a reading outside 15.5–30 °C is never tapped (gszigethy#61).
- An unrecognised mode refuses Start.
- Error messages no longer quote screen text (gszigethy#52).
-
An interrupted walk discards any setting it left unsaved instead of sending it with the next command (gszigethy#53).
-
Departure timers that were not read show unknown, not off (gszigethy#10).
-
Vehicle Settings is read even when the charge target is already known (gszigethy#9).
-
A stale battery level on a car whose volkswagen.de channel was plainly being read.
The poll opens with a relations lookup that resolves which platform the car is on, and a
refusal there used to abandon the rest of the poll — so the charging read never ran, the
volkswagen.de snapshot carried no battery level at all, and the merge kept the only value it
had: the portal feed's last capture, days old next to a channel that looked live. Nothing in
the merge was wrong. The refusal is now recorded and the remaining reads still run, exactly
as a refusal on one read already stopped costing the others. On a car that is not MEB the
platform stays unresolved after such a refusal and those reads are expected to come back
empty, which the diagnostics name. Thanks @Fishermanjb (#1827). -
A session that had really expired stopped being noticed. At the end of the same poll the
integration decides whether a refused read means "this one car is walled" or "the session is
dead", and it decided by asking whether a model name or colour had been filled in. Those are
kept for a day once read, so from the first successful poll onward the answer was always yes:
the "session is dead" branch could not be reached again for as long as Home Assistant stayed
running, and reconnecting was left to the ten-minute background refresh on its own. The
question is now whether a read actually reached Volkswagen during that poll. The model,
colour and renders do not flicker as a result — they are held a layer further up, which is
what that was always for. Found while looking into #1827.
Fixes in shared code (all channels)
- Read-only Mode stops commands from controls that were already loaded. The option applies without a reload, so a control created while the entry was writable could still send a command. The command dispatch now refuses it.
- A command for a car that sits in several entries goes to the first entry that can send it, instead of failing on a read-only one listed first (gszigethy#48).
- No entities are created on an entry that is unloading, and a poll that finishes during shutdown no longer notifies listeners (gszigethy#83). Cores without
ConfigEntryState.UNLOAD_IN_PROGRESSare unaffected. - Charging switch during conservation charging. The switch showed off while the car was conservation charging; it now shows on.
- Charging session with an unknown plug state. A session is no longer cancelled when the channel cannot see the plug.
- Climate
set_hvac_mode/set_temperature. A mode the entity does not list raises a validation error instead of being treated as off (gszigethy#52). set_departure_timer.enabledis optional. The companion can change only the time or the days; the cloud channels return a clear error ifenabledis left out (gszigethy#55).
Sicherheit / Security
- Diagnostics redaction hardening. The diagnostics download masks more of what it carries
before you attach it to an issue, in both the per-vehicle and the raw-payload section.
Nothing about the integration's behaviour changes and no sensor is affected. Two of the
newly masked entries are containers rather than single values, so a raw capture now shows a
note about their kind in place of their inner shape — worth knowing if you use that section
to help map a new field. Thanks @Fishermanjb, whose report of a neighbouring problem is what
led here. - Tokens:
- New ADB Bridge add-on setups require a token.
- The relay token form suggests a random token, and a custom token needs at least 32 characters with enough variety.
- Existing entries keep their tokens.
- Diagnostics: the add-on token, the agent token and the phone's host address are redacted.
- Screen dumps: a dump that contains an XML DOCTYPE or ENTITY declaration is refused before it is parsed (gszigethy#57).
- Vehicle identification numbers: CI refuses a VIN-shaped literal in the repository that carries no visible mark of being made up.
- For VW and Audi, the name you give your car in the brand's app is kept out of the model field. It is shown as the vehicle nickname instead, which a diagnostics download redacts. The Škoda official-API channel still puts that name in the model field; that is a separate change, because the same field carries the real model for every owner who never renamed their car. Entity IDs that already exist are not renamed. On a NEW setup the device is named after the model — and where the brand's garage entry carries only your name and no model, the device falls back to the brand plus the last six characters of the VIN, so a new entry can read "Volkswagen 1234AB" where it would previously have read your own wording.
- Vehicle Data Scout: the masking that prepares a sample value for a public
issue now covers another of the encodings the portal uses, so an encoded field
is replaced by a note about its kind and size rather than shortened. Reported
as a new field by @autosklo (#1830); nothing was exposed in that report.
Full diff vs v4.13.0 / Kompletter Diff zu v4.13.0
Every commit, file and code change between the two versions:
Jeder Commit, jede Datei und jede Code-Änderung zwischen beiden Versionen:
Recent releases / Letzte Releases
If you're upgrading from an older version, also read these notes:
Wenn du von einer älteren Version updatest, lies auch diese Release-Notes:
Full history: CHANGELOG.md
Installation / Update
HACS users: the update notification appears automatically within ~6 hours of the release.
HACS-User: Der Update-Hinweis erscheint automatisch innerhalb von ~6 Stunden nach dem Release.
Manual install / Manuelle Installation:
- Download
vag_connect.zipfrom this release /vag_connect.zipaus diesem Release herunterladen - Unzip and copy
custom_components/vag_connect/to your HAconfig/custom_components/folder, replacing any older copy / Entpacken und den Ordnercustom_components/vag_connect/in dein HAconfig/custom_components/kopieren — alten Ordner ersetzen - Restart Home Assistant / Home Assistant neu starten
Supported brands / Unterstützte Marken
Volkswagen EU · Audi · Škoda · SEAT · CUPRA · Volkswagen US/CA (Beta) · Porsche (Beta)
Found a bug? / Bug gefunden?
Open an issue with the bug-report template: https://github.com/its-me-prash/vwgroup-connect-ha/issues/new/choose
Bug-Report-Template: https://github.com/its-me-prash/vwgroup-connect-ha/issues/new/choose
Please mask your VIN to the last 6 characters and remove email/tokens/GPS before posting.
Bitte VIN auf die letzten 6 Zeichen kürzen und Email/Tokens/GPS vor dem Posten entfernen.