Files
elmer/doc/dynamic-tests.md

5.3 KiB
Raw Permalink Blame History

Динамические тесты — архитектура

v0.49.0-dev, 7 июня 2026 Ветка: dynamic-tests

Концепция

Два теста: на месте и в движении. Разница — только в подсказке юзеру.
Физически оба делают одно: опрашивают 12 PID каждые 250мс, копят в памяти.

Алгоритм работы (user flow)

1. Ошибки     → scanDtc() — считывание DTC
2. Диагностика → обычный скрипт L0/L1/L2 на сервер → LLM
3. LLM сказал сделать тест на месте →
     ⏱ На месте → СТАРТ → ... → СТОП → данные в памяти
4. Диагностика → обычный скрипт + динамические данные → LLM
5. LLM сказал сделать тест в движении →
     🚗 В движении → СТАРТ → ... → СТОП → данные в памяти
6. Диагностика → обычный скрипт + динамические данные → LLM (финал)

Android → Сервер

При нажатии Диагностика:

  1. Выполняется обычный скрипт (AT-команды, PID'ы)
  2. Если есть dynamicSamples (данные теста) — прикрепляются к тому же запросу
  3. POST /api/v1/session/upload с полем dynamic_samples
  4. Сервер по наличию dynamic_samples понимает, что пришёл динамический тест
  5. Выбирает промпт: DYNAMIC_PROMPT если только динамика, или SYSTEM_PROMPT + DYNAMIC_PROMPT если и то и то

Что надо сделать

Уже сделано (написан код, не проверен)

  • Сервер: build_dynamic_script() — скрипт 12 PID 250мс
  • Сервер: ?mode=dynamic в routes.py
  • Сервер: DYNAMIC_PROMPT в prompts.py
  • Android: кнопки «⏱ На месте» / «🚗 В движении» (layout)
  • Android: DynamicCollector.kt — сбор 12 PID 250мс
  • Android: ElmChecker.kt — добавлены методы для работы с DynamicCollector
  • Android: MainActivity — СТАРТ/СТОП, данные в памяти
  • Android: общий таймер tv_timer

Надо доделать

  • Android: при старте Диагностики — прикрепить dynamicSamples к upload
  • Сервер: принимать dynamic_samples в upload_session, выбирать промпт
  • Отладка на реальной машине

До отправки — в памяти

data class DynamicSample(
    val ts: Long,                    // System.currentTimeMillis()
    val responses: List<RawResponse>  // 12 ответов ELM
)

val samples = mutableListOf<DynamicSample>()  // в памяти, быстро

После СТОП — попытка отправки

1. Собираем все samples в JSON
2. POST /api/v1/session/upload
3. Если 200  ОК, забыли
4. Если ошибка  пишем ВСЁ в SessionDb

Локальное хранение — через SessionDb (уже есть)

-- Таблица sessions (уже существует)
session_type = "dynamic"   -- отличаем от обычных

-- Таблица responses (уже существует)  
-- Каждый сэмпл = одна запись в responses:
--   session_id, step_id = "sample_N", cmd = "batch",
--   raw = JSON всего опроса, decoded = "запись №N"

Плюсы: не надо новой таблицы, SessionDb уже умеет createSession/addResponse/getResponses.

Объём: 30 секунд × 4 опроса/с × 12 PID = 1440 записей ≈ ~100KB — норм.

Ретрай непосланных сессий

При старте приложения: db.getUnuploadedSessions() → отправить → пометить uploaded=1.

Промпт для LLM (сервер)

Отдельный DYNAMIC_PROMPT в brain/prompts.py:

Ты — эксперт по диагностике. Получены временные ряды 12 параметров с интервалом 250мс.
Проанализируй:
1. Отклик дросселя — есть ли задержка/провалы
2. STFT/LTFT — богатая или бедная смесь под нагрузкой и при сбросе
3. RPM — плавность роста/падения, пропуски
4. MAP — соответствует ли оборотам
5. Зажигание — есть ли коррекция, детонация
6. Аномалии — резкие скачки, выбросы
Отвечай кратко: 2-3 предложения вывода, затем по пунктам что не так.

Что НЕ делаем

  • GPS / акселерометр — не сейчас
  • Автодетект фаз (разгон/сброс) — ручной СТАРТ/СТОП
  • Отправка пачками в реальном времени — копим всё до СТОП