Example #1
0
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)))
Example #3
0
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))
Example #4
0
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)
Example #5
0
    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,
        )
Example #6
0
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)
Example #7
0
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')
Example #8
0
    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 = []
Example #9
0
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))
Example #10
0
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))
Example #11
0
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)
Example #12
0
 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"))
Example #13
0
    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 = []
Example #14
0
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 __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 = []
Example #16
0
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))
Example #17
0
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))
Example #18
0
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))
Example #19
0
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))
Example #20
0
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)
Example #21
0
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))
Example #22
0
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))
Example #23
0
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
    })
Example #24
0
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, '')}"}
Example #25
0
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))
Example #26
0
    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()
Example #27
0
    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
        }
Example #28
0
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?)")
Example #29
0
 def test_unknown_region(self):
     """Test unkown region."""
     with self.assertRaises(ValueError):
         get_region_from_name("unkown")
Example #30
0
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)
Example #31
0
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)