From d1903008c627bdca417bf8f02b3678c1e2593912 Mon Sep 17 00:00:00 2001 From: Repinoid Date: Thu, 28 May 2026 10:09:26 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20=D1=81=D0=B5=D1=81=D1=81=D0=B8=D1=8F=20?= =?UTF-8?q?28=20=D0=BC=D0=B0=D1=8F=20=E2=80=94=20AndrOBD=20=D1=81=D1=82?= =?UTF-8?q?=D0=B5=D0=B9=D1=82-=D0=BC=D0=B0=D1=88=D0=B8=D0=BD=D0=B0,=205=20?= =?UTF-8?q?=D0=B1=D0=B0=D0=B3=D0=BE=D0=B2,=20=D0=B2=D1=81=D0=B5=20=D0=B8?= =?UTF-8?q?=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/session-2026-05-28.md | 142 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 doc/session-2026-05-28.md diff --git a/doc/session-2026-05-28.md b/doc/session-2026-05-28.md new file mode 100644 index 0000000..90a0372 --- /dev/null +++ b/doc/session-2026-05-28.md @@ -0,0 +1,142 @@ +# Сессия 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-панель | потом |