# Сессия 2026-05-28 — AndrOBD стейт-машина, ELM-протокол, отладка ## Хронология ### 08:00 — Тест v0.12.0-dev на моке Скрипт отработал (ELM — зелёный), но upload «Сервер недоступен». Flask работал локально, проброс портов был настроен. **Диагностика:** `curl -X POST` на `/api/v1/session/upload` зависал на 60+ секунд — LLM `api.aillm.ru` долго отвечал, Flask ждал, OkHttp на телефоне таймаутил через 30с. **Исправление:** OkHttp `readTimeout` увеличен с 30с до 120с → v0.13.0-dev. ### 09:00 — Стейт-машина AndrOBD Пользователь потребовал НЕ изобретать своё, а скопировать 1:1 отлаженный код AndrOBD. Создана ветка `androbd-proto`. **Проблема 1: команды слались подряд, ответы перемешивались** Было (`init()` старая): ```python sendRaw("ATSP0"); sleep(200) # шлём, НЕ читаем ответ sendRaw("ATAT1"); sleep(200) # шлём, НЕ читаем ответ # → ответы на ATSP0 и ATAT1 в буфере → OBD-команды читают чужие ответы ``` Стало (`init()` новая): ```python _exec("ATSP0", timeout=10000) # шлём, ЖДЁМ ответ, читаем _exec("ATAT1", timeout=5000) # → каждая команда ждёт свой ответ → буфер чист ``` **Проблема 2: ATST отправлялся напрямую, ответ не читался** `_process()` вызывал `_send_atst()` которая писала `ATST` в порт и НЕ читала ответ. Следующая команда читала `OK` от ATST вместо своего ответа. Исправление: `_send_atst()` теперь читает и отбрасывает ответ на ATST. **Проблема 3: `_read()` возвращал частичный ответ при таймауте** При таймауте `_read()` возвращал что успел прочитать — например, первую строку DTC. Вторая строка попадала в следующую команду. Исправление: `_read()` теперь требует `>` перед возвратом. Без `>` — TimeoutError. **Проблема 4: таймаут 200мс мал для мока** Мок ждёт 300-500мс перед ответом на OBD-команды. AndrOBD использует 200мс с адаптивным увеличением через ATST, но мок не поддерживает аппаратный ATST. Исправление: увеличен базовый таймаут до 500мс, 10 ретраев вместо 5. **Проблема 5: BUS ERROR recovery блокирует всё** При BUS ERROR стейт-машина отправляет ATPC + ATSP0 для восстановления. Мок отвечает на ATSP0 через 1.8с. `_try_read()` ждал только 1с. Ответ на ATSP0 оставался в буфере и попадал в следующую команду. Исправление: `_try_read` использует таймаут 5с для recovery-команд. --- ## Итоговая архитектура AndrOBD ### Стейт-машина (AndrOBD ElmProt.java) ``` UNDEFINED → INITIALIZING → READY → BUSY → READY ↓ ERROR ↓ BUS ERROR RECOVERING DISCONNECTED ``` ### Классификация ответов (Rsp.identify) | Ответ | Тип | Реакция | |-------|-----|---------| | `>` | PROMPT | Конец ответа (разделитель) | | `OK` | OK | Успех, уменьшить таймаут | | `SEARCHING...` | SEARCHING | Нормально при ините | | `NODATA` | NODATA | Увеличить таймаут, ATST | | `UNABLE`, `BUS BUSY`, `CAN ERROR`, etc. | BUS ERROR | DISCONNECTED, ATPC, ATSP0 | | `ERROR` | ERROR | WARM START (ATWS) | | `DATA ERROR`, `BUFFER FULL`, `RX ERROR` | DATA ERROR | WARM START | | Всё остальное | DATA | Успех, уменьшить таймаут | ### Чтение (StreamHandler.java) - Побайтовое, пауза 1мс - CR (13) = разделитель строк - `>` (62) = конец ответа - LF (10) и пробел (32) = игнорируются - **Без `>` ответ не возвращается** (TimeoutError) ### Адаптивный таймаут (AdaptiveTiming.java) - Старт: 500мс (для мока; реальный ELM → 200мс) - Шаг: 20мс - Диапазон: 50-2000мс - ATST отправляется через `_queue_atst()` → ответ читается корректно --- ## Результаты тестирования Python-тест (`tools/test_androbd.py`) против Mock ELM327 v2: | Тест | Результат | |------|-----------| | VIN (0902) → 490201... | ✅ | | DTC (03) → 430113... + 430133... | ✅ | | RPM (010C) → 410C1AF8 | ✅ | | ОЖ (0105) → 41055A | ✅ | | Ответы не перемешаны | ✅ 2/3 прогонов | 1/3 прогонов упал из-за случайного BUS BUSY в моке (3%) — стейт-машина корректно восстановилась, но DTC-ответ был пустой (ожидаемое поведение). --- ## Версии APK | Версия | Что | |--------|-----| | v0.11.0-prod | Старая, ответы перемешаны | | v0.12.0-dev | Стейт-машина, но OkHttp 30с → «сервер недоступен» | | **v0.13.0-dev** | Стейт-машина + OkHttp 120с | --- ## Что дальше (P0 → P3) | P0 | ELM-протокол со стейт-машиной | ✅ сделано (Python + Kotlin) | | P0 | Тест на моке | ✅ 2/3 зелёные | | P0 | OkHttp timeout | ✅ 30→120с | | P1 | GPS-модуль | запланировано | | P1 | Трёхфазный флоу с жалобами | запланировано | | P2 | DTC-база на сервере | потом | | P2 | LLM cross-validation | потом | | P3 | Web-панель | потом |