def send_poi(args) -> None: """Send Point Of Interest to car.""" account = ConnectedDriveAccount(args.username, args.password, get_region_from_name(args.region)) vehicle = account.get_vehicle(args.vin) poi = PointOfInterest(args.latitude, args.longitude, name=args.name, street=args.street, city=args.city, postalCode=args.postalcode, country=args.country) vehicle.send_poi(poi)
def test_parse_gcj02_position(self): """Test conversion of GCJ02 to WGS84 for china.""" account = get_mocked_account(get_region_from_name("china")) status = VehicleStatus( account, { "properties": { "vehicleLocation": { "address": { "formatted": "some_formatted_address" }, "coordinates": { "latitude": 39.83492, "longitude": 116.23221 }, "heading": 123, }, "lastUpdatedAt": "2021-11-14T20:20:21Z", }, "status": { "fuelIndicators": [], "lastUpdatedAt": "2021-11-14T20:20:21Z", }, }, ) self.assertTupleEqual((39.8337, 116.22617), (round( status.gps_position[0], 5), round(status.gps_position[1], 5)))
def get_status(args) -> None: """Get the vehicle status.""" if args.json: for handler in logging.root.handlers[:]: logging.root.removeHandler(handler) account = ConnectedDriveAccount(args.username, args.password, get_region_from_name(args.region)) if args.lat and args.lng: for vehicle in account.vehicles: vehicle.set_observer_position(args.lat, args.lng) account.update_vehicle_states() if args.json: print(to_json(account.vehicles)) else: 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.status.mileage)) print('Vehicle data:') print(to_json(vehicle, indent=4))
def send_poi_from_address(args) -> None: """Create Point of Interest from OSM Nominatim and send to car.""" account = ConnectedDriveAccount(args.username, args.password, get_region_from_name(args.region)) vehicle = account.get_vehicle(args.vin) address = [(str(' '.join(args.address)))] try: response = requests.get("https://nominatim.openstreetmap.org", params={ "q": address, "format": "json", "addressdetails": 1, "limit": 1 }).json()[0] except IndexError: print('\nAddress not found') sys.exit(1) address = response.get("address", {}) city = address.get("city") town = address.get("town") poi_data = dict( lat=response["lat"], lon=response["lon"], name=args.name, street=address.get("road"), city=town if city is None and town is not None else None, postal_code=address.get("postcode"), country=address.get("country") ) vehicle.remote_services.trigger_send_poi(poi_data)
def __init__( self, hass: HomeAssistant, *, username: str, password: str, region: str, read_only: bool = False, ) -> None: """Initialize account-wide BMW data updater.""" # Storing username & password in coordinator is needed until a new library version # that does not do blocking IO on init. self._username = username self._password = password self._region = get_region_from_name(region) self.account = None self.read_only = read_only super().__init__( hass, _LOGGER, name=f"{DOMAIN}-{username}", update_interval=SCAN_INTERVAL, )
def send_message(args) -> None: """Send a message to car.""" account = ConnectedDriveAccount(args.username, args.password, get_region_from_name(args.region)) vehicle = account.get_vehicle(args.vin) msg_data = dict(text=args.text, subject=args.subject) vehicle.remote_services.trigger_send_message(msg_data)
def image(args) -> None: """Download a rendered image of the vehicle.""" account = ConnectedDriveAccount(args.username, args.password, get_region_from_name(args.region)) vehicle = account.get_vehicle(args.vin) with open('image.png', 'wb') as output_file: image_data = vehicle.get_vehicle_image(400, 400, VehicleViewDirection.FRONT) output_file.write(image_data) print('vehicle image saved to image.png')
def __init__(self, username: str, password: str, region_str: str, name: str, read_only) -> None: """Initialize account.""" region = get_region_from_name(region_str) self.read_only = read_only self.account = ConnectedDriveAccount(username, password, region) self.name = name self._update_listeners = []
def fingerprint(args) -> None: """Save the vehicle fingerprint.""" time_dir = Path.home() / 'vehicle_fingerprint' / time.strftime( "%Y-%m-%d_%H-%M-%S") time_dir.mkdir(parents=True) account = ConnectedDriveAccount(args.username, args.password, get_region_from_name(args.region), log_responses=time_dir) if args.lat and args.lng: for vehicle in account.vehicles: vehicle.set_observer_position(args.lat, args.lng) # doesn't work anymore # account.update_vehicle_states() # Patching in new My BMW endpoints for fingerprinting server_url = get_server_url(get_region_from_name(args.region)) for vehicle in account.vehicles: if vehicle.drive_train in HV_BATTERY_DRIVE_TRAINS: print("Getting 'charging-sessions' for {}".format(vehicle.vin)) account.send_request( "https://{}/eadrax-chs/v1/charging-sessions".format( server_url), params={ "vin": vehicle.vin, "maxResults": 40, "include_date_picker": "true" }, logfilename="charging-sessions") print("Getting 'charging-statistics' for {}".format(vehicle.vin)) account.send_request( "https://{}/eadrax-chs/v1/charging-statistics".format( server_url), params={ "vin": vehicle.vin, "currentDate": datetime.utcnow().isoformat() }, logfilename="charging-statistics") print('fingerprint of the vehicles written to {}'.format(time_dir))
def get_status(args) -> None: """Get the vehicle status.""" _LOGGER = logging.getLogger(__name__) for rtime in [1, 1, 1, 5, 30, 60, None]: try: account = ConnectedDriveAccount(args.username, args.password, get_region_from_name(args.region)) except IOError as e: if rtime is not None: _LOGGER.debug('Request failed. Retry in {} seconds.'.format(rtime)) time.sleep(rtime) continue else: raise break if args.lat and args.lng: for vehicle in account.vehicles: vehicle.set_observer_position(args.lat, args.lng) for rtime in [1, 1, 1, 5, 30, 60, None]: try: account.update_vehicle_states() except IOError as e: if rtime is not None: _LOGGER.debug('Request failed. Retry in {} seconds.'.format(rtime)) time.sleep(rtime) continue else: raise break dict_resp = [] for vehicle in account.vehicles: for rtime in [1, 1, 1, 5, 30, 60, None]: try: vehicle.last_trip.update_data() except IOError as e: if rtime is not None: _LOGGER.debug('Request failed. Retry in {} seconds.'.format(rtime)) time.sleep(rtime) continue else: raise break dict_resp.append({ 'vin': vehicle.vin, 'mileage': vehicle.state.mileage, 'properties': vehicle.attributes, 'status': vehicle.state.attributes, 'last_trip': vehicle.last_trip.attributes }) print(json.dumps(dict_resp, indent=4))
def light_flash(args) -> None: """Trigger the vehicle to flash its lights.""" account = ConnectedDriveAccount(args.username, args.password, get_region_from_name(args.region)) vehicle = account.get_vehicle(args.vin) if not vehicle: valid_vins = ", ".join(v.vin for v in account.vehicles) print('Error: Could not find vehicle for VIN "{}". Valid VINs are: {}'.format(args.vin, valid_vins)) return status = vehicle.remote_services.trigger_remote_light_flash() print(status.state)
def test_invalid_password_china(self): """Test parsing the results of an invalid password.""" with requests_mock.Mocker(adapter=get_base_adapter()) as mock: mock.post( "/eadrax-coas/v1/login/pwd", json=load_response(RESPONSE_DIR / "auth" / "auth_cn_login_error.json"), status_code=422, ) with self.assertRaises(HTTPError): ConnectedDriveAccount(TEST_USERNAME, TEST_PASSWORD, get_region_from_name("china"))
def __init__(self, username: str, password: str, region_str: str, name: str) -> None: """Constructor.""" from bimmer_connected.account import ConnectedDriveAccount from bimmer_connected.country_selector import get_region_from_name region = get_region_from_name(region_str) self.account = ConnectedDriveAccount(username, password, region) self.name = name self._update_listeners = []
def get_vehicle_rangemap(args) -> None: """Get a set of lat/lon points defining a polygon bounding vehicle range""" account = ConnectedDriveAccount(args.username, args.password, get_region_from_name(args.region)) vehicle = account.get_vehicle(args.vin) if not vehicle: valid_vins = ", ".join(v.vin for v in account.vehicles) print('Error: Could not find vehicle for VIN "{}". Valid VINs are: {}'. format(args.vin, valid_vins)) return print(json.dumps(vehicle.get_vehicle_rangemap(), indent=4))
def get_all_trips(args) -> None: """Downlad statistics of all trips""" account = ConnectedDriveAccount(args.username, args.password, get_region_from_name(args.region)) vehicle = account.get_vehicle(args.vin) if not vehicle: valid_vins = ", ".join(v.vin for v in account.vehicles) print('Error: Could not find vehicle for VIN "{}". Valid VINs are: {}'. format(args.vin, valid_vins)) return print(json.dumps(vehicle.get_vehicle_alltrips(), indent=4))
def get_vehicle_charging_profile(args) -> None: """Download one-time and weekly charging schedules and settings""" account = ConnectedDriveAccount(args.username, args.password, get_region_from_name(args.region)) vehicle = account.get_vehicle(args.vin) if not vehicle: valid_vins = ", ".join(v.vin for v in account.vehicles) print('Error: Could not find vehicle for VIN "{}". Valid VINs are: {}'. format(args.vin, valid_vins)) return print(json.dumps(vehicle.get_vehicle_charging_profile(), indent=4))
def get_vehicle_destinations(args) -> None: """Shows the destinations you've previously sent to the car.""" account = ConnectedDriveAccount(args.username, args.password, get_region_from_name(args.region)) vehicle = account.get_vehicle(args.vin) if not vehicle: valid_vins = ", ".join(v.vin for v in account.vehicles) print('Error: Could not find vehicle for VIN "{}". Valid VINs are: {}'. format(args.vin, valid_vins)) return print(json.dumps(vehicle.get_vehicle_destinations(), indent=4))
def image(args) -> None: """Download a rendered image of the vehicle.""" account = ConnectedDriveAccount(args.username, args.password, get_region_from_name(args.region)) vehicle = account.get_vehicle(args.vin) for viewdirection in VehicleViewDirection: filename = str(viewdirection.name).lower() + '.png' with open(filename, 'wb') as output_file: image_data = vehicle.get_vehicle_image(viewdirection) output_file.write(image_data) print('vehicle image saved to {}'.format(filename))
def send_poi(args) -> None: """Send Point Of Interest to car.""" account = ConnectedDriveAccount(args.username, args.password, get_region_from_name(args.region)) vehicle = account.get_vehicle(args.vin) poi_data = dict(lat=args.latitude, lon=args.longitude, name=args.name, street=args.street, city=args.city, postal_code=args.postalcode, country=args.country) vehicle.remote_services.trigger_send_poi(poi_data)
def fingerprint(args) -> None: """Save the vehicle fingerprint.""" time_dir = Path.home() / 'vehicle_fingerprint' / time.strftime("%Y-%m-%d_%H-%M-%S") time_dir.mkdir(parents=True) account = ConnectedDriveAccount(args.username, args.password, get_region_from_name(args.region), log_responses=time_dir) account.set_observer_position(args.lat, args.lng) if args.lat and args.lng: for vehicle in account.vehicles: vehicle.set_observer_position(args.lat, args.lng) account.update_vehicle_states() print('fingerprint of the vehicles written to {}'.format(time_dir))
def fingerprint(args) -> None: """Save the vehicle fingerprint.""" time_str = time.strftime("%Y-%m-%d_%H-%M-%S") time_dir = os.path.join(FINGERPRINT_DIR, time_str) os.makedirs(time_dir) account = ConnectedDriveAccount(args.username, args.password, get_region_from_name(args.region), log_responses=time_dir) account.set_observer_position(args.lat, args.lng) if args.lat and args.lng: for vehicle in account.vehicles: vehicle.set_observer_position(args.lat, args.lng) account.update_vehicle_states() print('fingerprint of the vehicles written to {}'.format(time_dir))
def vehicle_finder(args) -> None: """Trigger the vehicle finder to locate it.""" account = ConnectedDriveAccount(args.username, args.password, get_region_from_name(args.region)) account.set_observer_position(args.lat, args.lng) vehicle = account.get_vehicle(args.vin) if not vehicle: valid_vins = ", ".join(v.vin for v in account.vehicles) print('Error: Could not find vehicle for VIN "{}". Valid VINs are: {}'. format(args.vin, valid_vins)) return status = vehicle.remote_services.trigger_remote_vehicle_finder() print(status.state) print({ "gps_position": vehicle.status.gps_position, "heading": vehicle.status.gps_heading })
async def validate_input(hass: core.HomeAssistant, data): """Validate the user input allows us to connect. Data has the keys from DATA_SCHEMA with values provided by the user. """ try: await hass.async_add_executor_job( ConnectedDriveAccount, data[CONF_USERNAME], data[CONF_PASSWORD], get_region_from_name(data[CONF_REGION]), ) except OSError as ex: raise CannotConnect from ex # Return info that you want to store in the config entry. return {"title": f"{data[CONF_USERNAME]}{data.get(CONF_SOURCE, '')}"}
def get_status(args) -> None: """Get the vehicle status.""" account = ConnectedDriveAccount(args.username, args.password, get_region_from_name(args.region)) if args.lat and args.lng: for vehicle in account.vehicles: vehicle.set_observer_position(args.lat, args.lng) 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('vehicle properties:') print(json.dumps(vehicle.attributes, indent=4)) print('vehicle status:') print(json.dumps(vehicle.state.attributes, indent=4))
def __init__( self, username: str, password: str, region_str: str, name: str, read_only: bool, lat=None, lon=None, ) -> None: """Initialize account.""" region = get_region_from_name(region_str) self.read_only = read_only self.account = ConnectedDriveAccount(username, password, region) self.name = name self._update_listeners = [] # Set observer position once for older cars to be in range for # GPS position (pre-7/2014, <2km) and get new data from API if lat and lon: self.account.set_observer_position(lat, lon) self.account.update_vehicle_states()
def __init__(self, config, vehicles, logger): self.vehicles = [ vehicle for vehicle in vehicles if vehicle["manufacturer"] == "bmw" ] self.config = config self.logger = logger self.logger.info("BMW Connected Drive Cache started...") self.cache = get_cache_dir() self.max_staleness = self.config["max_staleness"] # minutes credentials = self.config["credentials"] region = get_region_from_name(credentials["region"]) self.account = ConnectedDriveAccount(credentials["user"], credentials["pwd"], region) self.vehicle_aliases: Dict[str, str] = { vehicle["vin"]: vehicle["alias"] for vehicle in self.vehicles } self.vehicle_update_timestamps: Dict[str, float] = { vehicle["vin"]: 0. for vehicle in self.vehicles }
def get_status(args) -> None: """Get the vehicle status.""" account = ConnectedDriveAccount(args.username, args.password, get_region_from_name(args.region)) account.update_vehicle_states() for vehicle in account.vehicles: print () print(vehicle.name) """print('VIN: {}'.format(vehicle.vin))""" miles = 1.609344 mileage = int (vehicle.state.mileage / miles) print('mileage: {:0}'.format(mileage)) maxRange = vehicle.state.maxRangeElectric / miles range = vehicle.state.remainingRangeElectricMls print('E-Range: {} miles'.format(range)) percent = vehicle.state.chargingLevelHv print('Battery: {}%'.format(percent)) position = vehicle.state.position """ home location """ hlat = radians (53.0) hlon = radians (-2.0) #lat = radians (position["lat"]) #lon = radians (position["lon"]) #dist = 6378 * acos(sin(hlat)*sin(lat) + cos(hlat)*cos(lat)*cos(hlon - lon)) #dist = dist / miles dist = 0 if dist > 0 : print("Location: %.1f miles from home" % dist ) else : print("Location: home") sinceCharge = round( maxRange - range,1) print ("Distance since last charge: {} miles" .format(sinceCharge)) BASE_URL = 'https://{server}/webapi/v1' VEHICLES_URL = BASE_URL + '/user/vehicles' VEHICLE_VIN_URL = VEHICLES_URL + '/{vin}' VEHICLE_TRIP_URL = VEHICLE_VIN_URL + '/statistics/lastTrip' response = account.send_request( VEHICLE_TRIP_URL.format(server=account.server_url, vin=vehicle.vin), logfilename='status', params="") lastTrip = response.json()['lastTrip'] print () print ("Last Trip:") date = datetime.strptime(lastTrip['date'],'%Y-%m-%dT%H:%M:%S+0000') print (date) duration = lastTrip["duration"] distance = lastTrip["totalDistance"] distance = round (distance / miles ,1) # convert kWh/100km to miles / kWh mpk = round (100 / (lastTrip['avgElectricConsumption'] * miles ),1) rating = round (lastTrip['efficiencyValue'] * 5.0,1) # update the status status = "Last journey / status:\n" status += " 🚗 " + str(distance) + " miles in "+ str(duration) + " mins\n" status += " 🌍 "+ str(mpk) + " mi/kWh\n" status += " 🔋 " + str(percent) + "% (" + str(range) + " miles)\n" status += " 🛡️ " + str(rating) + "/5.0" print (status) try: f = open('date.txt','r') lastdate = f.readline().strip() f.close() except FileNotFoundError: lastdate = "" print (lastdate, str(date)) if lastdate != str(date) : print ("tweeting") # authentication of consumer key and secret auth = tweepy.OAuthHandler(consumer_key, consumer_secret) # authentication of access token and secret auth.set_access_token(access_token, access_token_secret) api = tweepy.API(auth) # make a note of the last tweet date & time f = open("date.txt","w") f.write (format(date)) f.close try: api.update_status(status) except: print ("tweet error (duplicate?)")
def test_unknown_region(self): """Test unkown region.""" with self.assertRaises(ValueError): get_region_from_name("unkown")
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() username, regionname, vin, browsername = read_config() 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: "******"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)) regionname = region_name.lower() if choice == '1': print('Current username: {}'.format(username)) username = input("Type your new username ") if choice == '2': print('Paste a google maps URL, or') gps_position = parse_coordinates( input('enter lat, long in decimal format: ')) print('Lat {}, Lon {}'.format(gps_position[0], gps_position[1])) if vehicle: vehicle.set_observer_position(gps_position[0], gps_position[1]) poi = PointOfInterest(gps_position[0], gps_position[1]) 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]) vin = 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': if vehicle: light_flash(vehicle) else: print('No vehicle selected.') if choice == '6': if vehicle: sound_horn(vehicle) else: print('No vehicle selected.') 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])) send = input('Send to Pure Maps? ') if send == 'y' or send == 'Y': mapper = 'harbour-pure-maps' command = '{} geo:{},{} &'.format( mapper, vehicle.state.gps_position[0], vehicle.state.gps_position[1]) os.system(command) 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 == 'b': browsername = input( 'Please enter the executable name of your browser ') if choice == 'c': # Electric drivetrain only vehicle.remote_services.trigger_remote_charge_now() if choice == 'd': #Send a POI to car print('Paste a google maps URL, or') gps_position = parse_coordinates( input( 'Enter lat, long in decimal format, e.g. 34.01234, -92.98765 : ' )) print('Lat {}, Lon {}'.format(gps_position[0], gps_position[1])) poiname = input('Name this destination or hit <Enter> for none: ') streetname = input('Enter address or hit <Enter> for none: ') cityname = input('Enter city. <Enter> for none: ') zip = input('Enter postal (ZIP) code. <Enter> for none: ') countryname = input('Enter country name. <Enter> for none: ') if vehicle: poi = PointOfInterest(gps_position[0], gps_position[1], name=poiname, street=streetname, city=cityname, postalcode=zip) vehicle.send_poi(poi) if choice == 'l': # Get last trip statistics print('Last trip statistics:') print(json.dumps(vehicle.get_vehicle_lasttrip(), indent=4)) if choice == 'm': if browsername != '': print('Range Map:') maps = vehicle.get_vehicle_rangemap() #if sort_keys then rangemaps are sorted by "type" print('The following rangemaps are available') i = 1 for map in maps['rangemaps']: print('{} {}'.format(i, map['type'])) i += 1 i = int(input('Select a rangemap: ')) map = maps['rangemaps'][i - 1]['polyline'] f = open("rangemap.html", "w+") f.write(map1) f.write('center: [{}, {}],'.format(maps["center"]["lon"], maps["center"]["lat"])) f.write(map2) firstline = True for point in map: if not firstline: f.write(',') f.write('[{}, {}]'.format(point['lon'], point['lat'])) firstline = False f.write(map3) f.close() #input('Press Enter') #browser = 'sailfish-browser' #command = '{} {} &'.format(browsername, f.name) #os.system(command) webbrowser.open(f.name) #print(json.dumps(maps,sort_keys=True, indent=4)) #['rangemaps'][1] else: print('Enter your browser\'s executable name first. ') if choice == 'n': # Get destinations print('Vehicle destinations:') print(json.dumps(vehicle.get_vehicle_destinations(), indent=4)) if choice == 's': # Get all trip statistics print('All trip statistics:') print(json.dumps(vehicle.get_vehicle_alltrips(), indent=4)) if choice == 'o': password = input("Please enter your password: "******"doorLockState"])) print('Position: {}'.format( vehicle.state.attributes["position"]["status"])) if vin: vehicle = account.get_vehicle(vin) if choice == 'p': if vehicle: index = 1 while index != 0: views = [] for view in VehicleViewDirection: print('{} {}'.format(index, view.name)) views.append(view.name) index += 1 index = int( input('Please select view or type 0 for done. ')) if index != 0: print('{}'.format(views[index - 1])) get_image(vehicle, VehicleViewDirection(views[index - 1])) index = 1 else: print('No vehicle selected - select one first') 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 == 'w': # Get weekly charging planner print('Charging profile:') print(json.dumps(vehicle.get_vehicle_charging_profile(), indent=4)) if choice == 'z': # Send message to car subject = input('Type the subject: ') message = input('Type your message ') vehicle.send_message(message, subject) 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.') if choice == '?': print_about() printmenu() choice = input("Type an option ") print() write_config(username, regionname, vin, browsername)
BMW_CONNECTED_DRIVE_VIN = "" LOGO = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABX1BMVEV0dHT///9ubm5vb29JbYdwcHALY6QrapgqZpYAZrGmkH6cinssapgkZZk3a5GXl5cfaZjkoGtlb3ZxcXFycnJwcHBvb29wcHBwcHBwcHBwcHBwcHBwcHBxcXFwcHBwcHBvb29wcHBxcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBycnF1cW5rcHRvcHBxcXBwcHBwcHBwcHBzc3NwcHBwcHBxcHAUaKYEZ68IZ61TboJzcW9wcHBwcHBwcHBwcHBwcHBxcHA0a5MBZrEAZrEMZ6p+cWdxcXFxcXFvb28sa5kCZrAAZrEAZrJ+fn5ycnJxcXFwcHBycG8AZrMAZrEAZrF+cWdzcG9wcHBwcHC1h2QVaKcEZ68AZrEAZrEAZrEOZ6lQbYNkbneLg360hmRxcXFzcW8AZ7JxcXFycnJ7e3sAZrEAZ7Jvb3CAgIBzc3MAZ7JwcHBwcHBwcHAAZrH////TSxzlAAAAc3RSTlMAAAAAAAAAAAAAAAAAAAAAAAAAAAlCc3+FhnxzQRllWyJAkZUxIl1pfXkcL3Z+JzpkcAmPkGwxfpxIOSuRiFxGkInU5iAON2IkQdfjGwI3KncLeOUaDzQLdQEHl+fNMiBBCwEBdDV5HTQC0ygkAStJZzdyTLX+NwAAAAFiS0dEAf8CLd4AAAAHdElNRQflAwEXLBPRp6KhAAABB0lEQVQY0xXPh1qCUBgG4B+MzNwFNLEt7WG2i7ZRUB0CAgFnOXIUeO7/eTpewDdeAIpmOX5qemZ2bp6lKQAqJGQWFpeWV1bXsqIQooAW1jc2R7a2d3aZvf0DgYaceJg/Oj45PTu/uLzKiDngpOub2zt8//BYeMoXshzw8ujzC8aKGn59e2dkHpA29oEx1o1I2PwctxDYRcf1FL1UNtRKtVa3wa7XqhXVKJd0xXOdr29AVrRhxiKGTnLNuIZIKdNq/8RUBeNON9HjyWyy/9s2Kx7u/KXSEgesHzD9VqPqNrupicBnyfVBkGSiNSeeSAcDcp3gfEm26kWtJ/kCM+QO+ci2Ec8R/uQ/WgA6IA6KdS0AAAAldEVYdGRhdGU6Y3JlYXRlADIwMjEtMDMtMDFUMjM6NDE6MDIrMDA6MDCCqrT8AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIxLTAyLTI4VDExOjE0OjI3KzAwOjAwtgzNTQAAAABJRU5ErkJggg==" from bimmer_connected.account import ConnectedDriveAccount from bimmer_connected.country_selector import get_region_from_name from bimmer_connected.vehicle import VehicleViewDirection from bimmer_connected.state import ChargingState import base64 import datetime account = ConnectedDriveAccount( BMW_CONNECTED_DRIVE_USERNAME, BMW_CONNECTED_DRIVE_PASSWORD, get_region_from_name(BMW_CONNECTED_DRIVE_REGION), ) account.update_vehicle_states() if not BMW_CONNECTED_DRIVE_VIN: account_vins = [] for vehicle in account.vehicles: account_vins.append(vehicle.vin) # we'll just pick the first one BMW_CONNECTED_DRIVE_VIN = account_vins[0] vehicle = account.get_vehicle(BMW_CONNECTED_DRIVE_VIN) image_data = vehicle.get_vehicle_image(200, 80, VehicleViewDirection.FRONT) b64image = base64.b64encode(image_data)