diff --git a/doc/session-2026-05-26.md b/doc/session-2026-05-26.md index e320a94..2e7dded 100644 --- a/doc/session-2026-05-26.md +++ b/doc/session-2026-05-26.md @@ -305,3 +305,71 @@ python web/app.py 2. Настроить `DEEPSEEK_API_KEY` для LLM 3. Протестировать цепочку: телефон → сервер → LLM → диагноз 4. Подключить к реальному ELM327 в машине (Bluetooth вместо mock) + +--- + +## ЧАСТЬ 3: Толстый клиент (fat-client) + +### Архитектура (обсуждено) +Две фазы: +- **Офлайн**: клиент скачивает JSON-скрипт, сам гонит ELM327, пишет в SQLite +- **Онлайн**: заливает батч на сервер → LLM → диагноз на экране + +Скрипт содержит `steps[]`: OBD-команды, промпты водителю, `wait_for_user`. + +### Ветки +- `elmer-android`: `fat-client` (от `relay-only`) +- `elmer`: `fat-client` (от `master`) + +### Новые файлы + +| Файл | Что | +|------|-----| +| `ScriptRunnerService.kt` | Движок скриптов: скачать JSON, гонять ELM, SQLite, залить батч | +| `SessionDb.kt` | SQLite: `sessions` и `responses` | +| `web/script_endpoint.py` | `GET /api/v1/script`, `POST /api/v1/session/upload` | + +### Ошибки и решения (fat-client) + +| # | Ошибка | Причина | Решение | +|---|--------|---------|---------| +| 8 | `optString("cmd", null)` → строка `"null"` | Android JSONObject возвращает `"null"` строку | `optString("cmd", "")` + `.isNotEmpty()` | +| 9 | Два `companion object` в классе | Kotlin запрещает | Склеить в один | +| 10 | CI не собирал `fat-client` | Workflow: `branches: [master, relay-only]` | Добавить `fat-client` | +| 11 | «Плохой JSON скрипта» | `scriptUrl` = `http://host:5005` (HTML) вместо `/api/v1/script` | `EXTRA_SCRIPT_URL` с полным путём | +| 12 | `?` → бесконечный цикл на реальном ELM | Сервер без пауз, ELM не успевает | ATH0 вместо ATH1 + fallback-парсинг raw | +| 13 | CAN-заголовки `83 F1 1A 41 05...` | ATH1 включает заголовки, декодер не понимает | ATH0 — заголовки выкл | + +### Mock ELM327 — реалистичные задержки + +| Команда | Задержка | Разброс | +|---------|----------|---------| +| ATZ | ~2.5 сек | ±30% | +| ATSP0 | ~1.8 сек + SEARCHING... | ±30% | +| PID 01XX | ~0.2 сек | ±30% | +| DTC 03/07 | ~0.3 сек | ±30% | +| VIN 0902 | ~0.5 сек | ±30% | + +Убрано авто-приветствие при подключении (реальный ELM по BT не шлёт). + +### Результаты тестов + +**Mock (TCP 10.47.183.102:35000):** 18/18 команд успешно, VIN/DTC/PID декодированы ✅ + +**Реальный ELM327 (BT, Фаэтон):** +- BT-подключение ✅ +- ATZ → ATEx ✅ +- ATH1 → CAN-заголовки ломали декодер → исправлено на ATH0 +- Данные получены, но требуют доработки парсера под формат Фаэтона + +### Текущее состояние (ветки fat-client) + +| Компонент | Статус | +|-----------|--------| +| `ScriptRunnerService` | ✅ работает с mock | +| `ScriptRunnerService` + реальный ELM | ⚠️ требуется ATH0 (исправлено, ждёт APK) | +| `SessionDb` (SQLite) | ✅ | +| `GET /api/v1/script` | ✅ | +| `POST /api/v1/session/upload` | ✅ парсинг + fallback raw | +| LLM (DeepSeek) | ⚠️ нет API-ключа | +| APK-сборка CI | ✅ `fat-client` триггерит |