# 2026-06-07 — Пробинг ELM327, трехуровневый профиль ## Проблема `obd/protocol.py` — `init()` посылал ATAT1 и ATSTxx всем устройствам. Большинство клонов v1.5 не знают этих команд → тишина → `_exec()` делает до 10 ретраев → всё висит на десятки секунд. ## Решение ### 1. Трехуровневый пробинг (`obd/probe.py`) Каскадный тест: сначала база, потом улучшения. ``` Уровень 0 (база, все клоны): ATE0 ATL0 ATS0 ATH1 ATSP0 ATDPN ATRV ATI → хоть одна не ответила OK → НЕИСПРАВЕН Уровень 1 (хорошие клоны): ATAT1 → OK → уровень 1 Уровень 2 (настоящие ELM): ATCAF1 ATCFC1 → OK → уровень 2 ``` Результат сохраняется в `device_profiles` по ключу BT MAC. ### 2. Fix `obd/protocol.py` init() `init()` теперь шлёт ТОЛЬКО базу (уровень 0): ATE0 ATL0 ATS0 ATH1 ATSP0. Методы под уровень: - `init_base()` — то же что init() - `init_l1()` — + ATAT1 - `init_l2()` — + ATAT1 + ATCAF1 + ATCFC1 ### 3. Таблица `device_profiles` (`api/db.py`) ```sql CREATE TABLE device_profiles ( mac TEXT PRIMARY KEY, -- BT MAC level INTEGER NOT NULL, -- 0/1/2 elm_version TEXT, -- ATI ответ elm_desc TEXT, -- AT@1 (если есть) protocol TEXT, -- ATDPN voltage TEXT, -- ATRV supported TEXT, -- JSON: ["ATE0","ATL0",...] unsupported TEXT, -- JSON: ["ATAT1","ATCAF1",...] first_seen TEXT NOT NULL, last_seen TEXT NOT NULL ); ``` ### 4. Скрипты под уровень (`api/scripts.py`) - `build_script_l0()` — 5 PIDs + ошибки (однокадровые) - `build_script_l1()` — 8 PIDs + VIN + ошибки - `build_script_l2()` — 14 PIDs + VIN + калибровки + все ошибки ### 5. Эндпоинты (`api/routes.py`) - `POST /api/v1/elm/probe` — принимает MAC + ответы, возвращает профиль - `GET /api/v1/elm/profile/` — достаёт из кэша - `GET /api/v1/script?level=0|1|2` — скрипт под уровень ### 6. Рефакторинг: разделение на независимые сервисы Файлы разбиты по тематике, каждый — отдельный сервис: ``` obd/ commands.py — Каталог ВСЕХ AT-команд ELM327 (с метаданными) classifier.py — Классификация ответов + определение уровня connection.py — Транспортный слой (SerialTransport) probe.py — Пробинг (использует commands + classifier) protocol.py — Стейт-машина AndrOBD (использует connection) state.py — Состояния/типы ответов timing.py — Адаптивный таймаут ``` **Принцип**: каждый модуль делает одно дело, не дублирует логику. - `commands.py` — единственный источник правды о командах - `classifier.py` — единственное место классификации ответов - `connection.py` — единственное место I/O - `routes.py` — тонкая прослойка, без бизнес-логики ### 5. Эндпоинт (`api/routes.py`) `POST /api/v1/elm/probe` — принимает MAC, возвращает профиль. Сервер сам шлёт команды через реле (Android ElmForwardService). ## Ключевое правило **Нет в профиле → не слать. Никаких ретраев на неизвестное.**