5.3 KiB
5.3 KiB
Динамические тесты — архитектура
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 → Сервер
При нажатии Диагностика:
- Выполняется обычный скрипт (AT-команды, PID'ы)
- Если есть
dynamicSamples(данные теста) — прикрепляются к тому же запросу - POST
/api/v1/session/uploadс полемdynamic_samples - Сервер по наличию
dynamic_samplesпонимает, что пришёл динамический тест - Выбирает промпт:
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 / акселерометр — не сейчас
- Автодетект фаз (разгон/сброс) — ручной СТАРТ/СТОП
- Отправка пачками в реальном времени — копим всё до СТОП