Files
carpibord/obd2_client/README.md

436 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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** — автозапуск при загрузке
## Установка
```bash
# Основные зависимости
pip install -r requirements.txt
# Для PostgreSQL (опционально)
pip install psycopg2-binary
# Для UPS мониторинга (опционально, только RPi)
pip install smbus2 gpiozero
```
## Конфигурация RPi5
### /boot/firmware/config.txt
```ini
# CAN HAT (MCP2515)
dtparam=spi=on
dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25
# UART для Flipper Zero
enable_uart=1
dtoverlay=disable-bt
```
### Инициализация CAN
```bash
sudo ip link set can0 type can bitrate 500000
sudo ip link set can0 up
```
## Использование
### Базовый запуск
```bash
python -m src.main --interface can0
```
### С Flipper Zero
```bash
python -m src.main --interface can0 --flipper /dev/serial0
```
### Только сканирование PID
```bash
python -m src.main --interface can0 --scan-only
```
### Тестовый режим (виртуальный CAN)
```bash
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
```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
}
}
```
### Переменные окружения
```bash
# 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)
```
**Принцип работы:**
1. `VehiclePoller` опрашивает PID и вызывает callbacks
2. `StorageHandler` батчит данные и пишет в SQLite
3. `PostgreSQLHandler` в фоне синхронизирует unsynced записи в PostgreSQL
4. При потере связи данные накапливаются локально
5. При восстановлении — автоматическая досинхронизация
### Структура проекта
```
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 конфигурация
```json
"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 сервисы
### Установка
```bash
cd ../systemd
sudo ./install.sh
```
### Управление
```bash
# Запуск
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
### Создание базы
```sql
CREATE DATABASE carpibord;
CREATE USER carpibord WITH PASSWORD 'your-password';
GRANT ALL PRIVILEGES ON DATABASE carpibord TO carpibord;
```
### Таблицы (создаются автоматически)
```sql
-- 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