mikenemat / gm-onstar-probe

A reverse-engineered python library for remote starting GM/Onstar vehicles, and maybe more some day
34 stars 8 forks source link

Other API Functions #4

Open mcnutter1 opened 5 years ago

mcnutter1 commented 5 years ago

has anyone mapped the other API functions? Lock/Unlock, Vehicle Status, Location?

plucpel commented 5 years ago

I tried unlock but it did not work. I may just not have found the right syntax but could not get it to work. Location I think requires a specific 'plan' from OnStar that is not the basic once included with the car

DanH42 commented 5 years ago

If you GET /api/v1/account/vehicles/YOURVIN/commands, you'll get back a response that partially describes the available commands (converted to YAML to slightly increase readability):

- name: cancelAlert
  description: Cancel a vehicle alert (honk horns/flash lights).
  url: https://api.gm.com/api/v1/account/vehicles/YOURVIN/commands/cancelAlert
  isPrivSessionRequired: true
- name: getHotspotInfo
  description: Retrives the WiFi Hotspot info
  url: https://api.gm.com/api/v1/account/vehicles/YOURVIN/hotspot/commands/getInfo
  isPrivSessionRequired: false
- name: lockDoor
  description: Locks the doors.
  url: https://api.gm.com/api/v1/account/vehicles/YOURVIN/commands/lockDoor
  isPrivSessionRequired: true
- name: unlockDoor
  description: Unlocks the doors.
  url: https://api.gm.com/api/v1/account/vehicles/YOURVIN/commands/unlockDoor
  isPrivSessionRequired: true
- name: alert
  description: Triggers a vehicle alert (honk horns/flash lights).
  url: https://api.gm.com/api/v1/account/vehicles/YOURVIN/commands/alert
  isPrivSessionRequired: true
- name: start
  description: Remotely starts the vehicle.
  url: https://api.gm.com/api/v1/account/vehicles/YOURVIN/commands/start
  isPrivSessionRequired: true
- name: cancelStart
  description: Cancels previous remote start command.
  url: https://api.gm.com/api/v1/account/vehicles/YOURVIN/commands/cancelStart
  isPrivSessionRequired: true
- name: diagnostics
  description: Retrieves diagnostic vehicle data.
  url: https://api.gm.com/api/v1/account/vehicles/YOURVIN/commands/diagnostics
  isPrivSessionRequired: false
  commandData:
    supportedDiagnostics:
      supportedDiagnostic:
      - ENGINE COOLANT TEMP
      - ENGINE RPM
      - LAST TRIP FUEL ECONOMY
      - TIRE PRESSURE
      - AMBIENT AIR TEMPERATURE
      - LAST TRIP DISTANCE
      - INTERM VOLT BATT VOLT
      - OIL LIFE
      - LIFETIME FUEL ECON
      - FUEL TANK INFO
      - HOTSPOT CONFIG
      - LIFETIME FUEL USED
      - ODOMETER
      - VEHICLE RANGE
      - HOTSPOT STATUS
- name: sendTBTRoute
  description: Calculates route and initiate download of turn by turn directions to
    the vehicle.
  url: https://api.gm.com/api/v1/account/vehicles/YOURVIN/commands/sendTBTRoute
  isPrivSessionRequired: false
- name: location
  description: Retrieves the vehicle's current location.
  url: https://api.gm.com/api/v1/account/vehicles/YOURVIN/commands/location
  isPrivSessionRequired: true
- name: sendNavDestination
  description: Calculate route and send it to the vehicle's nav unit.
  url: https://api.gm.com/api/v1/account/vehicles/YOURVIN/navUnit/commands/sendNavDestination
  isPrivSessionRequired: false
- name: connect
  description: Initiates a connection to the vehicle
  url: https://api.gm.com/api/v1/account/vehicles/YOURVIN/commands/connect
  isPrivSessionRequired: false
- name: getHotspotStatus
  description: Retrive WiFi status
  url: https://api.gm.com/api/v1/account/vehicles/YOURVIN/hotspot/commands/getStatus
  isPrivSessionRequired: false
