Telegram bot для наших bmw G серии
Итак, однажды мне пришла мысль сделать что-то большее, чем доступно в официальном 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. Продолжение следует...