6.3 KiB
Сессия 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() старая):
sendRaw("ATSP0"); sleep(200) # шлём, НЕ читаем ответ
sendRaw("ATAT1"); sleep(200) # шлём, НЕ читаем ответ
# → ответы на ATSP0 и ATAT1 в буфере → OBD-команды читают чужие ответы
Стало (init() новая):
_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-панель | потом |