Reverse Engineering the BMW i3 API
I'm really enjoying driving the BMW i3.
I'd love to have it tweet its driving efficiency, or upload its location to my server, or let me turn on its air-conditioning when the temperature gets too warm - there are a hundred interesting things to do with the car's data. The official app has some of these features - but is slow, ugly, and a pain to use.
BMW used to have an API available for hackathons, but they shut it down.
Right! Only one thing to do - HACK THE MAINFRAME*!
Aim
The ultimate aim is to get access to all the car's functions which are exposed by the API - so I can do something like this:
Equipment
For this relatively simple bit of work you will need...
- A BMW i3.
- An account with BMW's ConnectedDrive.
- The BMW i Remote App for Android. (I'm using the non-US version.)
- An Android phone or tablet.
- A way to intercept encrypted communications leaving your device - I recommend Packet Capture by Grey Shirts.
With Packet Capture installed, close all other apps, start the logging, then log in to the i Remote app. Click around on a few functions, then flip back to the Packet Capture app.
You'll see a bunch of API calls which have been captured.
Click on one and you'll see the full API call, plus the JSON response. I've stripped out some of my personal details.
The most important thing you'll need is the Authorization: Bearer
token. This is a 32 character alphanumeric string.
Description
The latest version can always be found on GitHub.
These API calls are designed to allow you to interact with your BMW i3. They were reverse engineered from the official BMW i Remote Android app.
Your use of these API calls is entirely at your own risk. They are neither officially provided nor sanctioned.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Servers
There are three API servers.
https://b2vapi.bmwgroup.cn:8592
Chinahttps://b2vapi.bmwgroup.us
USAhttps://b2vapi.bmwgroup.com
Europe / Rest of World
Authorisation
In order to authenticate against the API you will need to be registered on BMW's Connected Drive service.
You will need:
- Your ConnectedDrive registered email address.
- Your ConnectedDrive registered password.
- The i Remote API Key.
- The i Remote API Secret.
You can get the i Remote details from either decompiling the Android App or from intercepting communications between your phone and the BMW server. This is left as an exercise for the reader ☺
Firstly, we use Basic authentication. That means taking the API Key and Secret and Base64 encoding them.
So key:secret
becomes a2V5OnNlY3JldA==
We also need to send the following parameters as
Content-Type: application/x-www-form-urlencoded
grant_type=password
&username=whatever%40example.com
&password=p4ssw0rd
&scope=remote_services+vehicle_data
Here's how to do it with curl
:
BASHcurl \
-H "Authorization: Basic a2V5OnNlY3JldA==" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password&username=whatever%40example.com&password=p4ssw0rd&scope=remote_services+vehicle_data" \
"https://b2vapi.bmwgroup.com/webapi/oauth/token/"
If everything has worked, you should get back the following JSON:
JSON{
"access_token": "RCQ1hLP4AFaUBW9BjcPUN3i4WgkwF90R",
"token_type": "Bearer",
"expires_in": 28800,
"refresh_token": "7WgKmEJ2kD1ydl9Hefp01eS8qDGzKnzjeORpA6vtsoFIEanz",
"scope": "vehicle_data remote_services"
}
You must include
Authorization: Bearer RCQ1hLP4AFaUBW9BjcPUN3i4WgkwF90R
in your headers with every request.
The expires_in
is in seconds - giving you 8 hours before you have to renew the token.
I've no idea what the refresh_token
is for. Once the access_token
expires, you can simply re-authenticate and gain a new one.
API
You must include
Authorization: Bearer RCQ1hLP4AFaUBW9BjcPUN3i4WgkwF90R
in your headers with every request.
Get Vehicle Data
-
/webapi/v1/user/vehicles/
- Remember to include the
Authorization: Bearer
header.
- Remember to include the
The most important thing here is the VIN - Vehicle Identification Number. You'll need that for all the other API calls as well as the Authorization Bearer.
Response
JSON{
"vehicleStatus": {
"vin": "WAB1C23456V123456",
"mileage": 1234,
"updateReason": "VEHICLE_SHUTDOWN_SECURED",
"updateTime": "2015-10-30T18:45:04+0100",
"doorDriverFront": "CLOSED",
"doorDriverRear": "CLOSED",
"doorPassengerFront": "CLOSED",
"doorPassengerRear": "CLOSED",
"windowDriverFront": "CLOSED",
"windowDriverRear": "CLOSED",
"windowPassengerFront": "CLOSED",
"windowPassengerRear": "CLOSED",
"trunk": "CLOSED",
"rearWindow": "INVALID",
"convertibleRoofState": "INVALID",
"hood": "CLOSED",
"doorLockState": "SECURED",
"parkingLight": "OFF",
"positionLight": "OFF",
"remainingFuel": 8.9,
"remainingRangeElectric": 73,
"remainingRangeElectricMls": 45,
"remainingRangeFuel": 126,
"remainingRangeFuelMls": 78,
"maxRangeElectric": 134,
"maxRangeElectricMls": 83,
"fuelPercent": 99,
"maxFuel": 9,
"connectionStatus": "DISCONNECTED",
"chargingStatus": "INVALID",
"chargingLevelHv": 58,
"lastChargingEndReason": "UNKNOWN",
"lastChargingEndResult": "FAILED",
"position": {
"lat": 51.123456,
"lon": -1.2345678,
"heading": 211,
"status": "OK"
},
"internalDataTimeUTC": "2015-10-30T18:47:44"
}
}
Values
mileage
is in Km.remainingFuel
is in Litres.maxRangeElectric
is in Km.maxRangeElectricMls
is in miles.chargingLevelHv
is the percentage of charge left in the (High voltage?) battery.maxFuel
is in Litres.heading
is in degrees.
Valid chargingStatus
es appear to be:
CHARGING
ERROR
FINISHED_FULLY_CHARGED
FINISHED_NOT_FULL
INVALID
NOT_CHARGING
WAITING_FOR_CHARGING
Valid connectionStatus
es appear to be:
CHARGING_DONE
CHARGING_INTERRUPED
[sic]CHARGING_PAUSED
CHARGIN_STARTED
[sic]CYCLIC_RECHARGING
DOOR_STATE_CHANGED
NO_CYCLIC_RECHARGING
NO_LSC_TRIGGER
ON_DEMAND
PREDICTION_UPDATE
TEMPORARY_POWER_SUPPLY_FAILURE
UNKNOWN
VEHICLE_MOVING
VEHICLE_SECURED
VEHICLE_SHUTDOWN
VEHICLE_SHUTDOWN_SECURED
VEHICLE_UNSECURED
Get Last Trip
Shows the details about your most recent trip.
-
/webapi/v1/user/vehicles/:VIN/statistics/lastTrip
- Where
:VIN
is your vehicle's VIN. - Remember to include the
Authorization: Bearer
header.
- Where
Response
JSON{
"lastTrip":{
"efficiencyValue":0.53,
"totalDistance":141,
"electricDistance":100.1,
"avgElectricConsumption":16.6,
"avgRecuperation":2,
"drivingModeValue":0,
"accelerationValue":0.39,
"anticipationValue":0.81,
"totalConsumptionValue":0.79,
"auxiliaryConsumptionValue":0.66,
"avgCombinedConsumption":1.9,
"electricDistanceRatio":71,
"savedFuel":0,
"date":"2015-12-01T20:44:00+0100",
"duration":124
}
}
Values
Distances appear to be in Kilometres rather than miles, so be sure to adjust accordingly. Multiply by 0.621371
to get miles.
totalDistance
is in Km.electricDistance
is in Km.avgElectricConsumption
is in kWh/100Km.avgRecuperation
is in kWh/100Km.duration
is in minutes.
To convert kWh/100Km to Miles/kWh.
1 / (0.01609344 * avgElectricConsumption)
Get Charging Times
Shows when the car is scheduled to charge.
-
/webapi/v1/user/vehicles/:VIN/chargingprofile
- Where
:VIN
is your vehicle's VIN. - Remember to include the
Authorization: Bearer
header.
- Where
Response
JSON{
"weeklyPlanner":{
"climatizationEnabled":true,
"chargingMode":"DELAYED_CHARGING",
"chargingPreferences":"CHARGING_WINDOW",
"timer1":{
"departureTime":"07:30",
"timerEnabled":true,
"weekdays":[
"MONDAY"
]
},
"timer2":{
"departureTime":"13:00",
"timerEnabled":false,
"weekdays":[
"SATURDAY"
]
},
"timer3":{
"departureTime":"08:00",
"timerEnabled":false,
"weekdays":[
]
},
"overrideTimer":{
"departureTime":"07:30",
"timerEnabled":false,
"weekdays":[
"MONDAY"
]
},
"preferredChargingWindow":{
"enabled":true,
"startTime":"05:02",
"endTime":"17:31"
}
}
}
Values
departureTime
appears to be the car's local time.
Get Vehicle Destinations
Shows the destinations you've previously sent to the car.
-
/webapi/v1/user/vehicles/:VIN/destinations
- Where
:VIN
is your vehicle's VIN. - Remember to include the
Authorization: Bearer
header.
- Where
Response
JSON{
"destinations":[
{
"lat":51.53053283691406,
"lon":-0.08362331241369247,
"country":"UNITED KINGDOM",
"city":"LONDON",
"street":"PITFIELD STREET",
"type":"DESTINATION",
"createdAt":"2015-09-25T08:06:11+0200"
}
]
}
Values
- An array of locations.
Get All Trip Details
Shows the statistics for all trips taken in the vehicle.
-
/webapi/v1/user/vehicles/:VIN/statistics/allTrips
- Where
:VIN
is your vehicle's VIN. - Remember to include the
Authorization: Bearer
header.
- Where
Response
JSON{
"allTrips": {
"avgElectricConsumption": {
"communityLow": 0,
"communityAverage": 16.33,
"communityHigh": 35.53,
"userAverage": 14.76
},
"avgRecuperation": {
"communityLow": 0,
"communityAverage": 3.76,
"communityHigh": 14.03,
"userAverage": 2.3
},
"chargecycleRange": {
"communityAverage": 121.58,
"communityHigh": 200,
"userAverage": 72.62,
"userHigh": 135,
"userCurrentChargeCycle": 60
},
"totalElectricDistance": {
"communityLow": 1,
"communityAverage": 12293.65,
"communityHigh": 77533.6,
"userTotal": 3158.66
},
"avgCombinedConsumption": {
"communityLow": 0,
"communityAverage": 1.21,
"communityHigh": 6.2,
"userAverage": 0.36
},
"savedCO2": 87.58,
"savedCO2greenEnergy": 515.177,
"totalSavedFuel": 0,
"resetDate": "1970-01-01T01:00:00+0100"
}
}
Values
chargecycleRange
is in Km.totalElectricDistance
is in Km.
I'm not sure what units of the other values are.
Get Range Map
Generate a polyline displaying the predicted range of the vehicle.
-
/webapi/v1/user/vehicles/:VIN/rangemap
- Where
:VIN
is your vehicle's VIN. - Remember to include the
Authorization: Bearer
header.
- Where
Response
JSON{
"rangemap": {
"center": {
"lat": 51.123456,
"lon": -1.2345678
},
"quality": "AVERAGE",
"rangemaps": [
{
"type": "ECO_PRO_PLUS",
"polyline": [
{
"lat": 51.6991281509399,
"lon": -2.00423240661621
},
{
"lat": 51.6909098625183,
"lon": -1.91526889801025
},
...
]
},
{
"type": "COMFORT",
"polyline": [
{
"lat": 51.7212295532227,
"lon": -1.7363977432251
},
{
"lat": 51.6991496086121,
"lon": -1.73077583312988
},
...
]
}
]
}
}
Values
ECO_PRO_PLUS
driving using the efficient Eco mode.COMFORT
driving using comfort mode.
Sending information to the car
Sending information to the car is slightly complicated.
Your app communicates with the API, the API then communicates with the car's 3G modem, then you have to wait for a response.
If your car is in poor coverage, you can expect significant latency. Often much higher than a typical timeout will allow for.
At a basic level, you can just send a request - for example to lock the doors, or set off-peak charging.
Get Request status
Shows the status of a POST
ed request
-
/webapi/v1/user/vehicles/:VIN/serviceExecutionStatus?serviceType=:SERVICE
- Where
:VIN
is your vehicle's VIN. - Remember to include the
Authorization: Bearer
header.
- Where
Response
JSON{
"executionStatus":{
"serviceType":"DOOR_LOCK",
"status":"EXECUTED",
"eventId":"123456789012345AB1CD1234@bmw.de"
}
}
Values
Valid status
es are:
DELIVERED
EXECUTED
INITIATED
NOT_EXECUTED
PENDING
TIMED_OUT
The following are valid :SERVICE
types, but may not be supported by your vehicle.
CHARGE_NOW
CHARGING_CONTROL
CLIMATE_CONTROL
CLIMATE_NOW
DOOR_LOCK
DOOR_UNLOCK
GET_ALL_IMAGES
GET_PASSWORD_RESET_INFO
GET_VEHICLES
GET_VEHICLE_IMAGE
GET_VEHICLE_STATUS
HORN_BLOW
LIGHT_FLASH
LOCAL_SEARCH
LOCAL_SEARCH_SUGGESTIONS
LOGIN
LOGOUT
SEND_POI_TO_CAR
VEHICLE_FINDER
POST a command
Instructs the car to perform an action.
-
/webapi/v1/user/vehicles/:VIN/executeService
- Where
:VIN
is your vehicle's VIN. - Remember to include the
Authorization: Bearer
header.
- Where
Available Commands
These commands are all available via the API, but may not be supported by your vehicle.
These are just what I've discovered so far.
Data must be POST
ed to the server.
Initiate Charging
If the vehicle is plugged in, but not charging (due to an off peak setting?) it is possible to force the car to charge.
serviceType=CHARGE_NOW
Start Climate Control
This will activate climate control within your vehicle.
It appears to be limited to the last temperature you set when you were in the car. I can't find a way to instruct the car to reach a specific temperature.
serviceType=CLIMATE_NOW
Lock the doors
Performs central locking.
serviceType=DOOR_LOCK
Unlock the doors
This will unlock all the doors on your vehicle.
Please use extreme caution when sending this command. Ensure that you are in sight of the vehicle and are able to lock it if needed.
serviceType=DOOR_UNLOCK
Flash the headlights
If you can't find the vehicle, or need to illuminate something in its vicinity, you can briefly activate the headlights.
-
serviceType=LIGHT_FLASH&count=2
- I assume that
count
relates to the number of seconds to keep the light on?
- I assume that
Charging Schedule
Set the peak / off peak charging schedule.
-
serviceType=CHARGING_CONTROL
- I haven't bothered to figure this out, but the error it returns should give you some pointers:
JSON{
"error":{
"code":500,
"description":"(SmartPhoneUtil-A-102) Bad value(s) for parameter(s): Invalid chargingProfile, expected weeklyPlanner or twoTimesTimer"
}
}
Vehicle Finder
-
serviceType=VEHICLE_FINDER
- I'm not sure what this does.
Response
An example response for all POST
commands:
JSON{
"executionStatus": {
"serviceType": "LIGHT_FLASH",
"status": "INITIATED",
"eventId": "123456789012345AB1CD1234@bmw.de"
}
}
What's Next
Using these commands you should be able to replicate the functionality of the official app.
As you can see, I've managed to get my car to Tweet:
It would be lovely if BMW decided to open up an official API so that people could fiddle with their cars. The API seems secure and there's limited scope for damaging the vehicles.
I've added all the documentation to GitHub. Please raise an issue or send a Pull Request with any changes.
aokincaid says:
This was a delightful read! Awesome work.
Tomas says:
What you described is pretty standard oAuth architecture. refresh_token is there to be able to refresh your access_token after it expires without having to send username and password again.
Quentin says:
Yes, excellent stuff - Well done! Not having an Android device, I've just used a proxy called Charles (https://www.charlesproxy.com) to get the necessary data from my iPhone app...
Justin says:
Hi quentin - I've done the same thing as you. Perhaps I am missing something or not following correctly, but I'm not seeing api key/secret in my packet capture. Any hints?
quentinsf says:
Hi Justin - I don't have it in front of me, but if memory serves, the key and secret are used to get a token which is valid for a certain period. I used the token that the app was using, initially, for the API, but also printed out its expiry time, which turned out not to be very distant.
The app will have the same expiry time, so I kept it using the proxy and the first time after the expiry, the key and secret were visible in the exchange.
Hope that helps!
William says:
it's really good to see you doing this. But it is lamentable - outrageous even - that BMW make it so hard. Two questions arise for me. 1. What sort of consumer pressure can BMW owners/drivers exert to get BMW to give them an open API on a car they've bought? and 2. Are there legality issues eg in US under DMCA and similar legislation, also under new emerging legislation such as TTP?
Longer term surely open source cars will prevail over closed systems.
Terence Eden says:
Hi William,
Most consumers won't care - API access is a non-issue. The best way to make consumers ask for this is by providing features which rely on this access. For example "VW's cars can do XYZ, why can't BMW's?".
I am not a lawyer - I'm also based in the UK, not the USA. I suggest contacting the EFF or writing to your local politicians.
And, yes, let's hope Open Source wins out in the end!
Alex B says:
Relevant parts of the UK's Copyright, Designs and Patents Act 1988:
http://www.legislation.gov.uk/ukpga/1988/48/section/50B http://www.legislation.gov.uk/ukpga/1988/48/section/50BA
However...
http://www.legislation.gov.uk/ukpga/1988/48/section/50C
and I'd imagine BMW have a click-through license somewhere that says you won't modify or copy their stuff.
Terence Eden says:
Interesting. There was nothing in the app's T&Cs which I can see. Thanks for the info.
franky_b (@Franky_B) says:
Terence, thank you for all this. Quick question, how can I get valid API Key & API Secret if I don't have an iPhone or Android (Windows all the way here) Since no iRemote app for Windows, I was planning to build my own.
Terence Eden says:
You'll need a copy of either app, sorry.
franky_b (@Franky_B) says:
That's what I was afraid of. Thanks for the reply.
anonymous coward says:
Great work Terence, although I've been unable to capture the authentication tokens as it appears BMW have now implemented some form of certificate pinning within their app. As now once the app is opened, multiple sessions are established with b2vapi.bmwgroup.com but no data is transfered - as if TLS is failing in handshake stages. Any ideas how I can get hold of the API key and secret? Cheers,
GuiToon says:
It's very good, can you post exemple to post command in python ? Thanks.
Terence Eden says:
You'll find example code on GitHub https://github.com/edent/BMW-i-Remote
GuiToon says:
Hi, on the GitHub I only found GET Commands. I need POST commands to send serviceType=CLIMATE_NOW. Thank you. Regards.
quentinsf says:
That may be my fault - I re-engineered some of Terence's original code, and I only did GET. I can't remember whether his original had POSTs as well - it wouldn't be difficult to add.
Rick Engle says:
Hi Terrence, is there a discussion group set up anywhere for this? I've made great progress on my own app but ran into a problem. After getting the vehicle status, once I retrieve that info it doesn't seem to change when I refresh that data unless I restart my app. Is there any possibility that a time stamp needs to be included too to trigger a new vehicle status update? Looking at the iPhone iRemote traffic it uses this type of URL for its status requests: https://b2vapi.bmwgroup.us/webapi/v1/user/vehicles/MyVIN/status?deviceTime=2016-01-03T17%3A46%3A46
Thanks, Rick
Terence Eden says:
Hi Rick, Best place to discuss is on GitHub https://github.com/edent/BMW-i-Remote
Thanks
Rick Engle says:
I may have a problem spotting where to go on GitHub but I just don't see any discussion/comment sections there. Can you point me specifically on where to go? I have a lot of questions and a lot of comments on things I've discovered in my C# app on Windows.
Terence Eden says:
Hi Rick,
Take a look at the issues page - https://github.com/edent/BMW-i-Remote/issues/ - for each thing you're interested in discussing, raise a separate issue.
Thanks
Terence
GuiToon says:
I'm not very good for coding in Python, I need help for POST commands.
Alexander Holsgrove says:
Has anyone managed to packet-sniff or otherwise obtain the key & secret? Are these different for every device or can someone share them. I had no luck using tPacketCapture (jp.co.taosoftware.android.packetcapture) or Packet Capture (app.greyshirts.sslcapture)
quentinsf says:
I think they're basically fixed for a specific app, but we don't really want to take the responsibility of sharing them. 🙂
What I did for my iOS phone in a similar situation was get a copy of the Charles proxy app (charlesproxy.com), run it on my laptop including SSL proxying, and on my phone (a) install the root SSL key that Charles can generate and (b) tell my phone to use the laptop as a proxy. Finally, if memory serves, when watching the current keys go by, look at their expiry time and after that has passed, fire up the app again and you'll see the key and secret being sent.
There are ways you can do this with free open source software, but Charles is very handy if you do any kind of HTTP network monitoring and worth the price, in my opinion.
Alexander Holsgrove says:
Thank you Quentin. Seems a fantastic bit of software and one I am likely to purchase. I am testing on both my Android phone and my iPad. I have installed the SSL certificate after setting up the proxy connection. I can also see it making requests to the API endpoint but I am getting no data and Charles shows "SSLHandshake: Received fatal alert: certificate_unknown" via Android and "SSLHandshake: Remote host closed connection during handshake". Is this a case that the app has been updated since you managed to get it to work. As an aside, I am also using the normal Remote app rather than one for the i3 / i8 car.
Alexander Holsgrove says:
Just a quick update. It seems that the regular Remote app doesn't want to play nice with Charles Proxy. I had to download the i Remote app and that gave me what I needed. I can now make requests and retrieve the vehicle data for my M135i 🙂 Thank you again
quentinsf says:
Ah - well done for sorting it out before I managed to respond! Interesting to know that it works for other vehicles too!
Rocco says:
One thing that I am interested in pulling is the energy consumed while charging. I can then register historical energy consumption and that allows me to make decisions about where to charge it, when, etc = save money. I can't see that data being exposed by BMW through this way, nor any other. Am I missing something?
Terence Eden says:
No, I don't think you can see the charging rate. Best you can do is measure the percentage of the battery every minute and work it out from there.
ryansbuckner says:
I was able to successfully use your technique to have my home automation system pre-cool my BMW 535i on hot mornings. Now my kids don't get into a hot car to wait for me to take them to camp.
Thank you so much!
Paul says:
I am using Charles and an iPhone with the iRemote app. I am unable to get the api keys. I get the following error in Charles: "Failure No request was made. Possibly the SSL certificate was rejected." I have the Charles certificate installed on the iPhone but the iRemote app does not seem to recognize it. I know it is installed properly because the proxy works for SSL sites from the Safari browser. Anyone have any ideas?
By the way, great work on this.
Terence Eden says:
I think the newer app uses Certificate Pinning. There's some discussion about this on the GitHub page.
Martin Zerweck says:
Hello Terence,
this is fascinating stuff. I don't own an i3, but I am currently researching data to build an estimation model for the range of electric cars in real world settings. The car manufacturers are not easily giving these out and i found no public data for this task. I was wondering if you or anyone else was collecting regular output of the "status" API durig a trip and would be willing to share some trip histories (anonymized, of course) to an open data platform or your blog? I am mostly interested in the lat/long coords, combined with the state of charge, remaining fuel, a timestamp and mileage. I completely understand however if you do not want to give out coordinates near your place of residence. I then would still be interested in the remaining data, since my model could also work with a combination of mileage and charging state. Thank you in any case.
Best regards, Martin
Egil Helleland says:
Hi Terence. is this not working anymore? i am not that good with coding. is there a workaround to get data from the bmw app? with the ssl thing?
Thank you for doing this work BTW!
@edent says:
I don't have this car any more. I cannot help you. If you read the GitHub pages, you may find someone who can. https://github.com/edent/BMW-i-Remote/issues/
Quentin Stafford-Fraser says:
Hi Egil -
I did a little work on this with Terence in the early days, but I now mostly monitor my i3 using my home automation system (which is based on Home Assistant). That has a BMW ConnectedDrive plugin, and looking more carefully at it, I see it’s based on this library (which also credits Terence’s library as being an influence!).
https://github.com/bimmerconnected/bimmer_connected
Hope it’s useful! Quentin
Havrla says:
Helooo this day change in response json socMAX to socmax.
fix: if r.status_code == 200: status = r.json() if status.get('socmax'): socMax = status['socmax'] if status.get('socMax'): socMax = status['socMax'] logging.info('SoC Data retreived successfully') return socMax else:
Havrla says:
if r.status_code == 200: status = r.json() if status.get('socmax'): socMax = status['socmax'] if status.get('socMax'): socMax = status['socMax'] logging.info('SoC Data retreived successfully') return socMax else:
Havrla says:
Heloo API off, BMW migrate to Azure and change functional 🙁 Havrla
Phillip says:
Any thoughts on how to intercept Messages that leave the telematics unit? I have a retrofited atm in my f series but have know idea what the donor vin is. Figure I can build a cheap gsm sniffer capture the calls as they egress the atm. My concern is the encryption one would hope messages are encrypted as they leave the atm. So wondering if anyone can confirm that before I waste my time trying to capture traffic.
Andreas says:
Is there a similar way to get data from the new API ?