- name: setHotspotInfo
  description: update the WiFi SSID and passPhrase
  url: https://api.gm.com/api/v1/account/vehicles/YOURVIN/hotspot/commands/setInfo
  isPrivSessionRequired: true
- name: disableHotspot
  description: Disable WiFi Hotspot
  url: https://api.gm.com/api/v1/account/vehicles/YOURVIN/hotspot/commands/disable
  isPrivSessionRequired: true
- name: enableHotspot
  description: Enable WiFi Hotspot
  url: https://api.gm.com/api/v1/account/vehicles/YOURVIN/hotspot/commands/enable
  isPrivSessionRequired: true

This reveals that controlling the doors uses the commands lockDoor and unlockDoor, rather than the arguably more intuitive lock and unlock that I also assumed would be the commands. isPrivSessionRequired indicates whether or not you're expected to call /oauth/token/upgrade.

However, you'll notice that while unlocking works with just {} as the request body, requests to lock the doors will be rejected with {"error":{"code":"ONS-105","description":"Invalid Input."}}. This took me a while to figure out, but after decompiling the Android app in a (failed) attempt to locate the API keys without needing to recompile the app, I found the classes involved with making these requests, and noticed that the lockDoor command expects a delay parameter, wrapped with lockDoorRequest. I'm not sure when you'd ever want to send a request to lock the doors at any time other than "right now", so you can probably just stick with a hardcoded {"lockDoorRequest":{"delay":0}}.

There's also some additional interesting endpoints that aren't under /commands, and I noticed someone else has already uploaded the decompiled RemoteAPIService interface to a public Gist. That class lists all the endpoints that are available to you along with which HTTP method to use, but doesn't include what POST data they expect. I haven't dug into them all, but you can do so yourself if needed by running the myChevrolet APK through dex2jar and the passing the result to a tool like jd-gui. I'm new to both of those utilities, so you're probably better off reading their documentation yourself rather than me trying to explain them and probably getting things wrong.

I was also particularly interested in pulling diagnostic information, which is also a bit complicated. This endpoint also expects instructions in the request body, and you actually need to list each data point you want to receive. The list is included in the /commands response above, but you may want to make that request yourself in case your vehicle responds with a different list of supported diagnostic items. Also the format shown in the response isn't the same as what expects you to send it -- digging into the decompiled Android source once again, I came up with this:

{
  "diagnosticsRequest": {
    "diagnosticItem": [
      "ENGINE COOLANT TEMP",
      "ENGINE RPM",
      "LAST TRIP FUEL ECONOMY",
      "TIRE PRESSURE",
      "AMBIENT AIR TEMPERATURE",
      "LAST TRIP DISTANCE",
      "INTERM VOLT BATT VOLT",
      "OIL LIFE",
      "LIFETIME FUEL ECON",
      "FUEL TANK INFO",
      "LIFETIME FUEL USED",
      "ODOMETER",
      "VEHICLE RANGE"
    ]
  }
}

You can change the items in the list as you see fit; the example above requests everything except WiFi hotspot information, which I know I don't care about tracking.

