molobrakos / volvooncall

Retrieve information from the Volvo On Call (VOC) web service
The Unlicense
151 stars 47 forks source link

VOC api not working for android auto vehicles #84

Open acoutts opened 2 years ago

acoutts commented 2 years ago

Located in the US. The official volvo on call app works for my vehicle. But all calls to the voc api used by this project simply fail with a 500 error:

{
    "errorLabel": "InvalidInputCriteria",
    "errorDescription": "The input parameters are invalid"
}

I used charles to take a look at how the official volvo app works. I can see it making requests to these URLs:

https://gw.consumer.api.volvocars.com/voc/disturbances/products/VolvoOnCall?region=NorthAmerica
https://cepmob.eu.prod.c3.volvocars.com
https://gw.consumer.api.volvocars.com/cbvs/subscriptions/

It appears their app is using the new api but when I follow the docs and query my account i just get an empty list for my vehicles, but querying their demo data shows a valid vin / vehicle to query.

Is there no working API for north america anymore?

nikagersonlohman commented 2 years ago

What vehicle are you querying? Vehicles with AAOS (Android Automotive OS) like the XC40 P8 and P6 are not supported yet

acoutts commented 2 years ago

2022 XC60 Recharge, also uses android automotive.

nikagersonlohman commented 2 years ago

Quote from their website: "This API works for all connected cars up to model year 2021, excluding the XC40 Recharge BEV.": https://developer.volvocars.com/volvo-api/connected-vehicle/

acoutts commented 2 years ago

Renamed accordingly, maybe we can track it here as they add support. The official app works so there's some kind of api, they just have not opened it yet.

nikagersonlohman commented 2 years ago

I have not yet found a way to query the car,.. looking forward to someone that does. Currently I cannot find a way to trace the app either, to register a car it requires Bluetooth which is not supported in Bluestacks and such

nikagersonlohman commented 2 years ago

I have a regular XC40 too and when switching from one to the other the app restarts and changes into the same look as yours without the vehicle buttons in the bottom... I'll make some screenshots to demonstrate

acoutts commented 2 years ago

At a minimum they are using an undocumented oauth method secured by the volvo account. I was able to see they make a request to an oauth endpoint using the volvo account to authorize it, then get a token to use for future requests but the requests aren't showing up in charles. I suspect they are using grpc so it's just tcp traffic not showing up in charles.

nikagersonlohman commented 2 years ago

exactly, tried it with charles proxy too and couldn't capture enough detail to reverse engineer what they do :(

acoutts commented 2 years ago

One thing i did take note on is unlike the public api docs they are not including a vcc-api key in the request.

acoutts commented 2 years ago

They also do not allow the app to be installed on apple silicon (this is a specific setting you disable in appstore connect) so they are intentionally hiding it like that.

nikagersonlohman commented 2 years ago

Here are some screenshots and a recording when switching from one car to the other to demonstrate complexity: https://photos.app.goo.gl/8RjdpKP8Zps6v5h26

bartwo commented 1 year ago

any update on this?

nikagersonlohman commented 1 year ago

Thanks for triggering this. I have checked Volvo's website and the Connect and Extended Vehicle APIs still do not support XC40 P8 / full electric. But... they introduced a new "Energy API": https://developer.volvocars.com/apis/energy/overview/

brownstone666 commented 1 year ago

Thanks for triggering this. I have checked Volvo's website and the Connect and Extended Vehicle APIs still do not support XC40 P8 / full electric. But... they introduced a new "Energy API": https://developer.volvocars.com/apis/energy/overview/

I try to use this new API, but i'm getting 404 when make https://api.volvocars.com/energy/v1/vehicles/{{VIN}}/recharge-status @nikagersonlohman Did you any success?

nikagersonlohman commented 1 year ago

I had the same issue πŸ™ˆstopped when it became too difficult... might try again soon...

andynash commented 1 year ago

I think you guys might be interested in my post here on the Home Assistant integration issue covering this.

I've set up a complete Postman implementation of the 3 APIs (Connected Vehicle, Energy and Extended Vehicle) that you can test, and have also made some hopeful progress on obtaining oAuth credentials from Volvo to get this API working outside their sandbox 🀞

All three APIs work just fine with a MY23 XC90 Recharge (AAOS), including commands. I'd be interested to hear how you do with your vehicles.

nikagersonlohman commented 1 year ago

Great job @andynash ! Thanks for this. Looks like the Energy API doesn't work yet on the XC40 P8, but while configuring the APIs I noticed that the Extended and Connected Verhicle APIs now work! This is good news, I can finally pre-heat my car when my Home Automation (OpenHAB) says the temperature is below a certain temp... πŸ‘πŸ‘

