OBD2 Client
Python приложение для мониторинга OBD2 данных Skoda Kodiaq 2021 на Raspberry Pi 5.
Возможности
- OBD2 Protocol — чтение стандартных PID (Mode 01)
- Offline-first Storage — SQLite с автосинхронизацией в PostgreSQL
- Handler Pipeline — модульная обработка данных
- Flipper Zero UI — отображение на портативном дисплее
- UPS Monitoring — мониторинг X120x UPS HAT
- Systemd Services — автозапуск при загрузке
Установка
# Основные зависимости
pip install -r requirements.txt
# Для PostgreSQL (опционально)
pip install psycopg2-binary
# Для UPS мониторинга (опционально, только RPi)
pip install smbus2 gpiozero
Конфигурация RPi5
/boot/firmware/config.txt
# CAN HAT (MCP2515)
dtparam=spi=on
dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25
# UART для Flipper Zero
enable_uart=1
dtoverlay=disable-bt
Инициализация CAN
sudo ip link set can0 type can bitrate 500000
sudo ip link set can0 up
Использование
Базовый запуск
python -m src.main --interface can0
С Flipper Zero
python -m src.main --interface can0 --flipper /dev/serial0
Только сканирование PID
python -m src.main --interface can0 --scan-only
Тестовый режим (виртуальный CAN)
sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link set up vcan0
python -m src.main --interface vcan0 --virtual
Параметры CLI
| Параметр | Описание |
|---|---|
-i, --interface |
CAN интерфейс (can0, vcan0) |
-c, --config |
Путь к config.json |
-v, --virtual |
Виртуальный CAN режим |
--scan-only |
Только сканирование PID |
--flipper PORT |
Включить Flipper Zero сервер |
--no-monitor |
Отключить консольный вывод |
--debug |
Отладочный режим |
Конфигурация
config.json
{
"can": {
"interface": "can0",
"bitrate": 500000,
"virtual": false
},
"obd2": {
"request_id": "0x7DF",
"response_id": "0x7E8",
"timeout": 0.2
},
"polling": {
"interval_fast": 0.1,
"interval_slow": 1.0,
"fast_pids": ["0x0C", "0x0D", "0x11", "0x04"],
"slow_pids": ["0x05", "0x5C", "0x0F", "0x2F"]
},
"storage": {
"enabled": true,
"db_path": null,
"wal_mode": true,
"retention_days": 30,
"batch_size": 50,
"flush_interval": 1.0
},
"postgresql": {
"enabled": false,
"host": "localhost",
"port": 5432,
"database": "carpibord",
"user": "carpibord",
"password": "",
"sync_interval": 30.0,
"batch_size": 500
},
"flipper": {
"enabled": true,
"port": "/dev/serial0",
"baudrate": 115200,
"show_ups": true
}
}
Переменные окружения
# CAN
export OBD2_CAN_INTERFACE=can0
export OBD2_CAN_BITRATE=500000
# Storage
export OBD2_STORAGE_ENABLED=true
export OBD2_STORAGE_PATH=/data/obd2.db
# PostgreSQL
export OBD2_PG_ENABLED=true
export OBD2_PG_HOST=postgres.example.com
export OBD2_PG_DATABASE=carpibord
export OBD2_PG_USER=carpibord
export OBD2_PG_PASSWORD=secret
# Flipper
export OBD2_FLIPPER_ENABLED=true
export OBD2_FLIPPER_PORT=/dev/serial0
Архитектура
Handler Pipeline (Offline-First)
VehiclePoller ──► HandlerPipeline
│
├── StorageHandler ──► SQLite (obd2_data.db)
│ │ │
│ │ [unsynced data]
│ │ │
│ └─────── background sync ───────┐
│ │
└── PostgreSQLHandler ◄──────────────────┘
│
▼
PostgreSQL (remote)
Принцип работы:
VehiclePollerопрашивает PID и вызывает callbacksStorageHandlerбатчит данные и пишет в SQLitePostgreSQLHandlerв фоне синхронизирует unsynced записи в PostgreSQL- При потере связи данные накапливаются локально
- При восстановлении — автоматическая досинхронизация
Структура проекта
obd2_client/
├── src/
│ ├── main.py # Точка входа, CLI
│ ├── config.py # Конфигурация
│ ├── logger.py # Логирование
│ │
│ ├── can/ # CAN абстракция
│ │ ├── frame.py # CANFrame dataclass
│ │ └── interface.py # CANInterface
│ │
│ ├── obd2/ # OBD2 протокол
│ │ ├── pids.py # Определения PID, декодеры
│ │ ├── protocol.py # Request/Response
│ │ └── scanner.py # Автодетект PID
│ │
│ ├── vehicle/ # Состояние автомобиля
│ │ ├── state.py # VehicleState (thread-safe)
│ │ └── poller.py # VehiclePoller (fast/slow)
│ │
│ ├── handlers/ # Data Pipeline
│ │ ├── base.py # BaseHandler, OBD2Reading
│ │ ├── pipeline.py # HandlerPipeline
│ │ ├── storage_handler.py # SQLite handler
│ │ └── postgresql_handler.py # PostgreSQL sync
│ │
│ ├── storage/ # Persistence
│ │ └── storage.py # SQLite + sessions
│ │
│ └── flipper/ # Flipper Zero интеграция
│ ├── protocol.py # UART протокол
│ ├── server.py # FlipperServer
│ ├── pages.py # PageManager, страницы
│ └── providers/ # Data providers
│ ├── base.py # BaseProvider
│ └── ups_provider.py # X120x UPS
│
├── config.json
├── config.json.example
├── requirements.txt
└── README.md
Поддерживаемые PID
OBD2 Standard (Mode 0x01)
| PID | Параметр | Единицы | Интервал |
|---|---|---|---|
| 0x04 | Engine Load | % | Fast |
| 0x05 | Coolant Temp | °C | Slow |
| 0x0C | Engine RPM | RPM | Fast |
| 0x0D | Vehicle Speed | km/h | Fast |
| 0x0F | Intake Air Temp | °C | Slow |
| 0x10 | MAF Rate | g/s | Slow |
| 0x11 | Throttle Position | % | Fast |
| 0x2F | Fuel Level | % | Slow |
| 0x5C | Oil Temperature | °C | Slow |
UDS Extended (Mode 0x22) — MQB Platform
UDS (ISO 14229) позволяет читать расширенные данные напрямую из ECU. Это read-only протокол, не влияющий на работу автомобиля.
Engine ECU (0x7E0 → 0x7E8)
| PID | Параметр | Единицы | Min | Max |
|---|---|---|---|---|
| 0x202A | Boost Pressure Actual | kPa | 0 | 400 |
| 0x2029 | Boost Pressure Target | kPa | 0 | 400 |
| 0xF423 | Fuel Rail Pressure | kPa | 0 | 25000 |
| 0x10C0 | Lambda Actual | λ | 0.5 | 2.0 |
| 0x1456 | Lambda Target | λ | 0.5 | 2.0 |
| 0x437C | Torque Actual | Nm | 0 | 500 |
| 0x39A2 | Wastegate Position | % | 0 | 100 |
| 0x39A3 | Wastegate Target | % | 0 | 100 |
| 0x2004 | Ignition Timing | ° | -10 | 50 |
| 0x200A | Timing Correction Cyl 1 | ° | -15 | 5 |
| 0x200B | Timing Correction Cyl 2 | ° | -15 | 5 |
| 0x200C | Timing Correction Cyl 3 | ° | -15 | 5 |
| 0x200D | Timing Correction Cyl 4 | ° | -15 | 5 |
Instrument Cluster (0x714 → 0x77E)
| PID | Параметр | Единицы | Min | Max |
|---|---|---|---|---|
| 0x22D1 | RPM (from cluster) | RPM | 0 | 8000 |
| 0x224D | Ambient Light Sensor | - | 0 | 255 |
DSG Transmission (0x7E1 → 0x7E9)
| PID | Параметр | Единицы | Min | Max |
|---|---|---|---|---|
| 0x3816 | Current Gear | gear | -1 | 7 |
| 0x3815 | Gear Selector (PRNDM) | mode | 0 | 5 |
| 0x1940 | Transmission Temp | °C | -40 | 150 |
UDS конфигурация
"uds": {
"enabled": true,
"interval_fast": 0.2,
"interval_slow": 1.0,
"fast_pids": ["0x202A", "0x437C", "0x10C0", "0x2004"],
"slow_pids": ["0x39A2", "0x200A", "0x3816", "0x3815"]
}
Flipper Zero — страница UDS Data
┌──────────────────────┐
│ UDS Data │
├──────────────────────┤
│ Boost: 185 kPa │
│ Torque: 280 Nm │
│ Lambda: 1.000 │
│ Timing: 12.5 deg │
│ Wastegate: 45% │
│ Gear: 4 │
└──────────────────────┘
Flipper Zero интеграция
Подключение
RPi5 GPIO Flipper Zero
───────── ────────────
GPIO14 (TX) ────── Pin 14 (RX)
GPIO15 (RX) ────── Pin 13 (TX)
GND ────── Pin 18 (GND)
Страницы
| # | Страница | Тип | Описание |
|---|---|---|---|
| 0 | Live Data | Info | RPM, Speed, Temps, Throttle, Fuel |
| 1 | Statistics | Info | Queries, Success rate, Uptime |
| 2 | System Info | Info | IP, CPU, Memory, CAN interface |
| 3 | App Status | Info | Pipeline, Storage, PostgreSQL sync |
| 4 | UPS Status | Info | Battery %, Voltage, Power status |
| 5 | Actions | Menu | Reconnect, Clear cache, Reboot, Shutdown |
Управление
| Кнопка | Действие |
|---|---|
| ← / → | Переключение страниц |
| ↑ / ↓ | Прокрутка / выбор пункта меню |
| OK | Подтверждение |
| Back | Отмена |
Systemd сервисы
Установка
cd ../systemd
sudo ./install.sh
Управление
# Запуск
sudo systemctl start carpibord
# Статус
sudo systemctl status carpibord
# Логи
journalctl -u carpibord -f
# Остановка
sudo systemctl stop carpibord
Сервисы
| Сервис | Описание |
|---|---|
can0-link.service |
Поднимает CAN интерфейс на 500 kbps |
carpibord.service |
Запускает OBD2 Client после CAN и сети |
PostgreSQL Setup
Создание базы
CREATE DATABASE carpibord;
CREATE USER carpibord WITH PASSWORD 'your-password';
GRANT ALL PRIVILEGES ON DATABASE carpibord TO carpibord;
Таблицы (создаются автоматически)
-- Readings
CREATE TABLE obd2_readings (
id SERIAL PRIMARY KEY,
device_id TEXT DEFAULT 'rpi5',
session_id TEXT,
pid INTEGER NOT NULL,
name TEXT NOT NULL,
value REAL NOT NULL,
unit TEXT NOT NULL,
timestamp TIMESTAMPTZ NOT NULL
);
-- Sessions
CREATE TABLE obd2_sessions (
id TEXT PRIMARY KEY,
device_id TEXT DEFAULT 'rpi5',
start_time TIMESTAMPTZ NOT NULL,
end_time TIMESTAMPTZ,
duration_seconds REAL,
reading_count INTEGER,
avg_speed REAL,
max_speed REAL,
avg_rpm REAL,
max_rpm REAL
);
UPS мониторинг (X120x)
Поддерживаются UPS HAT на базе MAX17048 fuel gauge:
- X1201, X1202 и совместимые
- Подключение по I2C (адрес 0x36)
- GPIO 6 для детекции потери питания
Отображаемые данные
- Battery % с визуализацией
[==== ] - Напряжение батареи (V)
- Статус: Charging / Full / Battery Mode
- Input voltage (V)
- Предупреждения при низком заряде
Лицензия
MIT