A work-in-progress fork of the Toyota EU community integration that fixes the smart status-refresh strategy on vehicles whose gateway returns persistent HTTP 500 on POST /v1/global/remote/refresh-status. Targets ha_toyota#293 (the gateway-rejects-the-wake-POST bucket of #291).
What changes vs stock ha_toyota 2.3.0:
- The wake POST is wrapped in try/except. A 5xx exception now correctly advances the auto-disable counter and lets the rest of the cycle's bookkeeping run (instead of propagating past it and freezing entities at last-good).
- A bare GET fallback fires when the POST fails, so
/statusentities still refresh this cycle even before auto-disable kicks in. - The "Refresh vehicle status" service / button now bypasses both auto-disable AND user-disable. If the gateway recovers (or you want a fully manual schedule), pressing the button forces a POST through.
- A successful POST automatically clears
auto_disabled_status_refresh, so recovery from auto-disable is a single button press instead of the options-flow toggle dance.
Once ha_toyota#293 is merged and a release is cut, none of this will be needed - HACS will pull the fix normally.
You will run terminal commands inside your Home Assistant container. If that sentence is unfamiliar, the rest of this document might be too. Set aside 10 minutes, follow each step exactly, and don't worry if something breaks - there's a rollback section at the bottom.
This guide does not modify pytoyoda. Stock pytoyoda 5.1.0 (which ha_toyota 2.3.0 already pins) is what stays installed.
| Install type | How to recognise it | What you'll do |
|---|---|---|
| Home Assistant OS (HAOS) | Settings -> System -> About shows "Operating system: Home Assistant OS X.Y" | SSH into the host, then docker exec into the container |
| HA Container / Supervised | You run HA via docker compose or docker run directly |
docker exec straight from your Docker host |
| HA Core in a venv | You manage the Python venv yourself | Skip the docker exec parts, edit /config/custom_components/toyota/ directly |
For HAOS, install the Advanced SSH & Web Terminal add-on by frenck, set Protection Mode: off, restart the add-on, and SSH in. The official "Terminal & SSH" core add-on has no docker command and won't work.
You're in the right shell when docker --version returns a version number.
docker exec -u 0 -it homeassistant bashYou should now see a # prompt.
# 2a. Move the stock integration OUT of custom_components/ entirely.
# Putting backups inside custom_components/ confuses HA's loader and
# can crash setup with "No module named 'custom_components.toyota.bak'".
cd /config/custom_components
rm -rf /config/_toyota_stock_backup
[ -d toyota ] && mv toyota /config/_toyota_stock_backup
# 2b. Clone the fork branch and move it into place.
git clone -b fix/wake-post-500-auto-disable --depth 1 \
https://github.com/nledenyi/ha_toyota.git /tmp/ha_toyota_fork
mv /tmp/ha_toyota_fork/custom_components/toyota toyota
rm -rf /tmp/ha_toyota_forkAfter this, /config/custom_components/toyota/ contains the fork code and /config/_toyota_stock_backup/ contains the stock backup outside the integrations folder.
Quick check that the fork code is in place:
grep -c "status_after_post_fail" /config/custom_components/toyota/__init__.pyExpected: 1. If 0, the swap didn't take - the toyota directory is still stock 2.3.0; re-run Step 2.
Exit the container shell:
exitThen restart HA Core. From your host shell:
ha core restartWait 1-3 minutes for HA to come back up.
The behaviour change is visible in two places:
If your gateway 500s persistently, the fork will:
- Cycle 1 (within first 6 minutes): POST fails ->
consecutive_post_rejections = 1, bare GET fallback runs. - Cycle 2 (~12 minutes after restart): POST fails again -> counter hits threshold ->
auto_disabled_status_refresh = Trueis persisted, integration reloads, strategy goes toHARD_DISABLED_AUTO.
In Home Assistant, find sensor.<alias>_status_refresh_state (under your vehicle's diagnostic entities). After ~12 minutes it should report hard_disabled_auto. On stock 2.3.0 this sensor stayed active forever even with the same persistent 500s - that's the exact bug this PR fixes.
On stock 2.3.0, when the wake POST 500'd, /status-derived entities (parking location, lock state, door states) froze at last-good. With the fork, the bare GET fallback runs on Layer 1 failure, so those entities refresh on every coordinator cycle as long as Toyota's gateway serves stale-cache data.
Check device_tracker.<alias>_parking_location and binary_sensor.<alias>_*_lock for state changes after ~12 minutes (or after a real-world event - e.g. someone takes the car for a drive, parks elsewhere; the location entity should pick that up after the next coordinator cycle once the legacy GET fires).
After the integration auto-disables, find the Refresh vehicle status button entity for your car and press it. Expected behaviour:
- The fork bypasses
HARD_DISABLED_AUTOfor service-call invocations. - A POST is attempted.
- If the POST succeeds (
return_code == "000000"), the fork auto-clearsauto_disabled_status_refreshand the strategy returns toACTIVEon the next cycle. - If the POST fails again (your gateway is still 500ing), the counter increments and re-trips auto-disable on the next failure.
In Settings -> System -> Logs, filter for toyota. After a successful service-call POST you should see:
INFO ... Toyota auto-disable cleared for vin=...XXXXXX after successful POST
That message is the recovery signal.
On stock 2.3.0 you saw an endless retry loop in the logs every cycle:
WARNING ... pytoyoda.controller:request_raw - Toyota API 500 on /v1/global/remote/refresh-status; retrying in 2s (attempt 2 of 4)
WARNING ... pytoyoda.controller:request_raw - Toyota API 500 on /v1/global/remote/refresh-status; retrying in 4s (attempt 3 of 4)
WARNING ... pytoyoda.controller:request_raw - Toyota API 500 on /v1/global/remote/refresh-status; retrying in 8s (attempt 4 of 4)
repeating forever. With the fork, you should see this pattern at most twice (cycles 1 and 2) before auto-disable kicks in and silences it.
If anything goes wrong, revert ha_toyota to stock 2.3.0:
docker exec -u 0 -it homeassistant bash
rm -rf /config/custom_components/toyota
mv /config/_toyota_stock_backup /config/custom_components/toyota
exit
ha core restartAfter the restart, your integration is back on stock 2.3.0 and your manual workaround (disabling "Refresh vehicle status remotely permanently" in the integration's options) continues to work.
If you can post the following on issue #293, that's the most useful:
- Did the integration set up successfully after the swap?
- After ~12 minutes, did
sensor.<alias>_status_refresh_stateflip fromactivetohard_disabled_auto? - After auto-disable, are your
/status-derived entities (parking location, lock state) updating again? (They should be served by the legacy bare GET path now.) - Bonus: try the refresh button while in
hard_disabled_auto. Does it (a) attempt a POST, and (b) flip the state back toactiveif the POST succeeds?
Thanks for testing!