BMW ConnectedDrive component

@coolTNT

What I did for the German website:
I used the developer console from Google Chrome and observed me logging into the connected drive site. And there is one URL where the browser sends the username/password and get the “access_token” back in the header of the response.

What I would need are examples of:

  • the url that the login request is sent to
  • an example of the request header (to see if the format is the same)
  • an example of the response header (to see if the format is the same)

I can’t analyze that as I can’t create a Canadian Connected Drive account without a Canadian vehicle…

Thanks for the very fast reply… I did see that in the documentation and left the name: but got the error.

Thanks for adding this!!! It will be very handy…

The proper example of the config file is:

bmw_connected_drive:
  some_random_name:
    username: USERNAME_BMW_CONNECTED_DRIVE
    password: PASSWORD_BMW_CONNECTED_DRIVE
    country: COUNTRY_BMW_CONNECTED_DRIVE

The problem here is that obviously the US and Canadian Connected Drive portals are using a different URL to login via username/password. So i need someone with such an account to figure out the parameters (see my comment above: BMW ConnectedDrive component)

I’ll take a look

The url that the login request is sent to:

Request URL:https://crm.bmw.ca/en-CA/ConnectedDrive/Account
Request Method:POST
Status Code:302 Found
Remote Address:170.34.127.29:443
Referrer Policy:no-referrer-when-downgrade

Request header:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en-CA;q=0.9,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Content-Length:226
Content-Type:application/x-www-form-urlencoded
Cookie:_ceir=1; _ceir=1; _ga=GA1.2.1358790589.1519157268; mbox=PC#5f453cbf5afe489c8e1a00cba67ceabe.28_36#1521138783|check#true#1519929243|session#0773a9326d19454988d8bf3811a24a24#1519931043; bmwdtm_hq_vs=1519929182; AMCVS_B52D1CFE5330949C0A490D45%40AdobeOrg=1; AMCV_B52D1CFE5330949C0A490D45%40AdobeOrg=1406116232%7CMCIDTS%7C17592%7CMCMID%7C82524880656740560990890069398466268113%7CMCAAMLH-1520533982%7C9%7CMCAAMB-1520533982%7CRKhpRz8krg2tLO6pguXWp5olkAcUniQYPHaMWWgdJ3xzPWQmdj0y%7CMCOPTOUT-1519936382s%7CNONE%7CMCAID%7CNONE%7CvVersion%7C2.5.0; s_cc=true; ASP.NET_SessionId=yzun3h1j02w2yohodym0ytu1; __RequestVerificationToken=SDHbxv7X7KYwJEGcgLsE4rWhZe0IouMtds-6WcdHHK9CuSZAkqcpUPQOIBzUHvdXs8Mz6WauX4kFIWfhhBMonOQr5CMiknK_x5BuCPIfluz-ACYqeDBRLIBbbiALis1CcaaJ9A2; content-bmwca.bmwgroup.net=3579912874.16927.0000; _gid=GA1.2.46712706.1519929328; CDSESSION=d93a5cc7-60f0-4b0c-837a-403918714e4e; _gat=1; _ceg.s=p4xefu; _ceg.u=p4xefu
Host:crm.bmw.ca
Origin:https://crm.bmw.ca
Pragma:no-cache
Referer:https://crm.bmw.ca/en-CA/ConnectedDrive/Account
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36

Response header:

Access-Control-Allow-Origin:*
Cache-Control:private
Connection:Keep-Alive
Content-Length:138
Content-Type:text/html; charset=utf-8
Date:Thu, 01 Mar 2018 19:07:28 GMT
Keep-Alive:timeout=15, max=100
Location:/en-CA/ConnectedDrive
p3p:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"
Server:Microsoft-IIS/7.5
Set-Cookie:CDSESSION=2b3f7cde-737d-405a-b7d2-7514ebe1d919; expires=Fri, 02-Mar-2018 07:07:28 GMT; path=/
Set-Cookie:CDSESSION=61b0f69d-b6f0-4b46-96ba-638b2812699f; expires=Fri, 02-Mar-2018 07:07:28 GMT; path=/
Strict-Transport-Security:max-age=31536000
X-AspNet-Version:4.0.30319
X-AspNetMvc-Version:4.0
X-Powered-By:ASP.NET

Form data:

__RequestVerificationToken:token
LoginId:[email protected]
Password:password
RememberMe:false

This should be fixed in HA 0.64.2 which is just released.

That’s already the case :grinning:
When the door_lock_state is LOCKED or SECURED:

  • The lock (switch) has a locked icon
  • The status of the binary sensor ‘Door lock state’ is shown as Safe

When the door_lock_state is SELECTIVELOCKED or UNLOCKED:

  • The lock (switch) has an unlocked icon
  • The status of the binary sensor ‘Door lock state’ is shown as Unsafe

I see you don’t have that binary sensor in your group, but it’s already available, so you can add that.
Quickest way to find all sensors available for your car is to go to Developer tools - States and go to Filter attributes where you can enter the type of your car, in your case X1 sDrive18d.

You can add control: hidden to your BMW X1 Group so no On/Off switch is shown in the header, which will avoid you to accidentally switch on the horn, lights and climate at the same time :wink:

now we are talking business :ok_man::rofl:

No change here with 64.2, still loads of errors:

