diff --git a/.instructions.md b/.instructions.md deleted file mode 100644 index 6e5ce3f..0000000 --- a/.instructions.md +++ /dev/null @@ -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 # Локальный запуск -``` diff --git a/analysis.md b/analysis.md deleted file mode 100644 index 9286396..0000000 --- a/analysis.md +++ /dev/null @@ -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 ` -- [ ] Привязать к `/dev/rfcomm0`: `rfcomm bind 0 ` -- [ ] `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/` -- [ ] База: миграция 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.* diff --git a/idea.md b/idea.md deleted file mode 100644 index 6f7e912..0000000 --- a/idea.md +++ /dev/null @@ -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, браузер | diff --git a/legacy-deploy.sh b/legacy-deploy.sh deleted file mode 100755 index b7ec436..0000000 --- a/legacy-deploy.sh +++ /dev/null @@ -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 diff --git a/legacy-resume.txt b/legacy-resume.txt deleted file mode 100644 index e58b1fb..0000000 --- a/legacy-resume.txt +++ /dev/null @@ -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 — НИЧЕГО не делать без прямого указания diff --git a/logo.jpg b/logo.jpg deleted file mode 100755 index ae181c5..0000000 Binary files a/logo.jpg and /dev/null differ diff --git a/morda.md b/morda.md deleted file mode 100644 index 1c47354..0000000 --- a/morda.md +++ /dev/null @@ -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` не используется