Итак, однажды мне пришла мысль сделать что-то большее, чем доступно в официальном myBMW приложении. В приложении все вроде ок, но чувство добавить чего-то своего не покидало меня. Немного покопавшись в могучем и необъятном интернете нашел библиотеку bimmerconnected на Github. Каково было мое удивление, что достать данные со своих авто оказалось не очень сложно. С этого и начался мой долгий и упорный труд небольшой оптимизации под себя моих же авто, а точнее их информационной составляющей. Прошу не пинать меня за предоставленный код ниже, я не являюсь серьезным программистом, а всего лишь занимаюсь АСУТП.

Для чего мне это?

Изучив доступные возможности библиотеки bimmerconnected я понял, что мне нужно получать уведомление в телегу о следующем:

  • остатке топлива в баке, чтобы супруга раз в день получала сообщения о необходимости дозаправке, если топливо в ее авто почти на нуле (менее 10 литров).

  • периодического фонового уведомления о локации авто по точкам. Допустим, супруга покинула квартиру, хочу получить уведомление, приехала к детскому садику - хочу получить уведомление, машина на даче - уведомление и тп. Мне так проще жить, когда вижу где авто и не мучаю тупыми вопросами супругу).

  • считыванием текущих ошибок прямо в телегу. Спустило колесо или вылезла та или иная ошибка - получил уведомление в телегу. Я не всегда нахожусь рядом с авто и работа вахтой наложила свои ограничения на мониторинг моих двух авто.

  • логировании сообщений, телега удобна именно тем, что спустя время легко найти что и когда появлялось, когда авто требовала замены масла в двигателе или тормозной жидкости и т. п.

Общая концепция

Общая схема работы сервиса следующая поэтапно следующая:

  • скачиваем данные с BMW connected drive и сохраняем SQLite DB. Для этого будем использовать отмеченную выше bimmerconnected библиотеку

  • Запускать данный процесс будем на VPS сервере, допустим, раз в 30 минут.

  • далее делаем telegram bot, который будет отправлять уведомления пользователю или же обрабатывать запросы от пользователя и точно также запускаем бота на VPS сервере.

Первый этап

Устанавливаем sqlite3, asyncio и bimmer_connected.

Для этого в командной строке вводим pip install bimmer_connected, pip install asyncio и pip install sqlite3.

Далее надо знать VIN номер авто и данные учетной записи connected drive. Для тестирования соединения пишем код ниже на питоне и смотрим результат.

import asyncio 
from bimmer_connected.account import MyBMWAccount 
from bimmer_connected.api.regions import Regions 
async def main(): 
  account=MyBMWAccount('USER','PASSWORD',Regions.REST_OF_WORLD) 
  await account.get_vehicles() 
  vehicle=account.get_vehicle('VIN') 
  print(vehicle.brand,vehicle.name,vehicle.vin,vehicle.mileage)
  result1=vehicle.fuel_and_battery
  print(result1)

  result2=vehicle.vehicle_location
  print(result2)

  result2 = vehicle.vehicle_location
  latitude1 = result2.location.latitude
  longitude1 = result2.location.longitude

  print("Latitude:", latitude1)
  print("Longitude:", longitude1)
  fuel_value = result1.remaining_fuel.value
  print("Fuel value:", fuel_value)
  print("Mileage:", vehicle.mileage.value)
  
asyncio.run(main())

Вместо USER, PASSWORD и VIN соответственно надо подставить данные своего авто.

Далее получаем успешный ответ:

Далее для сохранения в sqlite дописываем код следующим образом.

import sqlite3 
import asyncio 
from bimmer_connected.account import MyBMWAccount 
from bimmer_connected.api.regions import Regions 
async def main(): 
  account=MyBMWAccount('USER','PASSWORD',Regions.REST_OF_WORLD) 
  await account.get_vehicles() 
  vehicle=account.get_vehicle('VIN') 
  print(vehicle.brand,vehicle.name,vehicle.vin,vehicle.mileage) 
  print(result1)
  result2=vehicle.vehicle_location
  print(result2)
  # Получение локации
  result2 = vehicle.vehicle_location
  latitude1 = result2.location.latitude
  longitude1 = result2.location.longitude
  print("Latitude:", latitude1)
  print("Longitude:", longitude1)
  fuel_value = result1.remaining_fuel.value
  print("Fuel value:", fuel_value)
  print("Mileage:", vehicle.mileage.value)
  # Подключение к базе данных
  conn = sqlite3.connect('mydatabase.db')
  cursor = conn.cursor()

  # Создание таблицы (если она еще не существует)
  cursor.execute('''CREATE TABLE IF NOT EXISTS BMW
                    (id INTEGER PRIMARY KEY AUTOINCREMENT,
                     latitude FLOAT,
                     longitude FLOAT,
                     fuel FLOAT,
                     km FLOAT)''')

  # Вставка данных в таблицу
  latitude = latitude1
  longitude = longitude1
  fuel = fuel_value
  km = vehicle.mileage.value

  cursor.execute('INSERT INTO BMW (latitude, longitude, fuel, km) VALUES (?, ?, ?, ?)', (latitude, longitude, fuel, km))

  # Сохранение изменений в базе данных
  conn.commit()

  # Закрытие соединения
  conn.close()
asyncio.run(main())

Теперь данные выгружаются с сервера BMW в нашу пока еще локальную базу данных sqlite. Продолжение следует...