Add AppSync support for 24MM vehicles - #182
Open
efahrenholz wants to merge 3 commits into
Open
Conversation
|
This seems like a very important/useful PR. Why is it not yet merged and released? |
bhaggs
added a commit
to bhaggs/ha-toyota-na
that referenced
this pull request
Aug 11, 2026
Remote start is stateful: the vehicle reports whether it is running and for how much longer, and there is already a RemoteStartStatus feature carrying that. Two buttons threw it away. A switch reads the state back and exposes start time, end time, minutes remaining, and total runtime as attributes. Taken from widewing#182, which makes the general point that Home Assistant's Alexa and Google integrations expect stateful start/stop features to be switches and one-shot commands to be buttons. Only that idea is adopted here, not the PR's wider 24MM AppSync work, which this fork has no evidence of needing: remote commands over REST are confirmed working on a 2026 Solterra. Optimistic state is cleared on the next poll rather than retained. If a command silently failed the switch should say so rather than keep showing what was asked for - the same reasoning that led to dropping the Hazards Off button. The engine_start and engine_stop services are untouched, so automations built on them keep working. Their buttons are gone, and will show as orphaned entities until deleted from the entity registry. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bhaggs
added a commit
to bhaggs/ha-toyota-na
that referenced
this pull request
Aug 11, 2026
light-on returns HTTP 400, so the guess was wrong and the buttons are removed rather than left broken. The naming pattern they were extrapolated from is itself unreliable: PR widewing#182 shows the documented vocabulary is wrong about power-window-on/off, which are really power-window-open/close. Guessing one candidate per release is the wrong shape for this. The new toyota_na.send_command service sends an arbitrary command string to the vehicle, so candidates can be tried from Developer Tools in one sitting - headlight-on, lights-on, and so on - and a rejection comes back as a UI error naming the backend response. Useful well beyond this question, since the vocabulary is undocumented and the backend keeps changing. The LightsOn/LightsOff enum members and command map entries stay, so buttons can come back as a two-line change once the real strings are known. Hazards is renamed from "Hazards On" now that it stands alone. That changes its unique_id, so the old entity orphans alongside the two Lights buttons. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add a generation-aware AppSync path for 24MM vehicles (including 2025/2026 models) while leaving the existing REST behavior unchanged for 17CY, 17CYPLUS, and 21MM vehicles.
This addresses the two separate failure modes seen on newer vehicles:
v1/global/remote/command, which 24MM vehicles reject with errors such asONE-GLOBAL-RS-40009;Addresses #162, #164, and the newer lock-state representation related to #167.
Corrective action
1. Route 24MM remote commands through AppSync
For 24MM only, remote commands now use the current Toyota app sequence:
onPostRemoteCallback(vin:);start_ack;executeRemoteCommandGraphQL mutation;completedcallback (or surface its error/timeout).Older generations continue to use their existing REST routes.
One important clarification for #162: the current 24MM client still sends the wire command
engine-start. Toyota presents that action as climate conditioning for PHEVs, butclimate-startis not the command sent by the current client. The generation-specific AppSync transport and callback flow are the material API changes.2. Query current 24MM status directly
Add the current
GetVehicleStatusdocument and call it during the initial/polled 24MM update. The status subscription remains active for later pushes, but is no longer treated as the only source of opening/lock/electric state because subscriptions do not guarantee a replay of the current value.The status subscription document is also expanded to include the electric battery, range, connector, and charging fields.
3. Parse the current response vocabulary
Normalize both classic and current values:
close/closed,open/opened;lock/locked,unlock/unlocked.Unknown values are left unknown instead of being converted to open/unlocked. This prevents a 24MM
lock+closeresponse from appearing as an unlocked or unknown vehicle.The 24MM electric document now populates battery percentage, EV range (with and without A/C), remaining charge time, plug/connector status, charge type, and charging state. Battery percentage uses Toyota's current preference order:
stateOfChargeDisplay, thenplugInEnergy, thenchargeRemainingAmount.4. Recognize current capabilities during discovery
Connected Services detection now accepts the shapes used by newer vehicle-list responses:
remoteSubscriptionStatusorsubscriptionStatusis active/subscribed;remoteSubscriptionExistsis true;doorLockUnlockCapableorremoteEngineStartStopare true.EV/PHEV detection also accepts
fuelTypeEorI, and the actual vehicle generation and backdoor type are preserved for later requests. This allows Home Assistant to create the subscription- and electric-dependent entities for newer vehicles.5. Expose controllable features with native Home Assistant domains
The integration now maps Toyota remote commands to controllable entities instead of read-only sensors:
switch, usingengine-start/engine-stop;switch, usinghazard-on/hazard-off;coverwithdevice_class: window, usingpower-window-open/power-window-close;switchfor subscribed 24MM EV/PHEV vehicles, usingimmediate-charge/charge-stop;buttonentities, usingsound-hornandbuzzer-warning.The entity domains match Home Assistant's Alexa and Google integrations: open/close is represented as a cover, stateful start/stop features as switches, and stateless one-shot commands as buttons. Hazard state is optimistic because Toyota does not report its current state. Voice users should expose only the controls they intend to make available because non-lock entities may not receive lock-style PIN protection.
6. Parse current 24MM tire pressure data
The AppSync status query and subscription now include
frontLeft,frontRight,rearLeft,rearRight, andsparetire pressure data. The parser accepts scalar values and{value, unit}objects in psi, kPa, or bar, and exposes them as pressure sensors usingSensorDeviceClass.PRESSURE.Tire pressure remains a sensor rather than a controllable entity. Alexa and Google do not currently expose pressure sensors, so these entities are intended for Home Assistant dashboards, history, and automations.
Validation
python3 -m unittest discover -s tests -v(15 tests)python3 -m compileall -q custom_components/toyota_na testsgit diff --checkThe 15 tests cover the AppSync callback flow, 24MM status and tire-pressure parsing, capability normalization, remote start/stop, hazard and charging switch commands, window cover behavior, horn and buzzer buttons, error recovery, and generation gating.
The tests use a sanitized synthetic 24MM fixture and mocked AppSync socket/mutation flow; they do not contact a vehicle. Separately, the protocol and
lock/closeresponse shape were validated with a 2026 RAV4 XSE PHEV, including successful physical lock and unlock commands. The additional window, horn, buzzer, hazard, and charging commands use the command strings implemented by the Toyota client and remain subject to per-vehicle physical verification.