doc: fat-client — архитектура, 6 ошибок, решения, mock-задержки, результаты

This commit is contained in:
Repinoid
2026-05-26 13:31:02 +03:00
parent 6e8096d10d
commit d733b58814
+68
View File
@@ -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` триггерит |