Once you've connected to the vehicle and then sent that request, you should get a 202 Accepted response code, and a JSON object that includes a commandResponse object with a url property. You'll want to GET that URL (passing the same Authorization header you've been using with every other request) and check for "status": "success" in the response object that it returns. You can poll every couple seconds until that's the case, at which point it will also include a body with all the diagnostic information data you requested.

Do note that there is a limit to how many consecutive remote requests you're allowed to make. This count does NOT appear to reset with time, and you must instead get into your vehicle and start it yourself. As soon as you do this, your API requests will start working again. When polling at a 30-minute interval, I've been seeing requests start to fail after about 16 requests with {"error":{"code":"ONS-216","description":"Unable to establish packet session to the vehicle"}}. I've switched to only polling once an hour, but that was less than 16 hours ago, so we'll see if I get cut off after the same number of requests.

I've just gotten started with this a couple days ago, so I'm by no means an expert, but hopefully the time I spent banging my head against the wall can save a couple other folks from having to go through the same thing.

samrum commented 5 years ago

I've mapped out a bunch of the API requests and bundled them into a NodeJS library: OnStarJS. Also have a homebridge plugin that uses it for Siri support: homebridge-onstar.

All of this was thanks to this repo <3

kallisti5 commented 4 years ago

SNEEZE

        "commands": {
            "command": [
                {
                    "description": "Enrolls a vehicle in telemetry.",
                    "name": "telemetryOptIn",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/commands/telemetryOptIn"
                },
                {
                    "description": "Unenrolls a vehicle from telemetry..",
                    "name": "telemetryOptOut",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/commands/telemetryOptOut"
                },
                {
                    "description": "Locks the doors.",
                    "name": "lockDoor",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/commands/lockDoor"
                },
                {
                    "description": "Unlocks the doors.",
                    "name": "unlockDoor",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/commands/unlockDoor"
                },
                {
                    "description": "Triggers a vehicle alert (honk horns/flash lights).",
                    "name": "alert",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/commands/alert"
                },
                {
                    "description": "Cancels vehicle alert (honk horns/flash lights) in progress.",
                    "name": "cancelAlert",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/commands/cancelAlert"
                },
                {
                    "description": "Remotely starts the vehicle.",
                    "name": "start",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/commands/start"
                },
                {
                    "description": "Cancels previous remote start command.",
                    "name": "cancelStart",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/commands/cancelStart"
                },
                {
                    "commandData": {
                        "supportedDiagnostics": {
                            "supportedDiagnostic": [
                                "LIFETIME FUEL USED",
                                "LIFETIME FUEL ECON",
                                "LAST TRIP DISTANCE",
                                "ODOMETER",
                                "LAST TRIP FUEL ECONOMY",
                                "TIRE PRESSURE",
                                "OIL LIFE",
                                "FUEL TANK INFO",
                                "VEHICLE RANGE",
                                "EV BATTERY LEVEL",
                                "GET CHARGE MODE",
                                "LIFETIME EV ODOMETER",
                                "GET COMMUTE SCHEDULE"
                            ]
                        }
                    },
                    "description": "Retrieves diagnostic vehicle data.",
                    "name": "diagnostics",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/commands/diagnostics"
                },
                {
                    "description": "Calculates route and initiate download of turn by turn directions to the vehicle.",
                    "name": "sendTBTRoute",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/commands/sendTBTRoute"
                },
                {
                    "description": "Retrieves the vehicle's current location.",
                    "name": "location",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/commands/location"
                },
                {
                    "description": "Calculate route and send it to the vehicle's nav unit.",
                    "name": "sendNavDestination",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/commands/sendNavDestination"
                },
                {
                    "description": "get charging profile.",
                    "name": "getChargingProfile",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/commands/getChargingProfile"
                },
                {
                    "description": "set charging profile.",
                    "name": "setChargingProfile",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/commands/setChargingProfile"
                },
                {
                    "description": "charge Override",
                    "name": "chargeOverride",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/commands/chargeOverride"
                },
                {
                    "description": "get commute schedule",
                    "name": "getCommuteSchedule",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/commands/getCommuteSchedule"
                },
                {
                    "description": "set commute schedule",
                    "name": "setCommuteSchedule",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/commands/setCommuteSchedule"
                },
                {
                    "description": "Disables the hotspot on your vehicle",
                    "name": "disableHotspot",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/hotspot/commands/disable"
                },
                {
                    "description": "Enables the hotspot on your vehicle",
                    "name": "enableHotspot",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/hotspot/commands/enable"
                },
                {
                    "description": "Fetches hotspot information on your vehicle",
                    "name": "getHotspotInfo",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/hotspot/commands/getHotspotInfo"
                },
                {
                    "description": "Fetches hotspot status information on your vehicle",
                    "name": "getHotspotStatus",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/hotspot/commands/getHotspotStatus"
                },
                {
                    "description": "Set hotspot information on your vehicle",
                    "name": "setHotspotInfo",
                    "url": "https://api.gm.com/api/v1/account/vehicles/VIN/hotspot/commands/setHotspotInfo"
                }
            ]
        },