chore: remove trash from root — analysis.md, idea.md, legacy-*, .instructions.md, logo.jpg, morda.md

This commit is contained in:
Repinoid
2026-07-10 15:43:22 +04:00
parent bbbc06ec68
commit 1baaa8dffe
7 changed files with 0 additions and 703 deletions
-57
View File
@@ -1,57 +0,0 @@
# Инструкция для Copilot — проект elmAI
> Последнее обновление: 31 мая 2026 · v0.36.0-dev
## Репозитории
| Репо | Назначение | Хостинг |
|------|-----------|---------|
| `elmer/` (этот) | Сервер Python/Flask | gitea.services.ngcloud.ru/Nail/elmer |
| `elmer/android/` | Android-приложение Kotlin | github.com/Repinoid/elmer-android |
## Деплой
### Сервер (obdai.ru, 5.172.178.213)
- Код: `/opt/elmer` (git clone gitea)
- Ветка: `master` (по умолчанию)
- Деплой: `ssh obdai.ru "cd /opt/elmer && git pull && sudo systemctl restart elmer"`
- Сервис: `gunicorn -w 4 -b 127.0.0.1:8000 web.app:app`
- Прокси: nginx :443 → :8000
- **APK отдавать напрямую через nginx, НЕ через Flask/gunicorn:** `location = /elmer.apk { alias /opt/elmer/web/static/app-debug.apk; }`
### APK
- Сборка: **автоматически GitHub Actions** при пуше в master
- Деплой: CI сам заливает APK на сервер (`appleboy/scp-action`)
- Ссылка: `https://obdai.ru/elmer.apk` → nginx отдаёт напрямую `web/static/app-debug.apk`
### Версионирование
- APK: `android/app/build.gradle.kts``versionName`
- Сайт: `web/templates/index.html` (синхронизировать вручную)
- Документация: в заголовках `.md` файлов
## Правила работы
1. **ЕСЛИ в диалоге содержится ВОПРОС в любой форме — только ответить. НИЧЕГО НЕ ПРЕДПРИНИМАТЬ.** Не писать код, не редактировать файлы, не коммитить, не деплоить. Только прямые императивы («сделай», «исправь», «напиши», «внеси», «задеплой») — команда к действию.
2. **Не выдумывать инфраструктуру.** Никаких Docker, Kubernetes. Всё на голом железе.
3. **Читать документацию перед действиями.** `doc/architecture.md` — канонический источник.
3. **Не редактировать отчёты Опуса.** `doc/opus-review*.md` — только для чтения.
4. **Ключи и токены:** LLM-ключ только на сервере (`config.yaml`), НЕ в APK. `X-Api-Key` приложения — через `BuildConfig.API_KEY` из `local.properties`.
5. **Git:** `elmer/` и `elmer/android/` — отдельные репо, отдельные коммиты.
6. **Ветки:** `master` — продакшен, `opus-fixes` и др. — для правок. Вливать в master когда готово.
7. **После правок:** коммит + пуш + (если сервер) деплой через SSH.
8. **Версия:** менять в трёх местах — `build.gradle.kts`, `index.html`, доки.
9. **Документировать изменения** в `doc/history/YYYY-MM-DD.md` после каждого сеанса работы. Формат: 🔴/🟡/🟢 для приоритета, по файлам.
## Структура сервера
```
elmer/
├── api/ # REST, БД, скрипты, парсер
├── brain/ # LLM-клиент, промпты
├── obd/ # ELM327 стейт-машина
├── web/ # Flask, шаблоны, статика (APK)
├── android/ # Android-приложение (отдельный репо)
├── doc/ # Документация
├── config.yaml # LLM API key, порты
└── run.py # Локальный запуск
```
-249
View File
@@ -1,249 +0,0 @@
# Elmer — анализ и план (2026-05-25)
## Суть проекта
Сервис анализа ошибок электроники автомобиля через ELM327 OBD2 + LLM.
## Железо
- **Сканер:** ELM327 Bluetooth v1.5, чип PIC18F25K80 (китайский клон)
- **Ноутбук разработчика:** с Bluetooth, будет соединяться с ELM327 напрямую для отладки
## Целевая аудитория
- Технически любопытный автовладелец (не профессионал, но и не «глубинарий»)
- Уже имеет ELM327 — значит базовое понимание есть
- Хочет понять проблему, а не просто получить код ошибки
## Ключевые требования к ответам
- **Честная уверенность:** «С вероятностью ~80% проблема в X, потому что...»
- **Пояснение логики:** почему именно этот вывод
- **Предупреждения:** «Если НЕ помогло — тогда проверь Y»
- **Никаких категоричных «меняй X»** без 100% уверенности
- **Liability Protection:** нельзя чтобы пользователь сломал машину из-за неверного диагноза
## LLM
- Рассматривается DeepSeek (дёшево через API)
- Или другая простая/дешёвая модель
- Нужен RAG/grounding на реальных repair manuals и TSB, чтобы минимизировать галлюцинации
## Компоненты системы
1. **Android-приложение** (в последнюю очередь)
- Стабильная версия Android (не гоняться за новейшей)
- Максимально простое: минимум кнопок
- Русский язык
- Bluetooth SPP → ELM327
2. **Сервер** (после отладки логики на ноутбуке)
- Принимает данные от приложения
- Формирует запросы к LLM
- Итеративный цикл: запрос → ответ → может запросить ещё параметры или действия от пользователя
- Отдаёт диагноз с пояснениями
3. **LLM-слой**
- Промпт с контекстом автомобиля (VIN → марка/модель/двигатель)
- RAG на базу знаний (ошибки, мануалы, TSB)
- Итеративная диагностика: сервер может переспрашивать LLM
## Протокол диагностики (конечный автомат)
Цикл:
1. Приложение считывает VIN → сервер
2. Приложение считывает коды ошибок → сервер
3. Сервер → LLM: первичный анализ
4. LLM может запросить:
- Дополнительные PID'ы с ЭБУ (live data)
- Действия от пользователя (прогазовать, проехать, считать на холодную и т.д.)
5. Повторять пока не будет достаточно данных для диагноза
6. Финальный ответ: диагноз + степень уверенности + пояснения + что делать
## План разработки (три фазы)
### Фаза 1: Ноутбук + ELM327 (СЕЙЧАС)
- Python-скрипт: Bluetooth → ELM327 → читаем VIN, ошибки, PID'ы
- Отправляем в LLM вручную — отлаживаем логику, промпты, цикл вопросов-ответов
- Никакого сервера, никакого Android
### Фаза 2: Сервер
- Flask/FastAPI — принимать данные, проксировать в LLM
- База знаний / RAG
- State machine диагностики
### Фаза 3: Android-приложение
- Bluetooth SPP (Serial Port Profile) — есть нюансы на Android 12+
- Минималистичный UI
- Отправка данных на сервер, отображение ответов
## Риски
1. **ELM327 v1.5 клон** — неполный протокол, глюки на高速 CAN
2. **PID'ы разные у разных марок** — нужна БД по производителям
3. **LLM галлюцинации** — только grounding/RAG спасёт
4. **Bluetooth SPP на Android 12+** — permissions, pairing
## Ресурсы
- `python-OBD` — библиотека для работы с ELM327 (или свой serial-протокол)
- `pyserial` уже установлен в системе
- DeepSeek API (или OpenRouter как альтернатива)
---
## Структура проекта (создана 2026-05-25)
```
elmer/
├── elmer/ # Python-пакет
│ ├── __init__.py # версия 0.1.0
│ ├── config.py # загрузка config.yaml + подстановка ${ENV}
│ ├── elm.py # ELM327: pyserial, VIN, DTC, PID
│ ├── db.py # SQLite: cars, tokens, llm_messages, ecu_parameters, dtc_codes
│ ├── prompts.py # SYSTEM_PROMPT + build_user_prompt()
│ └── diagnose.py # DeepSeek API (OpenAI-совместимый)
├── config.yaml # настройки (BT-порт, API-ключ, PID'ы)
├── requirements.txt # pyserial, pyyaml, requests
├── run.py # главный вход: ELM → данные → LLM → печать + сохранение
├── idea.md # исходная задумка
└── analysis.md # этот файл
```
## Запуск (в салоне авто)
```bash
# 1. Установить зависимости
pip install -r requirements.txt
# 2. Сопрячь ELM327 по Bluetooth
bluetoothctl pair 11:22:33:44:55:66
# (в config.yaml прописан порт /dev/rfcomm0)
# 3. Запустить
DEEPSEEK_API_KEY=sk-... python run.py
```
Что произойдёт:
1. Подключится к ELM327
2. Прочитает VIN
3. Считает ошибки (stored mode 03 + pending mode 07)
4. Считает параметры (обороты, температура, скорость, дроссель, MAP, IAT, топливные тримы)
5. Отправит в DeepSeek → напечатает диагноз
6. Сохранит всё в `elmer.db` (SQLite)
---
## Десктопный UI (Web)
Для тестирования на ноутбуке (не тыкать грязным пальцем в телефон):
- `web/app.py` — Flask (порт 5005), один endpoint `/api/diagnose` (POST)
- `web/templates/index.html` — одна кнопка, тёмная тема, результат
- В будущем этот же код — прототип серверного API
Запуск:
```bash
DEEPSEEK_API_KEY=sk-... python web/app.py
# Открыть http://localhost:5005
```
## Версии для пользователей (будущее)
- **Android** — Kotlin/Java, Bluetooth SPP
- **Windows** — тот же веб-интерфейс в WebView (или Electron, или просто браузер)
- Общий серверный API между ними
---
---
## Архитектура клиент-сервер (решено 2026-05-25)
### Принцип: тонкий клиент
Клиент ничего не знает о диагнозе. Только транспорт:
```
ELM327 ←Bluetooth SPP→ Android Client ←HTTP JSON→ Сервер ←API→ DeepSeek
```
### Клиент как универсальный SDK
- Пользователь вводит URL своего сервера (или используется наш по умолчанию)
- Протокол HTTP/JSON документирован — любой backend
- Два режима работы клиента:
1. **«Опрос» (основной):** клиент сам читает VIN + DTC + PID'ы, шлёт JSON серверу
2. **«Ретранслятор» (расширенный):** сервер шлёт сырые AT-команды, клиент пересылает ответ
### Десктоп
- Браузер (Chrome) → локальный Flask → pyserial → ELM327
- Отдельного «приложения» для Windows не нужно
- Тот же `web/app.py` — и тестовый UI, и прототип сервера
### Открытость и доверие
| Что | Где | Зачем |
|---|---|---|
| **Клиент (Android)** | GitHub (открытый) | Доверие — любой может проверить код, собрать сам |
| **Сервер (Python)** | Gitea (закрытый) | API-ключи, логика, коммерческая часть |
| **Публикация** | RuStore | Бесплатно, модерация = дополнительное доверие |
### Git-стратегия
- `gitea.services.ngcloud.ru/Nail/elmer` — разработка сервера (текущий репо)
- `github.com/Nail/elmer-android` — клиент (будет создан), лицензия MIT
- Серверный репо на GitHub НЕ публикуем
---
## TODO / Дорожная карта
### 🔴 Фаза 1 — отладка на ноутбуке (ближайшая)
- [ ] Проверить Bluetooth на ноутбуке: `hciconfig`, `bluetoothctl`
- [ ] Сопрячь ELM327: `bluetoothctl pair <MAC>`
- [ ] Привязать к `/dev/rfcomm0`: `rfcomm bind 0 <MAC>`
- [ ] `pip install -r requirements.txt`
- [ ] `DEEPSEEK_API_KEY=sk-... python run.py` — консольный тест
- [ ] `DEEPSEEK_API_KEY=sk-... python web/app.py` — веб-тест
- [ ] Подключить реальную машину, считать VIN + ошибки + параметры
- [ ] Оценить качество ответа DeepSeek
### 🟡 Фаза 2 — сервер
- [ ] Выделенный сервер/ВМ (или Kubernetes pod)
- [ ] Flask → production (gunicorn)
- [ ] API: `/api/diagnose` (как сейчас), + `/api/sessions`, + `/api/history/<vin>`
- [ ] База: миграция SQLite → PostgreSQL
- [ ] RAG: база знаний (repair manuals, TSB) для grounding
- [ ] State machine: итеративные запросы к LLM
- [ ] HTTPS (Let's Encrypt)
### 🟢 Фаза 3 — Android-клиент
- [ ] Создать репо `github.com/Nail/elmer-android`
- [ ] Kotlin, minSdk ~24 (Android 7), targetSdk 34
- [ ] Bluetooth SPP: поиск, pairing, connect, read/write
- [ ] OBD2 парсер: VIN (0902), DTC (03/07), PID (01XX)
- [ ] UI: одна кнопка «Диагностика» + поле ввода URL сервера
- [ ] HTTP-клиент: POST JSON на сервер, показ ответа (Markdown → текст)
- [ ] Permissions: только BLUETOOTH + INTERNET
- [ ] Подпись APK, публикация в RuStore
- [ ] README: как собрать самому, как использовать с чужим сервером
---
## Заметки по итогам обсуждения
- **Гипотеза подтверждена:** DeepSeek уже дал полный анализ по логам VCDS. Лучше гугла.
- **Модерация RuStore:** проверяет вредоносный код и permissions. BLUETOOTH + INTERNET — вопросов не вызовет.
- **Sideload (APK напрямую):** проверок нет, но permissions видны до установки.
- **Chrome на Android НЕ может:** Web Bluetooth API только BLE, Web Serial API не поддерживается.
- **Termux с Python:** теоретически, но Bluetooth-доступ сложен.
- **ELM327 v1.5 (PIC18F25K80):** китайский клон. Неполный протокол, возможны глюки. Держать в уме.
- **Нет готового аналога:** ниша новая (LLM + OBD2), старые приложения без AI-анализа.
---
*Продолжить: тестировать в салоне авто с реальным ELM327.*
-60
View File
@@ -1,60 +0,0 @@
# obdai.ru — AI-диагностика автомобиля через ELM327
Сервис анализа ошибок электроники автомобиля с помощью ИИ (DeepSeek).
## Как работает
```
ELM327 ←Bluetooth→ Телефон (тонкий клиент) ←HTTP→ Сервер ←API→ DeepSeek
вся логика здесь
```
## Железо пользователя
- ELM327 Bluetooth (клон PIC18F25K80 — дешёвый, массовый)
- Android-телефон (7+)
## Тонкий клиент (Android)
Только транспорт, никакой логики:
- Bluetooth SPP → ELM327
- Читает сырые OBD-ответы
- Отправляет HTTP POST на сервер
- Показывает ответ от сервера
Открытый исходный код на GitHub → доверие пользователей.
Публикация в RuStore.
## Сервер (вся логика)
1. Принимает сырые данные от клиента (`/api/v1/raw-obd`)
2. Парсит: VIN, коды ошибок, параметры ЭБУ
3. Формирует промпт → DeepSeek API
4. LLM отвечает → сервер анализирует → может запросить ещё данные
5. Итеративный цикл:
- диагноз
- или команда «считай ещё параметр X»
- или задание водителю («прогазуй до 3000 об/мин», «проедь 5 км», «дожми до кикдауна»)
6. Финальный ответ: диагноз + степень уверенности + пояснения + что делать
## Десктоп (для тестирования)
Ноутбук → Bluetooth → ELM327 → локальный Flask → DeepSeek.
Браузерный UI. Без Android.
## Домен
**obdai.ru** (обыгрывается: «обдай грязью» + OBD + AI)
## LLM
DeepSeek (через OpenAI-совместимый API). Дёшево, справляется с анализом логов.
## Компоненты
| Компонент | Где | Технологии |
|---|---|---|
| Сервер | obdai.ru | Python, Flask → gunicorn, PostgreSQL |
| Клиент Android | GitHub + RuStore | Kotlin, AndrOBD library (GPLv2), OkHttp |
| Десктоп | Локально | Python, Flask, pyserial, браузер |
-86
View File
@@ -1,86 +0,0 @@
#!/bin/bash
# Деплой Elmer на obdai.ru
set -e
echo "=== Установка пакетов ==="
apt update && apt install -y python3-pip python3-venv nginx certbot python3-certbot-nginx
echo "=== Клонирование репо ==="
cd /opt
git clone https://gitea.services.ngcloud.ru/Nail/elmer.git || (cd elmer && git pull)
cd elmer
git checkout fat-client
echo "=== Виртуальное окружение ==="
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install gunicorn
echo "=== Конфигурация ==="
cp config.yaml config.yaml.bak
cat > config.yaml << 'YAML'
elm327:
port: /dev/rfcomm0
baudrate: 38400
llm:
api_key: "sk-ucI5YvOticoOQ9Kuj5K9mQ"
model: "gpt-oss-120b"
base_url: "https://api.aillm.ru/v1"
pids:
"0105": ["coolant_temp", "°C"]
"010C": ["rpm", "об/мин"]
"010D": ["speed", "км/ч"]
YAML
echo "=== Systemd сервис ==="
cat > /etc/systemd/system/elmer.service << 'UNIT'
[Unit]
Description=Elmer Flask API
After=network.target
[Service]
User=naeel
WorkingDirectory=/opt/elmer
ExecStart=/opt/elmer/venv/bin/gunicorn -w 4 -b 127.0.0.1:8000 web.app:app
Restart=always
[Install]
WantedBy=multi-user.target
UNIT
echo "=== Nginx ==="
cat > /etc/nginx/sites-available/elmer << 'NGX'
server {
listen 80;
server_name obdai.ru www.obdai.ru ai.obdai.ru test.obdai.ru;
location /static/ {
alias /opt/elmer/web/static/;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
NGX
ln -sf /etc/nginx/sites-available/elmer /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
nginx -t && systemctl reload nginx
echo "=== SSL ==="
certbot --nginx -d obdai.ru -d www.obdai.ru --non-interactive --agree-tos -m tazet@narod.ru || true
echo "=== Запуск ==="
systemctl daemon-reload
systemctl enable elmer
systemctl restart elmer
systemctl restart nginx
echo "=== ГОТОВО ==="
curl -s http://obdai.ru/api/v1/script | head -c 50
-78
View File
@@ -1,78 +0,0 @@
## 4. Контекст проекта (РЕЗЮМЕ для нового чата)
### Что это
elmAI — Android-приложение + Python-сервер для диагностики авто через ELM327.
### Текущая версия
**v0.48.0** (APK: https://obdai.ru/elmer.apk)
### Репозитории
- Сервер: https://gitea.services.ngcloud.ru/Nail/elmer (ветка master)
- Android: https://github.com/Repinoid/elmer-android (ветка relay-only)
- Сервер живёт на 5.172.178.213 (SSH: naeel@5.172.178.213, ключ ~/.ssh/naeel_vm_id_ed25519)
### Деплой
```bash
# ВСЕГДА сначала bump версии в android/app/build.gradle.kts!
cd /home/naeel/elmer/android && git add -A && git commit -m "..." && git push origin master
cd /home/naeel/elmer && tar czf /tmp/android-src.tar.gz --exclude='.git' --exclude='build' --exclude='.gradle' android/
scp -i ~/.ssh/naeel_vm_id_ed25519 /tmp/android-src.tar.gz naeel@5.172.178.213:/tmp/
ssh -i ~/.ssh/naeel_vm_id_ed25519 naeel@5.172.178.213 \
"cd /opt/elmer && rm -rf android && tar xzf /tmp/android-src.tar.gz && \
cd android && gradle wrapper --gradle-version 8.7 && \
export ANDROID_SDK_ROOT=\$HOME/android-sdk && \
./gradlew clean assembleDebug && \
cp app/build/outputs/apk/debug/app-debug.apk /opt/elmer/web/static/"
```
### Структура проекта
```
elmer/
android/ — Android-приложение (Kotlin)
.../client/
MainActivity.kt — UI + приёмники
ElmForwardService.kt — BT/TCP-реле
TestService.kt — автономный тест ELM
api/ — Flask API (Python)
db.py — БД (sessions + device_profiles)
routes.py — эндпоинты
scripts.py — скрипты L0/L1/L2
parser.py — парсинг ответов
config.py, dtc.py, ping.py
brain/ — LLM-клиент, промпты
obd/ — ELM-протокол (Python)
commands.py — каталог AT-команд
classifier.py — классификация ответов
connection.py — SerialTransport
probe.py — пробинг ELM
protocol.py — стейт-машина AndrOBD
state.py — состояния/ответы
timing.py — адаптивный таймаут
doc/ — Документация, сессии
web/ — Flask web, статика
```
### Что сделано (сессия 2026-06-07)
#### Сервер
- **Пробинг ELM**: трехуровневый каскад (L0/L1/L2), профили в БД по MAC
- **Fix init**: больше не шлём ATAT1/ATSTxx (вешало клоны)
- **Скрипты под уровень**: L0 (5 PIDs), L1 (8 + VIN), L2 (14 + калибровки)
- **Рефакторинг**: код разбит на независимые модули (commands, classifier, connection...)
#### Android
- **Вывод**: append вместо overwrite (строки не перекрываются)
- **Таймер**: отдельный TextView, тикает только во время обмена (Engine Time)
- **TestService**: адаптивные таймауты, ATS0, \r терминатор
### Что НЕ сделано (TODO)
- Полевой тест на машине ← СЕЙЧАС
- Разбить MainActivity.kt
- Разбить ElmChecker.kt
### Важные правила
- ELM327 v1.5 — фейк, НЕ слать ATAT1/AT@1/AT@2/ATST/ATCAF1/ATCFC1
- Все статусы через append("\n..."), не tvStatus.text =
- Таймер операций (opTimerStart/Stop), не сессии
- Версию поднимать ВЕЗДЕ: build.gradle.kts, index.html (2 места), CHANGELOG.md, resume.txt, doc/architecture.md
- В проекте elmer — НИЧЕГО не делать без прямого указания
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 586 KiB

-173
View File
@@ -1,173 +0,0 @@
# Морда elmAI v2
> Новая архитектура UI. Обсуждено 7 июня 2026.
## Макет
```
┌──────────────────────────────────────────┐
│ 🔧 elmAI v?.?.? │
│ 📡 Сервер ● 🔌 ELM ● 🚗 ЭБУ ● 🧠 LLM ● │ иконки + светофоры
├──────────────────────────────────────────┤
│ [ ОШИБКИ / ДИАГНОСТИКА / СТАРТ / СТОП ] │ одна кнопка
├──────────────────────────────────────────┤
│ │
│ поле вывода результатов │
│ │
├──────────────────────────────────────────┤
│ [📋 История] │
├──────────────────────────────────────────┤
│ [____________________________] [➤] │ поле ввода + кнопка
└──────────────────────────────────────────┘
```
## Иконки и светофоры
Четыре иконки в строке под версией. Справа от каждой — цветной индикатор.
| Иконка | Текст | 🟢 Зелёный | 🟡 Жёлтый | 🔴 Красный |
|--------|-------|-----------|----------|-----------|
| 📡 | Сервер | ping < 3с | проверка... | нет связи |
| 🔌 | ELM | BT + ATI ok | подключение... | нет ELM |
| 🚗 | ЭБУ | 0100 ответил | — | нет связи с ЭБУ |
| 🧠 | LLM | ping-llm ok | проверка... | нет доступа |
- Жёлтый — только на время проверки
- LLM проверяется только если Сервер зелёный
- ЭБУ проверяется только если ELM зелёный
- **Тап по иконке** — перепроверка. Сбрасывает цвет на жёлтый, запускает проверку заново.
### Таймауты
- **ELM**: 2 попытки BT-подключения по ~4с = макс 8с → 🔴
- **Сервер**: HTTP GET `/api/v1/ping`, таймаут 3с → 🔴
- **LLM**: HTTP GET `/api/v1/ping-llm`, таймаут 5с → 🔴 (только если Сервер 🟢)
- При тапе на иконку проверка запускается немедленно, без задержек.
### Стартовый сценарий
1. Открыли приложение → все индикаторы 🟡 или 🔴
2. ELM 🟡 — пробуем подключиться (8с макс) → 🟢 или 🔴
3. Сервер 🟡 — ping (3с) → 🟢 или 🔴
4. Если Сервер 🟢 → LLM 🟡 — ping-llm (5с) → 🟢 или 🔴
5. Если ELM 🟢 → ЭБУ — пробуем `0100` → 🟢 или 🔴
После первого цикла индикаторы не обновляются автоматически — только по тапу.
## Кнопка-трансформер
Одна широкая кнопка. Меняет текст, цвет и действие в зависимости от этапа.
```
🔴 [⚠️ ОШИБКИ] — начальное состояние
↓ тап
сканирование DTC (03 + 07)
🔵 [🔍 ДИАГНОСТИКА] — ошибки считаны
↓ тап
ЕСЛИ сервер 🟢 → запрос параметров ЭБУ → отправка на сервер → LLM-анализ → вывод
ЕСЛИ сервер 🔴 → пояснение в выводе: «Сервер недоступен. Сделайте тест.»
🟢 [▶ СТАРТ] — готов к динамическому тесту
↓ тап
подсказка в выводе: «Газ до 3000, 3-4с, сброс. → СТОП»
запись 12 PID каждые 250мс
🔴 [⏹ СТОП] — запись идёт
↓ тап
запись остановлена, данные в памяти
вывод: «Записано N отсчётов. ➤ для отправки.»
🟢 [▶ СТАРТ] — можно повторить тест
```
- После СТОП можно снова нажать СТАРТ — новый тест, старые данные сохраняются.
- **Отправка данных** — не кнопкой, а через ➤ в поле ввода.
## Поле вывода
- ScrollView, моноширинный шрифт
- После done — кнопка «✕ Закрыть» (сворачивает вывод, возвращает все кнопки)
- После Share в истории — возврат в приложение (стандартное поведение Android)
## Поле ввода + кнопка ➤
2 строки, всегда активно. Плейсхолдер: «Что беспокоит? Чем подробнее — тем лучше».
Кнопка ➤ справа:
- **Обычный режим**: текст из поля → отправка на сервер (`/api/v1/chat`) → сервер спрашивает LLM → ответ в вывод
- **После СТОП**: накопленные данные теста → отправка на сервер (`/api/v1/session/upload`) + текст (если есть) → сервер анализирует через LLM → ответ в вывод
- Ответ → в поле вывода
## История
- Кнопка «📋 История»
- Список последних 20 сессий (дата, заголовок, статус загрузки)
- Выбор → диагноз во всплывающем окне
- Кнопка «📤 Поделиться» → системный Share Sheet (Telegram, WhatsApp, Gmail...)
- После Share — возврат в наше приложение
## Что удаляется
- Кнопки «📡 Сервер», «🔌 ELM», «🚗 ЭБУ» как отдельные — заменены на иконки со светофорами
- Кнопки «⏱ На месте», «🚗 В движении» — всё через одну кнопку-трансформер
- `tvDtcStatus` («Сначала считай ошибки») — не нужен
- `cbFullMode` (чекбокс полной диагностики) — всегда полная
- `tvPrompt` (оверлей) — не нужен
- `btnDynStart` — не нужен
## Серверные изменения
Ничего нового — всё уже есть:
- `/api/v1/ping`
- `/api/v1/ping-llm`
- `/api/v1/chat`
- `/api/v1/session/upload` с `dynamic_samples`
## Текущий макет (реализовано)
```
elmAI v0.68 📡🟢 ELM🟢 ECU🟢 LLM🟢 ← одна строка
[ ОШИБКИ / ДИАГНОСТИКА / СТАРТ / СТОП ]
вывод
[ 📋 История ] ⏱ 12с ← таймер справа
[____________________________] [➤] ← 3 строки ввода
```
## Логика кнопки (стейт-машина)
| State | Текст | Цвет | Действие |
|-------|-------|------|----------|
| INIT | ⚠️ ОШИБКИ | 🟠 | scanDtc() |
| DTC | 🔍 ДИАГНОСТИКА | 🔵 | runDiagnostics() |
| DIAG | ▶ СТАРТ | 🟢 | startDynamicRecording() |
| START | ⏹ СТОП | 🔴 | stopDynamicRecording() |
| STOP | ▶ СТАРТ | 🟢 | не используется |
- Кнопка неактивна (alpha=0.4) если ELM 🔴 или ECU 🔴
- Поле ввода неактивно если LLM 🔴
- После DTC-сканирования ECU → 🟢
- После СТОП → DIAG (можно снова СТАРТ)
## Исправлено (v0.57 → v0.68)
| v | Что |
|---|-----|
| 0.57 | Layout v2, иконки, трансформер |
| 0.58 | Всё в одной строке |
| 0.59 | setIndicator в runOnUiThread |
| 0.60 | LLM → 🤓 |
| 0.61 | Таймер в строке Истории, нет ELM → кнопка неактивна |
| 0.62 | Поле ввода неактивно без LLM |
| 0.63 | 🤓 → 🎓 |
| 0.64 | 🎓 → LLM текст |
| 0.65 | СТОП работает, ECU 🟢 после сканирования |
| 0.66 | ensureConnected всегда перед dynamic test |
| 0.67 | Кнопка неактивна без ECU |
| 0.68 | Двойной вызов checkLlm/checkEcu убран, таймер в catch |
## Известные проблемы (TODO)
- `findElmDevice()` возвращает null при >1 устройствах (диалог асинхронный)
- Android 12+ — startChecks до получения BT-разрешений
- `State.STOP` не используется