During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/usr/lib/python3.6/asyncio/tasks.py", line 180, in _step
    result = coro.send(None)
  File "/usr/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 223, in async_update_ha_state
    device_attr = self.device_state_attributes
  File "/config/custom_components/switch/bmw_connected_drive.py", line 69, in device_state_attributes
    'last_update': vehicle_state.timestamp,
  File "/config/deps/lib/python3.6/site-packages/bimmer_connected/state.py", line 46, in _func_wrapper
    raise ValueError('No data available!')
ValueError: No data available!
2018-03-02 08:43:13 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/config/deps/lib/python3.6/site-packages/bimmer_connected/state.py", line 44, in _func_wrapper
    return func(self, *args, **kwargs)
  File "/config/deps/lib/python3.6/site-packages/bimmer_connected/state.py", line 91, in timestamp
    unix_time = int(self._attributes['updateTime_converted_timestamp'])
KeyError: 'updateTime_converted_timestamp'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/usr/lib/python3.6/asyncio/tasks.py", line 180, in _step
    result = coro.send(None)
  File "/usr/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 223, in async_update_ha_state
    device_attr = self.device_state_attributes
  File "/config/custom_components/switch/bmw_connected_drive.py", line 69, in device_state_attributes
    'last_update': vehicle_state.timestamp,
  File "/config/deps/lib/python3.6/site-packages/bimmer_connected/state.py", line 46, in _func_wrapper
    raise ValueError('No data available!')
ValueError: No data available!

You are using the custom component, that version is not changed yet.
Either remove the custom component so you can use the updated version in 0.64.2 or wait until I have updated the custom component.

Edit: the custom component is bumped to bimmer_connected v0.41.

OK fair enough, sorry!

My data doesn’t seem to work though.

sensor.440i_mileage	26891.0	unit_of_measurement: mls
friendly_name: 440i mileage
sensor.440i_remaining_fuel	32.0	unit_of_measurement: mpg
friendly_name: 440i remaining_fuel

This hasn’t changed since I first installed this component.

Similarly my GPS location in device_tracker is completely wrong. It’s actually my local BMW body shop!

It’s almost like the data retrieved is days or even weeks/months old.

No problem :grinning:

Can you open the BMW ConnectedDrive app and after that check if HA shows recent data?
Some older cars don’t seem to support auto refresh of the data. See this post BMW ConnectedDrive component.

2017 320d MSport in the UK and I get milage, remaining_fuel and remaining_range_fuel and GPS location on hass.io 0.95

Can you advise how to change the remaining fuel from mpg to litres? Also seem to be missing all the nice icons under hass.io - any advise

Am about to try the custom components if you need any testing done

Mmm not much different.

sensor.440i_mileage	26891.0	unit_of_measurement: mls
friendly_name: 440i mileage
sensor.440i_remaining_fuel	32.0	unit_of_measurement: mpg
friendly_name: 440i remaining_fuel

GPS has updated though!

@coolTNT
Thx for the analysis. The request and response look quite different from the one from Europe. What I’m missing is the access_token in the Location attribute. This token is then used in the authentication of the API calls. So it seems this is done differently in the Canadian site :frowning:

Location:https://www.bmw-connecteddrive.com/app/static/external-dispatch.html#state=SOME_STRING&access_token=SOME_SECRET_TOKEN&token_type=Bearer&expires_in=7199

I gave it a shot anyway and implemented it on the branch “canada”. But I would not expect it to work…
https://github.com/ChristianKuehnel/bimmer_connected/tree/canada

If you want, you can run status.py from the branch and see if it gives you the current vehicle status.

@gr4z

Maybe this is related to the vehicle. In my last vehicle, I had to push the “update position” icon in the BMW connected drive portal. Only then it would update the position after waiting for some time.

Only the later generations of the head units seem to upload the position automatically after parking the car.

Which model, year and head unit do you have?

I have a 2016 F36 (440i Gran Coupe). It only has ID4 so I wonder if that is the problem, perhaps you need ID5 or 6 for this to work properly? Damn BMW for superseding its software so quick!

Yes you need ID5.

Grrr, damn you BMW. No upgrade path either except to buy another car!

Yeah, I ran status.py from the canada branch, and it couldn’t get an access token.

However, I captured the packets that the BMW Remote app sends out when performing first time login, and it seems to get it’s access token from b2vapi.bmwgroup.us/webapi/oauth/token , then gets vehicle information from b2vapi.bmwgroup.us/webapi/v1/user/vehicles with the access token that it just received.

So essentially AUTH_URL for Canada might be b2vapi.bmwgroup.us/webapi/oauth/token

VEHICLE_SPECS_URL or LIST_VEHICLES_URL would be b2vapi.bmwgroup.us/webapi/v1/user/vehicles (I can’t tell, I only have one car)

I haven’t gotten around to trying any remote services yet, but will try to find out what the REMOTE_SERVICE_URL is soon. :slight_smile:

To try these URLs I would just have to put them into bimmer_connected/const.py right?

Update: I tried it, it doesn’t work. I think it’s because the Canadian site sends the access token back as a JSON in the response, which I think removes the need to use 'redirect_uri': 'https://www.bmw-connecteddrive.com/app/default/static/external-dispatch.html', and self._oauth_token = url_with_token['access_token'][0]

Below is the first packet sent/recieved by the BMW Remote app on first startup, after the login button is pressed.