andynash commented 1 year ago

@nikagersonlohman Great stuff, shame about the Energy API though πŸ˜”

I take it you will also need to wait for Volvo to let us publish apps before you can use the Connected/Extended APIs? Or do you have another way to access them, eg scraping?

nikagersonlohman commented 1 year ago

I have only been able to use the hourly tokens, so I will soon create a script to use selenium to click on the right tags (assume that's what you meant with scraping?)

andynash commented 1 year ago

Ah yes, have now seen your comment on the HA issue, yes that's what I meant - Selenium is a good call if Volvo don't come through with the key/secret πŸ‘

nikagersonlohman commented 1 year ago

Wel... I have published a quick-and-dirty release of getting the authorization with Selenium... Be aware, this will still have many bugs...

https://github.com/nikagl/volvo

nikagersonlohman commented 1 year ago

image

nikagersonlohman commented 1 year ago

Good to know, the following code works to authenticate and query the (in this case extended-vehicle) Volvo APIs for Electric Cars as well:

import requests
import json

print ("Connecting...")

username = 'VOLVO ID Username'
password = 'VOLVO ID Password'
vccapikey = 'DEVELOPER VCC API KEY'

try:
    response = requests.post(
        "https://volvoid.eu.volvocars.com/as/token.oauth2",
        headers = {
            'authorization': 'Basic aDRZZjBiOlU4WWtTYlZsNnh3c2c1WVFxWmZyZ1ZtSWFEcGhPc3kxUENhVXNpY1F0bzNUUjVrd2FKc2U0QVpkZ2ZJZmNMeXc=',
            'content-type': 'application/x-www-form-urlencoded',
            'user-agent': 'okhttp/4.10.0'
        },
        data = {  
            'username': username,
            'password': password,
            'access_token_manager_id': 'JWTh4Yf0b',
            'grant_type': 'password',
            'scope': 'openid email profile care_by_volvo:financial_information:invoice:read care_by_volvo:financial_information:payment_method care_by_volvo:subscription:read customer:attributes customer:attributes:write order:attributes vehicle:attributes tsp_customer_api:all conve:brake_status conve:climatization_start_stop conve:command_accessibility conve:commands conve:diagnostics_engine_status conve:diagnostics_workshop conve:doors_status conve:engine_status conve:environment conve:fuel_status conve:honk_flash conve:lock conve:lock_status conve:navigation conve:odometer_status conve:trip_statistics conve:tyre_status conve:unlock conve:vehicle_relation conve:warnings conve:windows_status energy:battery_charge_level energy:charging_connection_status energy:charging_system_status energy:electric_range energy:estimated_charging_time energy:recharge_status vehicle:attributes'
        }
    )
    # print(json.dumps(response.json(), indent=4))
    print("Login successful!")
except requests.exceptions.RequestException as error:
    print("Login failed:")
    print(error)

access_token = response.json()['access_token']
# print(access_token)

try:
    vehicles = requests.get(
        "https://api.volvocars.com/extended-vehicle/v1/vehicles",
        headers= {
            "accept": "application/json",
            "vcc-api-key": vccapikey,
            "Authorization": "Bearer " + access_token
        }
    )
    print("\nResult:")
    print(vehicles)

    vehiclesjson = json.dumps(vehicles.json(), indent=4)
    print("\nResult JSON:")
    print(vehiclesjson)

except requests.exceptions.RequestException as error:
    print("Get vehicles failed:")
    print(error)
nikagersonlohman commented 1 year ago

When you'd like to use the API's with Postman, you can use a Pre-request Script like the following:

const username = pm.variables.get('Volvo On-call Username')
const password = pm.variables.get('Volvo On-call Password')
console.log('Using username:' + username)
const postRequest = {
  url: 'https://volvoid.eu.volvocars.com/as/token.oauth2',
  method: 'POST',
  timeout: 0,
  header: {
    'authorization': 'Basic aDRZZjBiOlU4WWtTYlZsNnh3c2c1WVFxWmZyZ1ZtSWFEcGhPc3kxUENhVXNpY1F0bzNUUjVrd2FKc2U0QVpkZ2ZJZmNMeXc=',
    'content-type': 'application/x-www-form-urlencoded',
    'user-agent': 'okhttp/4.10.0'
  },
  body: {
    mode: 'urlencoded',
    urlencoded: [
        { key: 'username', value: username},
        { key: 'password', value: password},
        { key: 'grant_type', value: 'password'},
        { key: 'scope', value: 'openid email profile care_by_volvo:financial_information:invoice:read care_by_volvo:financial_information:payment_method care_by_volvo:subscription:read customer:attributes customer:attributes:write order:attributes vehicle:attributes tsp_customer_api:all conve:brake_status conve:climatization_start_stop conve:command_accessibility conve:commands conve:diagnostics_engine_status conve:diagnostics_workshop conve:doors_status conve:engine_status conve:environment conve:fuel_status conve:honk_flash conve:lock conve:lock_status conve:navigation conve:odometer_status conve:trip_statistics conve:tyre_status conve:unlock conve:vehicle_relation conve:warnings conve:windows_status energy:battery_charge_level energy:charging_connection_status energy:charging_system_status energy:electric_range energy:estimated_charging_time energy:recharge_status vehicle:attributes'}
        ]
  }
};

pm.sendRequest(postRequest, function (err, res) {
    console.log('Granting access...');
    var responseJson = res.json();
    console.log(responseJson);
    pm.environment.set('Energy Access Token', responseJson['access_token']);
    pm.environment.set('Connected Vehicle Access Token', responseJson['access_token']);
    pm.environment.set('Extended Vehicle Access Token', responseJson['access_token']);
});

Simply define the Volvo On-call Username and Password variables and it replaces the access tokens from you collection (@andynash).

You can also use the default Volvo collections from here: https://developer.volvocars.com/apis/connected-vehicle/specification/ https://developer.volvocars.com/apis/energy/specification/ https://developer.volvocars.com/apis/extended-vehicle/specification/

Import them into Postman and create the collections from the API. For this, use the following Pre-request Script:

const username = pm.globals.get('Volvo On-call Username')
const password = pm.globals.get('Volvo On-call Password')
const vccapikey = pm.globals.get('VCC API Key (Primary)')
const postRequest = {
  url: 'https://volvoid.eu.volvocars.com/as/token.oauth2',
  method: 'POST',
  timeout: 0,
  header: {
    'authorization': 'Basic aDRZZjBiOlU4WWtTYlZsNnh3c2c1WVFxWmZyZ1ZtSWFEcGhPc3kxUENhVXNpY1F0bzNUUjVrd2FKc2U0QVpkZ2ZJZmNMeXc=',
    'content-type': 'application/x-www-form-urlencoded',
    'user-agent': 'okhttp/4.10.0'
  },
  body: {
    mode: 'urlencoded',
    urlencoded: [
        { key: 'username', value: username},
        { key: 'password', value: password},
        { key: 'grant_type', value: 'password'},
        { key: 'scope', value: 'openid email profile care_by_volvo:financial_information:invoice:read care_by_volvo:financial_information:payment_method care_by_volvo:subscription:read customer:attributes customer:attributes:write order:attributes vehicle:attributes tsp_customer_api:all conve:brake_status conve:climatization_start_stop conve:command_accessibility conve:commands conve:diagnostics_engine_status conve:diagnostics_workshop conve:doors_status conve:engine_status conve:environment conve:fuel_status conve:honk_flash conve:lock conve:lock_status conve:navigation conve:odometer_status conve:trip_statistics conve:tyre_status conve:unlock conve:vehicle_relation conve:warnings conve:windows_status energy:battery_charge_level energy:charging_connection_status energy:charging_system_status energy:electric_range energy:estimated_charging_time energy:recharge_status vehicle:attributes'}
        ]
  }
};

pm.sendRequest(postRequest, function (err, res) {
    console.log('Granting access...');
    var responseJson = res.json();
    console.log(responseJson);
    pm.environment.set('access_token', responseJson['access_token']);
    pm.request.headers.add({
        key: "Authorization",
        value: "Bearer " + responseJson['access_token']
        });
    pm.request.headers.add({
        key: "vcc-api-key",
        value: vccapikey
        });
});

To use them for all collections, I use "global" variables instead of collection variables. Just need to set them once :)

