Update readme and add UDS

This commit is contained in:
2026-01-30 16:53:05 +03:00
parent 19d3885bb2
commit cfccf5e75c
10 changed files with 1736 additions and 105 deletions

View File

@@ -1,111 +1,95 @@
# OBD2 Client для Skoda Kodiaq 2021 на RPi5
# OBD2 Client
Python приложение для чтения OBD2 данных через WaveShare 2-CH CAN HAT.
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/config.txt
```
### /boot/firmware/config.txt
```ini
# CAN HAT (MCP2515)
dtparam=spi=on
dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=23
dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25
# UART для Flipper Zero
enable_uart=1
dtoverlay=disable-bt
```
### Инициализация CAN интерфейса
### Инициализация CAN
```bash
sudo ip link set can0 up type can bitrate 500000
sudo ifconfig can0 txqueuelen 65536
sudo ip link set can0 type can bitrate 500000
sudo ip link set can0 up
```
## Использование
### Запуск с реальным авто
### Базовый запуск
```bash
python -m src.main --interface can0
```
### Только сканирование 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
```
### Параметры командной строки
| Параметр | Описание |
|----------|----------|
| `-i, --interface` | CAN интерфейс (can0, vcan0) |
| `-c, --config` | Путь к config.json |
| `-v, --virtual` | Использовать виртуальный CAN |
| `--scan-only` | Только сканировать PID |
| `--flipper PORT` | Включить Flipper Zero сервер на указанном порту |
| `--debug` | Включить отладочный вывод |
## Интеграция с Flipper Zero
### Подключение
```
RPi5 Flipper Zero
GPIO14 (TX) --------> RX (pin 14)
GPIO15 (RX) <-------- TX (pin 13)
GND ---------- GND (pin 18)
```
### Запуск с Flipper
### С Flipper Zero
```bash
python -m src.main --interface can0 --flipper /dev/serial0
```
### Страницы на Flipper
### Только сканирование PID
| Страница | Тип | Описание |
|----------|-----|----------|
| Live Data | Info | RPM, Speed, Coolant, Throttle, Fuel |
| Statistics | Info | Queries, Success rate, Uptime |
| System Info | Info | IP, CPU temp, Memory, CAN interface |
| Actions | Menu | Reconnect, Clear cache, Reboot, Shutdown |
```bash
python -m src.main --interface can0 --scan-only
```
### Управление
### Тестовый режим (виртуальный CAN)
- **←/→** - переключение страниц
- **↑/↓** - выбор пункта меню / прокрутка
- **OK** - подтверждение действия
- **Back** - отмена / возврат
```bash
sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link set up vcan0
## Поддерживаемые PID
python -m src.main --interface vcan0 --virtual
```
| PID | Параметр | Единицы |
|-----|----------|---------|
| 0x04 | Engine Load | % |
| 0x05 | Coolant Temp | °C |
| 0x0C | Engine RPM | RPM |
| 0x0D | Vehicle Speed | km/h |
| 0x0F | Intake Air Temp | °C |
| 0x10 | MAF Rate | g/s |
| 0x11 | Throttle Position | % |
| 0x2F | Fuel Level | % |
| 0x5C | Oil Temperature | °C |
### Параметры 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`:
### config.json
```json
{
@@ -117,49 +101,335 @@ python -m src.main --interface can0 --flipper /dev/serial0
"obd2": {
"request_id": "0x7DF",
"response_id": "0x7E8",
"timeout": 0.1
"timeout": 0.2
},
"polling": {
"interval_fast": 0.1,
"interval_slow": 1.0,
"fast_pids": ["0x0C", "0x0D", "0x11"],
"slow_pids": ["0x05", "0x2F", "0x5C"]
"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
}
}
```
## Переменные окружения
### Переменные окружения
- `OBD2_CONFIG_PATH` - путь к config.json
- `OBD2_CAN_INTERFACE` - CAN интерфейс
- `OBD2_CAN_BITRATE` - битрейт
- `OBD2_CAN_VIRTUAL` - использовать виртуальный CAN (true/false)
- `OBD2_TIMEOUT` - таймаут ответа
```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/
│ ├── __init__.py
│ ├── main.py # Точка входа, CLI
│ ├── config.py # Конфигурация
├── logger.py # Логирование
│ ├── can/
│ │ ├── frame.py # CAN фрейм dataclass
│ │ └── interface.py # Абстракция CAN шины
├── obd2/
│ ├── pids.py # Определения PID
│ │ ├── protocol.py # OBD2 запросы/ответы
│ │ ── scanner.py # Автодетект PID
├── vehicle/
│ │ ├── state.py # Состояние авто
│ └── poller.py # Циклический опрос
└── flipper/
── protocol.py # UART протокол
├── pages.py # Генераторы страниц
└── server.py # UART сервер
│ ├── 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