# 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