docs: архитектура dynamic-tests
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
# Динамические тесты — архитектура
|
||||
|
||||
> v0.49.0-dev, 7 июня 2026
|
||||
> Ветка: `dynamic-tests`
|
||||
|
||||
## Концепция
|
||||
|
||||
Два теста: **на месте** и **в движении**. Разница — только в подсказке юзеру.
|
||||
Физически оба делают одно: опрашивают 12 PID каждые 250мс, копят в памяти, отправляют на сервер одной пачкой.
|
||||
|
||||
## Flow
|
||||
|
||||
```
|
||||
Юзер → кнопка «⏱ На месте» / «🚗 В движении»
|
||||
→ подсказка в окне вывода
|
||||
→ кнопка «▶ Старт»
|
||||
→ опрос 12 PID каждые 250мс, вывод: «запись... N отсчётов»
|
||||
→ кнопка «⏹ Стоп»
|
||||
→ отправка на сервер POST /api/v1/session/upload
|
||||
→ LLM-анализ → вывод в чат
|
||||
```
|
||||
|
||||
## Скрипт (сервер)
|
||||
|
||||
Новый режим `?mode=dynamic` в `api/scripts.py`:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"title": "Динамический тест",
|
||||
"mode": "dynamic",
|
||||
"interval_ms": 250,
|
||||
"steps": [
|
||||
{"id": "pid_04", "cmd": "0104", "desc": "Нагрузка"},
|
||||
{"id": "pid_05", "cmd": "0105", "desc": "ОЖ"},
|
||||
{"id": "pid_06", "cmd": "0106", "desc": "STFT"},
|
||||
{"id": "pid_07", "cmd": "0107", "desc": "LTFT"},
|
||||
{"id": "pid_0B", "cmd": "010B", "desc": "MAP"},
|
||||
{"id": "pid_0C", "cmd": "010C", "desc": "RPM"},
|
||||
{"id": "pid_0D", "cmd": "010D", "desc": "Скорость"},
|
||||
{"id": "pid_0E", "cmd": "010E", "desc": "Зажигание"},
|
||||
{"id": "pid_0F", "cmd": "010F", "desc": "IAT"},
|
||||
{"id": "pid_10", "cmd": "0110", "desc": "MAF"},
|
||||
{"id": "pid_11", "cmd": "0111", "desc": "Дроссель"},
|
||||
{"id": "pid_1F", "cmd": "011F", "desc": "Время работы"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Хранение данных (Android)
|
||||
|
||||
### До отправки — в памяти
|
||||
```kotlin
|
||||
data class DynamicSample(
|
||||
val ts: Long, // System.currentTimeMillis()
|
||||
val responses: List<RawResponse> // 12 ответов ELM
|
||||
)
|
||||
|
||||
val samples = mutableListOf<DynamicSample>() // в памяти, быстро
|
||||
```
|
||||
|
||||
### После СТОП — попытка отправки
|
||||
```kotlin
|
||||
1. Собираем все samples в JSON
|
||||
2. POST /api/v1/session/upload
|
||||
3. Если 200 → ОК, забыли
|
||||
4. Если ошибка → пишем ВСЁ в SessionDb
|
||||
```
|
||||
|
||||
### Локальное хранение — через SessionDb (уже есть)
|
||||
```sql
|
||||
-- Таблица 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 / акселерометр — не сейчас
|
||||
- Автодетект фаз (разгон/сброс) — ручной СТАРТ/СТОП
|
||||
- Отправка пачками в реальном времени — копим всё до СТОП
|
||||
+7
-5
@@ -9,15 +9,17 @@ elmAI — Android-приложение + Python-сервер для диагно
|
||||
**v0.49.0-dev** (APK: https://obdai.ru/elmer.apk)
|
||||
|
||||
### Репозитории
|
||||
- Сервер: https://gitea.services.ngcloud.ru/Nail/elmer (ветка master)
|
||||
- Android: https://github.com/Repinoid/elmer-android (ветка relay-only)
|
||||
- Сервер: https://gitea.services.ngcloud.ru/Nail/elmer (ветка **dynamic-tests**)
|
||||
- Android: https://github.com/Repinoid/elmer-android (ветка **dynamic-tests**)
|
||||
- Сервер живёт на 5.172.178.213 (SSH: naeel@5.172.178.213, ключ ~/.ssh/naeel_vm_id_ed25519)
|
||||
|
||||
### Деплой (localhost → сервер)
|
||||
```bash
|
||||
# 1. bump версии в android/app/build.gradle.kts на локальной машине!
|
||||
# 2. закоммитить + запушить
|
||||
cd /home/naeel/elmer && git add -A && git commit -m "bump vX.Y.Z-dev" && git push origin master
|
||||
# 2. закоммитить + запушить (dynamic-tests!)
|
||||
cd /home/naeel/elmer && git add -A && git commit -m "..." && git push origin dynamic-tests
|
||||
|
||||
# 3. залить android-исходники на сервер
|
||||
|
||||
# 3. залить android-исходники на сервер
|
||||
cd /home/naeel/elmer && tar czf /tmp/android-src.tar.gz --exclude='.git' --exclude='build' --exclude='.gradle' android/
|
||||
@@ -25,7 +27,7 @@ scp -i ~/.ssh/naeel_vm_id_ed25519 /tmp/android-src.tar.gz naeel@5.172.178.213:/t
|
||||
|
||||
# 4. на сервере: обновить сервер + собрать APK
|
||||
ssh -i ~/.ssh/naeel_vm_id_ed25519 naeel@5.172.178.213 "
|
||||
cd /opt/elmer && git checkout master && git pull origin master
|
||||
cd /opt/elmer && git checkout dynamic-tests && git pull origin dynamic-tests
|
||||
pip install -r requirements.txt
|
||||
sudo systemctl restart elmer
|
||||
|
||||
|
||||
Reference in New Issue
Block a user