Files
carpibord/obd2_client
2026-01-30 21:45:06 +03:00
..
2026-01-30 21:45:06 +03:00
2026-01-30 16:53:05 +03:00
2026-01-30 16:53:05 +03:00

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)

Принцип работы:

  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 конфигурация

"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