Serious problem with new BMW ConnectedDrive Website (USA)

BMW i3 Forum

Help Support BMW i3 Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.
fireball08 said:
Yup, did the same thing as Alohart - unchecked the box. Suddenly car is gone from the app. No features on the portal through computer. Not sure whether to wait or unregister, then re-add the car.

I suggest deleting and re-registering your car on the Website. This worked for me although 2 attempts to have a security code sent to our car were required.

fireball08 said:
I can't understand why they would release a new interface, leave one checkbox and not expect people to explore this????
Very poor interface design! BMW has not demonstrated much software development expertise.
 
symonray said:
Do you now have access to the remote cockpit functions for your vehicle on the Connected Drive website?

The web site seems to be nothing more than a sales pitch for renewing services. No status from the car, no remote controls, and not even a way to find where I parked it. Since my account on ConnectedDrive is only a few days old, I have no idea what the web portal used to look like before today's lame page.

My guess is that BMW has decided to embrace the post-PC era (https://en.wikipedia.org/wiki/Post-PC_era) with their new portal, and focus on mobile apps and not the web.....
 
Long-time listener, first-time caller here.

I had pretty much the same problem as Art. I saw the new version of the connected drive website, noticed the lack of car status, and clicked the green checkmark. What could go wrong, it's green and it's a checkmark? I did not expect that that was the connected drive self-destruct button. (After all, I need to confirm just logging out of the website.)

So my i3 gets removed from connected drive, no in-car services and no remote status info either. I called BMW customer service this past Wednesday to be told for 36 hours that their system was down and to call back later. When I finally called in with system working on their end ,I got a sympathetic and helpful rep who, despite those attributes, couldn't solve my problem at the time. She did, however, escalate my problem to IT and issue my a trouble ticket number and -- fast-forward to today -- my car shows up again on the connected drive website with my subscribed services. Yay! Still no car status on the website anymore, but I think other functionality now restored.

So if anyone else has clicked a friendly-looking checkmark and instead activated self-destruct sequence, I'd call customer service. They seem to be able to ultimately resolve the problem. I would definitely say that the website violates generally accepted best-practices of user interface design of allowing non-reversible catastrophic inputs! Not even a tooltip saying "Don't press this button!"

I also noticed that user gt1 had problems with his/her automated system from late March thru mid-April. I suspect that s/he was probably using Home Assistant or OpenHAB. BMW USA server had either intentionally or accidentally blocked oauth access from these systems for that period. I had the same issue. This problem has resolved itself, but problems that go away by themselves can also come back on their own . . .

So as far as accessing the car from a desktop computer, what can be done?

Well, there's a project on github https://github.com/m1n3rva/bimmer_connected that might be helpful. It does require some command-line-fu and comfort with python. There's documentation on github to get you started with installation and use. With the demo program, you can type (from appropriate directory): "bimmerconnected status <username> <password> <region>" where region is north_america, china, rest_of_world. This will spew a stream of info about all your connecteddrive vehicles. The program has help to get other command arguments for data and to send commands to the car.

I've also written a very rudimentary text-mode interactive interface to the bimmerconnected library. I'm not sure what's the easiest way to share that here . . . if it's just pasting it into a post, I'll be happy to.
 
robthebold said:
I've also written a very rudimentary text-mode interactive interface to the bimmerconnected library. I'm not sure what's the easiest way to share that here . . . if it's just pasting it into a post, I'll be happy to.
I would be interested in using your CLI on or porting it to macOS. Pasting it into a post might be the easiest way to share your work. Thanks!
 
Suddenly my i3 reappeared. Thanks Alohart. Clearly a server-side issue.

If they want people to pay for a service, IMHO they should support it.
 
I just called their helpdesk and they told me that the web site will no longer show the charging and expected completion times for the i3. Also you can no longer send a street address to the car for navigation from the web site. The web site seems to have no purpose other than advertising BMW services that you can't use from everything but a phone.
 
robthebold said:
I also noticed that user gt1 had problems with his/her automated system from late March thru mid-April. I suspect that s/he was probably using Home Assistant or OpenHAB. BMW USA server had either intentionally or accidentally blocked oauth access from these systems for that period. I had the same issue. This problem has resolved itself, but problems that go away by themselves can also come back on their own . . .

Are you able to pull the Bat. Kapa. Max. value from the US server? I use openHAB and still not getting it.
 
gt1 said:
Are you able to pull the Bat. Kapa. Max. value from the US server? I use openHAB and still not getting it.

No, I don't find it in the raw JSON data pulled off the server . . . :(
 
Yes, same here. I asked in case I missed something. It is very disappointing, Kappa Max was the monst useful parameter for monitoring the battery data. After all the effort to get it running, I only got about month worth of data.
 
Remote precondition is failing for last 4 days. Tried deleting and adding the car again but no luck.

It's 100f hot... Bmw sucks
 
Yeah, it’s not working for me either, and it hasn’t for several weeks at least. And it’s very hot and muggy here in central Ohio.

They expect people to pay money for this service?
 
Due to a lack of support for my preferred mobile devices and the regression of the BMW connected website, I've written my own super-basic terminal interface to the connected drive system. It's taken a while, but I've been trying to get my "motorlaunch" code to at least the alpha stage so enthusiasts could give it a try, and I think it's sorta there. I've written a _very_ basic text mode interface to the bimmer_connected python library available on github. I'm also working on a more user-friendly GUI for mainstream users, but that's not ready yet.

Obviously, it requires that you install that python library I referred to above^^^^. Your first step to getting this working is to follow the installation for the library at https://github.com/m1n3rva/bimmer_connected/blob/master/README.rst This is not my work. Github member m1n3rva did all the heavy lifting. This should work on any device -- computer or mobile -- that supports python and has a text-mode interface available. Once you install that library, you have command-line access to you connected drive account. It's a little cumbersome with all the typing, but it works. That command line interface can do a lot, but typing your vin and password and stuff over and over is a big pain.

So I've written an interactive terminal-mode interface to this library. I call it "motorlaunch". I'm posting the code below. It depends on already having the "bimmer_connected" library above installed. It needs internet access, and of course you need to have a connected drive account and a supported vehicle.

Anyway, here is the python code for an interactive terminal interface to connected drive. There is a bunch of documentation in the code itself, so have a look there. I am _not_ 100% sure that posting this with "code" tags will work, so this is the test . . .

Code:
#!/usr/bin/python3
""" 
    Text mode interactive interface to bimmerconnected library

    Copyright (C) 2019  Robert Bruce

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
    
    Disclaimer: not endorsed or affiliated with BMW or the authors of bimmer_connected
    
    Support and encourage development:
    
    buy me coffee or electricity: paypal.me/zeppelinware
    and/or
    contribute: bug reports
    and/or
    contribute: translations/localizations
    and/or
    contribute: code

"""



import argparse
import logging
import json
import os
import time
import configparser
import getpass
from pathlib import Path
from bimmer_connected.account import ConnectedDriveAccount
from bimmer_connected.country_selector import get_region_from_name, valid_regions, Regions
from bimmer_connected.vehicle import VehicleViewDirection

def main() -> None:
    """Main function."""
    
    print()
    print('Motorlaunch, Copyright (C) 2019 Robert Bruce.')
    print('A text mode interface to the bimmer_connected library,')
    print('this program provides access to services and information')
    print('from BMW ConnectedDrive.')
    print('This program is not endorsed or affiliated with BMW')
    print('or the developers of the bimmer_connected library.')
    print('Use of BMW services is the user\'s responsibility.')
    print()
    print('This program comes with ABSOLUTELY NO WARRANTY')
    print('This is free software,')
    print('and you are welcome to redistribute it')
    print('under certain conditions')
    print('For more info on license and warranty,')
    print('see https://www.gnu.org/licenses/gpl-3.0-standalone.html')
    print()
    print('This is alpha-quality software, and doesn\'t even have a')
    print('version number yet. Many inputs are not checked for proper')
    print('values. Incorrect entries will probably cause the program')
    print('to terminate. Errors returned by the BMW server whether yours')
    print('or theirs will usually also crash this program.')
    print('If your config file gets munged up and stuff won\'t work,')
    print('delete .motorlaunch/motorlaunch.ini from your home')
    print('directory and start over.')
    print()
    print('Not all features are available in all regions. All features')
    print('are subject to availabilty of BMW servers via the internet.')
    print('This program has not been tested anywhere outside the USA,')
    print('although the underlying library has been used worldwide.')
    print('Your mileage may vary.')
    print()
    print('All units are SI, this means l for volume and km for distance.')
    print()
    print('Your password is _not_ saved in the configuration.')
    print('To wipe your username and VIN from this computer,')
    print('simply delete \".motorlaunch/motorlaunch.ini\"')
    print('from your home directory with a method commensurate with')
    print('your security needs.')
    print()

    
    password = ''
    lat = 0.0
    long = 0.0
    home = str(Path.home())
    configdir = home+'/.motorlaunch'
    configfilename = configdir+'/motorlaunch.ini'
    
    config = configparser.ConfigParser()
    config['credentials'] = {'username': ''}
    config['region'] = {'region': 'nowhere'}
    config['language'] = {'language':'en_us'}
    config['vehicles'] = {'currentvin': ''}
    
    #Create config file directory if it doesn't already exist
    if not os.path.exists(configdir):
        os.mkdir(configdir)
    
    config.read(configfilename);
    #print('config sections {}'.format(config.sections()))
    username = config.get("credentials", "username")
    regionname = config.get('region','region')
    vin = config.get('vehicles','currentvin')
    
    print('Current username {}'.format(username))
    print('Selected region {}'.format(regionname))
    print('Selected VIN {}'.format(vin))
    print()
    
    if username and regionname:
        password = getpass.getpass(prompt="Please enter your password: ")
        account = ConnectedDriveAccount(username, password, get_region_from_name(regionname))
        account.update_vehicle_states()
        print()
        print('Found {} vehicles: {}'.format(len(account.vehicles),','.join([v.name for v in account.vehicles])))
        if vin:
            vehicle = account.get_vehicle(vin)
        else:
            for vehicle in account.vehicles:
                print('VIN: {}'.format(vehicle.vin))
                
        quick_status(vehicle)    
  
    else:
        print('Notice: Configuration file is empty.')
        print('Please set up your username and reqion')
        print('using functions 0 and 1, then')
        print('quit and restart motorlaunch.')
  
    printmenu()

    choice=input("Type an option ")
    print()
    while choice != 'q':
        print(choice)
        if choice == '0':
            print('Current Region is {}'.format(regionname))
            print('Select Region From {}'.format((valid_regions())))
            regionname=input("Type region ")
            for region_name, region in Regions.__members__.items():
                if regionname.lower() == region_name.lower():
                    print('Region {}'.format(region))
                    config['region']['region'] = region_name.lower()
        if choice == '1':
            print('Current username: {}'.format(username))
            username = input("Type your new username ")
            config['credentials']['username'] = username
        if choice == '2':
            print('Not implemented yet.')
        if choice == '3':
            if vehicle:
                print('Current vehicle {}'.format(vehicle.vin))
                vins=[]
                index = 1
                for vehicle in account.vehicles:
                    print('{} VIN: {} {}'.format(index,vehicle.vin,vehicle.name))
                    vins.append(vehicle.vin)
                    index += 1
                index=int(input('Enter number of vehicle to select. '))
                vehicle = account.get_vehicle(vins[index-1])
                config['vehicles']['currentvin'] = vehicle.vin
                print('Current vehicle is now {} {}'.format(vehicle.vin,vehicle.name))
                quick_status(vehicle)
            else:
                print('No vehicle selected.')
        if choice == '4':
            if vehicle:
                print('vehicle status: ')
                print('VIN: {}'.format(vehicle.vin))
                print('Doors:')
                print('  {}'.format(vehicle.state.attributes["doorLockState"]))
                print('    Driver Front: {}'.format(vehicle.state.attributes["doorDriverFront"]))
                print('    Driver Rear: {}'.format(vehicle.state.attributes["doorDriverRear"]))
                print('    Passenger Front: {}'.format(vehicle.state.attributes["doorPassengerFront"]))
                print('    Passenger Rear: {}'.format(vehicle.state.attributes["doorPassengerRear"]))
                print('Hood: {}'.format(vehicle.state.attributes["hood"]))
                print('Trunk: {}'.format(vehicle.state.attributes["trunk"]))
                print('Windows:')
                print('    Driver Front: {}'.format(vehicle.state.attributes["windowDriverFront"]))
                print('    Driver Rear: {}'.format(vehicle.state.attributes["windowDriverRear"]))
                print('    Passenger Front: {}'.format(vehicle.state.attributes["windowPassengerFront"]))
                print('    Passenger Rear: {}'.format(vehicle.state.attributes["windowPassengerRear"]))
                print('    Sunroof: {}'.format(vehicle.state.attributes["sunroof"]))
                print('    Rear: {}'.format(vehicle.state.attributes["rearWindow"]))
                print('Fuel:')
                print('    Remaining Fuel: {}/{}'.format(vehicle.state.attributes["remainingFuel"],vehicle.state.attributes["maxFuel"]))
                print('    Fuel Range: {}'.format(vehicle.state.attributes["remainingRangeFuel"]))
                print('Battery:')
                print('    Percent Remaining: {}'.format(vehicle.state.attributes["chargingLevelHv"]))
                print('    Electric Range: {}/{}'.format(vehicle.state.attributes["remainingRangeElectric"],vehicle.state.attributes["maxRangeElectric"]))
                print('')
                
            else:
                print('No vehicle selected.')
        if choice == '5':
            light_flash(vehicle)
        if choice == '6':
            sound_horn(vehicle)
        if choice == '7':
            if vehicle and vehicle.state.is_vehicle_tracking_enabled:
                print('Latitude {}, Longitude {}'.format(vehicle.state.gps_position[0],vehicle.state.gps_position[1]))
            else:
                print('I\'m sorry Dave, I\'m afraid I can\'t do that.')
        if choice == '8':
            vehicle.remote_services.trigger_remote_door_lock()
        if choice == '9':
            vehicle.remote_services.trigger_remote_door_unlock()
        if choice == 'a':
            vehicle.remote_services.trigger_remote_air_conditioning()
        if choice == 'o':
            password = input("Please enter your password: ")
            account = ConnectedDriveAccount(username, password, get_region_from_name(regionname))
            account.update_vehicle_states()
            print('Found {} vehicles: {}'.format(len(account.vehicles),','.join([v.name for v in account.vehicles])))
            for vehicle in account.vehicles:
                print('VIN: {}'.format(vehicle.vin))
                print('mileage: {}'.format(vehicle.state.mileage))
                print('Doors: {}'.format(vehicle.state.attributes["doorLockState"]))
                print('Position: {}'.format(vehicle.state.attributes["position"]["status"]))
            if vin:
                vehicle = account.get_vehicle(vin)
        if choice =='r':
            if vehicle:
                print('Raw status info (You asked for it):')
                print('VIN: {}'.format(vehicle.vin))
                print(json.dumps(vehicle.state.attributes, indent=4))
            else:
                print('No vehicle selected.')

        if choice =='i':
            if vehicle:
                print('Inquire a single status field:')
                field=input('Carefully type exact field name: ')
                print('VIN: {}'.format(vehicle.vin))
                print(json.dumps(vehicle.state.attributes[field], indent=4))
            else:
                print('No vehicle selected.')
           
        printmenu()
        choice=input("Type an option ")
        print()
        
    with open(configfilename, 'w') as configfile:
        config.write(configfile)

def light_flash(vehicle) -> None:
    """Trigger the vehicle to flash its lights."""
    status = vehicle.remote_services.trigger_remote_light_flash()
    print(status.state)

def sound_horn(vehicle) -> None:
    """Trigger the vehicle to sound its horn."""
    vehicle.remote_services.trigger_remote_horn()
    
def quick_status(vehicle) -> None:
    print('vehicle status: ')
    print('VIN: {}'.format(vehicle.vin))
    if not vehicle.has_check_control_messages:
        print('No check control messages')
    if vehicle.state.all_lids_closed and vehicle.state.all_windows_closed and (vehicle.state.door_lock_state.name in ['LOCKED','SECURED']) and vehicle.state.are_all_cbs_ok:
        print('Everything\'s OK')
    else:
        print('Something\'s open or unlocked!')
        if not vehicle.state.all_lids_closed:
            print('Following lids open: {}'.format(','.join([lid.name for lid in vehicle.state.open_lids])))
        if not vehicle.state.all_windows_closed:
            print('Following {} windows open: {}'.format(len(vehicle.state.open_windows),','.join([lid.name for lid in vehicle.state.open_windows])))
        if not vehicle.state.door_lock_state in ['LOCKED','SECURED']:
            print('Lock state {}'.format(vehicle.state.door_lock_state))

    
def printmenu() -> None:
    print()
    print('0. Select region')
    print('1. Enter Username')
    print('2. Enter my location')
    print('3. Select vehicle')
    print('4. Get status')
    print('5. Flash Lights')
    print('6. Honk horn')
    print('7. Get position')
    print('8. Lock doors')
    print('9. Unlock doors')
    print('a. Climatize (air condition or ventilate)')
    print('o. Open a Different Account')
    print('r. Spew raw status')
    print('i. Inquire status item (expert function)')
    print('q. Quit');
    print()


if __name__ == '__main__':
    main()

< begin plain-text code>

#!/usr/bin/python3
"""
Text mode interactive interface to bimmerconnected library

Copyright (C) 2019 Robert Bruce

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.

Disclaimer: not endorsed or affiliated with BMW or the authors of bimmer_connected

Support and encourage development:

buy me coffee or electricity: paypal.me/zeppelinware
and/or
contribute: bug reports
and/or
contribute: translations/localizations
and/or
contribute: code

"""



import argparse
import logging
import json
import os
import time
import configparser
import getpass
from pathlib import Path
from bimmer_connected.account import ConnectedDriveAccount
from bimmer_connected.country_selector import get_region_from_name, valid_regions, Regions
from bimmer_connected.vehicle import VehicleViewDirection

def main() -> None:
"""Main function."""

print()
print('Motorlaunch, Copyright (C) 2019 Robert Bruce.')
print('A text mode interface to the bimmer_connected library,')
print('this program provides access to services and information')
print('from BMW ConnectedDrive.')
print('This program is not endorsed or affiliated with BMW')
print('or the developers of the bimmer_connected library.')
print('Use of BMW services is the user\'s responsibility.')
print()
print('This program comes with ABSOLUTELY NO WARRANTY')
print('This is free software,')
print('and you are welcome to redistribute it')
print('under certain conditions')
print('For more info on license and warranty,')
print('see https://www.gnu.org/licenses/gpl-3.0-standalone.html')
print()
print('This is alpha-quality software, and doesn\'t even have a')
print('version number yet. Many inputs are not checked for proper')
print('values. Incorrect entries will probably cause the program')
print('to terminate. Errors returned by the BMW server whether yours')
print('or theirs will usually also crash this program.')
print('If your config file gets munged up and stuff won\'t work,')
print('delete .motorlaunch/motorlaunch.ini from your home')
print('directory and start over.')
print()
print('Not all features are available in all regions. All features')
print('are subject to availabilty of BMW servers via the internet.')
print('This program has not been tested anywhere outside the USA,')
print('although the underlying library has been used worldwide.')
print('Your mileage may vary.')
print()
print('All units are SI, this means l for volume and km for distance.')
print()
print('Your password is _not_ saved in the configuration.')
print('To wipe your username and VIN from this computer,')
print('simply delete \".motorlaunch/motorlaunch.ini\"')
print('from your home directory with a method commensurate with')
print('your security needs.')
print()


password = ''
lat = 0.0
long = 0.0
home = str(Path.home())
configdir = home+'/.motorlaunch'
configfilename = configdir+'/motorlaunch.ini'

config = configparser.ConfigParser()
config['credentials'] = {'username': ''}
config['region'] = {'region': 'nowhere'}
config['language'] = {'language':'en_us'}
config['vehicles'] = {'currentvin': ''}

#Create config file directory if it doesn't already exist
if not os.path.exists(configdir):
os.mkdir(configdir)

config.read(configfilename);
#print('config sections {}'.format(config.sections()))
username = config.get("credentials", "username")
regionname = config.get('region','region')
vin = config.get('vehicles','currentvin')

print('Current username {}'.format(username))
print('Selected region {}'.format(regionname))
print('Selected VIN {}'.format(vin))
print()

if username and regionname:
password = getpass.getpass(prompt="Please enter your password: ")
account = ConnectedDriveAccount(username, password, get_region_from_name(regionname))
account.update_vehicle_states()
print()
print('Found {} vehicles: {}'.format(len(account.vehicles),','.join([v.name for v in account.vehicles])))
if vin:
vehicle = account.get_vehicle(vin)
else:
for vehicle in account.vehicles:
print('VIN: {}'.format(vehicle.vin))

quick_status(vehicle)

else:
print('Notice: Configuration file is empty.')
print('Please set up your username and reqion')
print('using functions 0 and 1, then')
print('quit and restart motorlaunch.')

printmenu()

choice=input("Type an option ")
print()
while choice != 'q':
print(choice)
if choice == '0':
print('Current Region is {}'.format(regionname))
print('Select Region From {}'.format((valid_regions())))
regionname=input("Type region ")
for region_name, region in Regions.__members__.items():
if regionname.lower() == region_name.lower():
print('Region {}'.format(region))
config['region']['region'] = region_name.lower()
if choice == '1':
print('Current username: {}'.format(username))
username = input("Type your new username ")
config['credentials']['username'] = username
if choice == '2':
print('Not implemented yet.')
if choice == '3':
if vehicle:
print('Current vehicle {}'.format(vehicle.vin))
vins=[]
index = 1
for vehicle in account.vehicles:
print('{} VIN: {} {}'.format(index,vehicle.vin,vehicle.name))
vins.append(vehicle.vin)
index += 1
index=int(input('Enter number of vehicle to select. '))
vehicle = account.get_vehicle(vins[index-1])
config['vehicles']['currentvin'] = vehicle.vin
print('Current vehicle is now {} {}'.format(vehicle.vin,vehicle.name))
quick_status(vehicle)
else:
print('No vehicle selected.')
if choice == '4':
if vehicle:
print('vehicle status: ')
print('VIN: {}'.format(vehicle.vin))
print('Doors:')
print(' {}'.format(vehicle.state.attributes["doorLockState"]))
print(' Driver Front: {}'.format(vehicle.state.attributes["doorDriverFront"]))
print(' Driver Rear: {}'.format(vehicle.state.attributes["doorDriverRear"]))
print(' Passenger Front: {}'.format(vehicle.state.attributes["doorPassengerFront"]))
print(' Passenger Rear: {}'.format(vehicle.state.attributes["doorPassengerRear"]))
print('Hood: {}'.format(vehicle.state.attributes["hood"]))
print('Trunk: {}'.format(vehicle.state.attributes["trunk"]))
print('Windows:')
print(' Driver Front: {}'.format(vehicle.state.attributes["windowDriverFront"]))
print(' Driver Rear: {}'.format(vehicle.state.attributes["windowDriverRear"]))
print(' Passenger Front: {}'.format(vehicle.state.attributes["windowPassengerFront"]))
print(' Passenger Rear: {}'.format(vehicle.state.attributes["windowPassengerRear"]))
print(' Sunroof: {}'.format(vehicle.state.attributes["sunroof"]))
print(' Rear: {}'.format(vehicle.state.attributes["rearWindow"]))
print('Fuel:')
print(' Remaining Fuel: {}/{}'.format(vehicle.state.attributes["remainingFuel"],vehicle.state.attributes["maxFuel"]))
print(' Fuel Range: {}'.format(vehicle.state.attributes["remainingRangeFuel"]))
print('Battery:')
print(' Percent Remaining: {}'.format(vehicle.state.attributes["chargingLevelHv"]))
print(' Electric Range: {}/{}'.format(vehicle.state.attributes["remainingRangeElectric"],vehicle.state.attributes["maxRangeElectric"]))
print('')

else:
print('No vehicle selected.')
if choice == '5':
light_flash(vehicle)
if choice == '6':
sound_horn(vehicle)
if choice == '7':
if vehicle and vehicle.state.is_vehicle_tracking_enabled:
print('Latitude {}, Longitude {}'.format(vehicle.state.gps_position[0],vehicle.state.gps_position[1]))
else:
print('I\'m sorry Dave, I\'m afraid I can\'t do that.')
if choice == '8':
vehicle.remote_services.trigger_remote_door_lock()
if choice == '9':
vehicle.remote_services.trigger_remote_door_unlock()
if choice == 'a':
vehicle.remote_services.trigger_remote_air_conditioning()
if choice == 'o':
password = input("Please enter your password: ")
account = ConnectedDriveAccount(username, password, get_region_from_name(regionname))
account.update_vehicle_states()
print('Found {} vehicles: {}'.format(len(account.vehicles),','.join([v.name for v in account.vehicles])))
for vehicle in account.vehicles:
print('VIN: {}'.format(vehicle.vin))
print('mileage: {}'.format(vehicle.state.mileage))
print('Doors: {}'.format(vehicle.state.attributes["doorLockState"]))
print('Position: {}'.format(vehicle.state.attributes["position"]["status"]))
if vin:
vehicle = account.get_vehicle(vin)
if choice =='r':
if vehicle:
print('Raw status info (You asked for it):')
print('VIN: {}'.format(vehicle.vin))
print(json.dumps(vehicle.state.attributes, indent=4))
else:
print('No vehicle selected.')

if choice =='i':
if vehicle:
print('Inquire a single status field:')
field=input('Carefully type exact field name: ')
print('VIN: {}'.format(vehicle.vin))
print(json.dumps(vehicle.state.attributes[field], indent=4))
else:
print('No vehicle selected.')

printmenu()
choice=input("Type an option ")
print()

with open(configfilename, 'w') as configfile:
config.write(configfile)

def light_flash(vehicle) -> None:
"""Trigger the vehicle to flash its lights."""
status = vehicle.remote_services.trigger_remote_light_flash()
print(status.state)

def sound_horn(vehicle) -> None:
"""Trigger the vehicle to sound its horn."""
vehicle.remote_services.trigger_remote_horn()

def quick_status(vehicle) -> None:
print('vehicle status: ')
print('VIN: {}'.format(vehicle.vin))
if not vehicle.has_check_control_messages:
print('No check control messages')
if vehicle.state.all_lids_closed and vehicle.state.all_windows_closed and (vehicle.state.door_lock_state.name in ['LOCKED','SECURED']) and vehicle.state.are_all_cbs_ok:
print('Everything\'s OK')
else:
print('Something\'s open or unlocked!')
if not vehicle.state.all_lids_closed:
print('Following lids open: {}'.format(','.join([lid.name for lid in vehicle.state.open_lids])))
if not vehicle.state.all_windows_closed:
print('Following {} windows open: {}'.format(len(vehicle.state.open_windows),','.join([lid.name for lid in vehicle.state.open_windows])))
if not vehicle.state.door_lock_state in ['LOCKED','SECURED']:
print('Lock state {}'.format(vehicle.state.door_lock_state))


def printmenu() -> None:
print()
print('0. Select region')
print('1. Enter Username')
print('2. Enter my location')
print('3. Select vehicle')
print('4. Get status')
print('5. Flash Lights')
print('6. Honk horn')
print('7. Get position')
print('8. Lock doors')
print('9. Unlock doors')
print('a. Climatize (air condition or ventilate)')
print('o. Open a Different Account')
print('r. Spew raw status')
print('i. Inquire status item (expert function)')
print('q. Quit');
print()


if __name__ == '__main__':
main()

<end plain-text-code>

If you can't or don't want to do the PIP install of the bimmerconnected library, you can just download the source files from github and put them in a subdirectory from where this script resides called "bimmer_connected".
 
So if you want to try my interactive program above, first make sure you can use the bimmer_connected library it depends on. If that CLI works, then my interactive terminal program should work as well.

BTW, it will climatize my i3,. Although the function may timeout, it still turns on the A/C.
 
My son very elegantly put it this way. The connected drive is a$$. BMW should be ashamed to put this out or not yet redeveloped it.
 
robthebold said:
Anyway, here is the python code for an interactive terminal interface to connected drive. There is a bunch of documentation in the code itself, so have a look there. I am _not_ 100% sure that posting this with "code" tags will work, so this is the test . . .

The contents of the "code" block is missing line terminators and indents when I view this post, but strangely appears to display with what looks like functional indents and line terminators in the message editor window when I reply!

Since we all know how cranky Python gets over indents, is there a way that you can post this file to Github or another site for sharing?

I have digging into the bimmer_connected library on my to-do list when I get a round tuit, so I can't personally test this code at the moment.....
 
vreihen said:
robthebold said:
Anyway, here is the python code for an interactive terminal interface to connected drive. There is a bunch of documentation in the code itself, so have a look there. I am _not_ 100% sure that posting this with "code" tags will work, so this is the test . . .

The contents of the "code" block is missing line terminators and indents when I view this post, but strangely appears to display with what looks like functional indents and line terminators in the message editor window when I reply!

Since we all know how cranky Python gets over indents, is there a way that you can post this file to Github or another site for sharing?

I have digging into the bimmer_connected library on my to-do list when I get a round tuit, so I can't personally test this code at the moment.....

I was concerned that neither method I used would work given that python absolutely depends on indentation.

Let me see what I can do to make this usable . . .
 
OK, I've created a git repository for motorlaunch.

https://github.com/robthebold/motorlaunch_cli

As I mentioned above, this script depends on the bimmer_connected library for backend functionality.

Fun fact: since there's no Sailfish OS or Ubuntu Touch version of the connected drive app, I've been using this on my "Brand X" phones.
 
I've been unable to "climatize now" through the mobile app for over 2 months now. 100% failure rate. The other functions (that I have never ever needed) like lock/unlock work as they should.

Contacted BMW about it 3 different ways and no solution. It's only the hottest part of summer. :x
 
When I call the climatize function from my python script it does timeout, but I don't do anything other than report that happened. And even though it times out, the A/C does start and cools off the car. So I suspect that this is a problem with the BMW server not responding in a timely manner, and perhaps the connecteddrive app is being too fussy about it. If your mobile device supports python, you might want to try the script I wrote -- or if you're a little familiar with python you could adapt it to create a climatize-now script for yourself.
 
Back
Top