brownstone666 commented 1 year ago

@nikagersonlohman Thanks for the script. Can you use the Energy API? I have a XC60 23 Hybrid and your flow authentication works fine. When i use any API of Energy I receive 404 error (Resource Not found). When i use old API to list my veicles (extended-vehicle/v1/vehicles) i received and empty array. I think that the problem is with the VIN and my account, because when i try with test access token provided by volvo portal of my car (https://developer.volvocars.com/apis/docs/test-access-tokens/#my-volvo-car) i received the same 404 error.

nikagersonlohman commented 1 year ago

No, Recharge API doesn't work for me either. For some it does though (I know from other forums).

However both extended-vehicle and connected-vehicle do return the VINs of both vehicles in my account: image image

Using the API in the Swagger interface of Volvo with the hourly access token is the best way to test, then you know for sure it is some issue with the API.

I have already seen several issues:

HeffRaleigh commented 1 year ago

For those in the US...Still waiting for Volvo to make the endpoints available for our country. Eager to do some app development once it's available.

Frankstar commented 1 year ago

@nikagersonlohman

        'access_token_manager_id': 'JWTh4Yf0b',

where did you get this from? Cant find it in the documentation or i'm blind ...

nikagersonlohman commented 1 year ago

I found it "on the web"... assume it was somehow traced/debugged/reverse-engineered from the Volvo App, or someone somehow leaked it. Officially you need to apply for a key at the Volvo Developer portal for the app you're developing, but Volvo does not supply them yet: https://developer.volvocars.com/apis/docs/authorisation/

josecarre commented 1 year ago

Thanks for this bud! The odometer needs to be multiplied with 10

I was becoming crazy thinking if it was the demo car or just mine (which is new but no so new πŸ˜† ) I got a 2023 XC60 recharge yesterday... is a pity the API doesnt work fine so that the in-core Home Assistant Volvo On Call integration would work... but nothing works... so Im trying to play with the API... and seems to work.

Does anybody know what it would be needed to bump the core HA integration code to be compatible with our new models?

If not I guess that I will need to do my usual dirsy, very dirty, workaround with node-red and from there add in HA as new entities :( I still need to see how to fix the authorization thing and token renewal because i dont know how do do it in node-red meanwhile the core HA integration gets fixed

Thanks anyway, very good thread!

josecarre commented 1 year ago

Ok, some good and bad news after some days playing :) I managed to check that a fix is doable, as I have integrated my 2023 XC60 PHEV into HA... but not with core integration (that one doesnt work...yet?), but manually with each API request and node-red, and from node-red to HA sensors/buttons...etc The way I handle the authentication is the dirty one, a full auth for each time i get sensors data. It seems to work fine... fuel status, battery, door status... lock doors... unlock doors... activate climate...etc All but car location because I cannot find how to get that info from API :( (in my former BMW i had a device tracker with car GPS location, it was really nice, but in Volvo i dont know how is handled)

So... at least we know that the API work and that the integration is fixable... Sadly my python skills are not enough for fixing the integration. Besides the Volvo developer portal where there is a lot of info... I got the requests formats and some very usefull toolkit to do tests from this repo from @andynash : https://www.postman.com/andynash/workspace/volvo-apis/collection/6009097-92ddc541-ef84-4d87-acec-03b1b19abd9b?tab=overview

For now I have just added some stuff that I use most (it gets refreshed every 5min), im only missing the car location: image

So for everyone... as doing this dirty way with node-red...etc is very far from clean... I can only say to other people that the integration is fixable for our cars... so with some time I guess we will have in Home Assistant core this working again :)

josecarre commented 1 year ago

Ok, some good and bad news after some days playing :) I managed to check that a fix is doable, as I have integrated my 2023 XC60 PHEV into HA... but not with core integration (that one doesnt work...yet?), but manually with each API request and node-red, and from node-red to HA sensors/buttons...etc The way I handle the authentication is the dirty one, a full auth for each time i get sensors data. It seems to work fine... fuel status, battery, door status... lock doors... unlock doors... activate climate...etc All but car location because I cannot find how to get that info from API :( (in my former BMW i had a device tracker with car GPS location, it was really nice, but in Volvo i dont know how is handled)

So... at least we know that the API work and that the integration is fixable... Sadly my python skills are not enough for fixing the integration. Besides the Volvo developer portal where there is a lot of info... I got the requests formats and some very usefull toolkit to do tests from this repo from @andynash : https://www.postman.com/andynash/workspace/volvo-apis/collection/6009097-92ddc541-ef84-4d87-acec-03b1b19abd9b?tab=overview

For now I have just added some stuff that I use most (it gets refreshed every 5min), im only missing the car location: image

So for everyone... as doing this dirty way with node-red...etc is very far from clean... I can only say to other people that the integration is fixable for our cars... so with some time I guess we will have in Home Assistant core this working again :)

If anyone is interested in the node-red flow, here I posted the info: https://github.com/home-assistant/core/issues/61785#issuecomment-1584970951

Dielee commented 1 year ago

Maybe it is interesting for someone who is facing exactly this problem. I have built a MQTT bridge to connect AAOS cars to Homeassistant. Take a look here: https://github.com/Dielee/volvo2mqtt