# elmAI — полное описание проекта для AI-агентов > Последнее обновление: 2026-07-10 | Версия app: 1.18.0-dev | Версия raw: 0.4.1-dev --- ## 1. ЧТО ЭТО elmAI — OBD2-диагностика автомобиля через ELM327-адаптер + LLM (DeepSeek). Телефон подключается к ELM327 по Bluetooth, собирает данные с ЭБУ, отправляет на сервер, сервер анализирует через LLM и возвращает диагноз. --- ## 2. РЕПОЗИТОРИИ | Репо | URL | Ветка | Что внутри | |------|-----|-------|-----------| | **Сервер** | `gitea.services.ngcloud.ru/Nail/elmer` | `dynamic-tests` | Python Flask + elmAI бэкенд | | **Android** | `github.com/Repinoid/elmer-android` | `opus-fixes` | Kotlin Android-приложение | **ВАЖНО**: Android-репо лежит ВНУТРИ серверного: `/home/naeel/elmer/android/`. Это отдельный git-репо со своим remote. Коммитить и пушить надо ИЗНУТРИ `android/`. --- ## 3. СЕРВЕР (obdai.ru, 5.172.178.213) ``` elmer/ ├── api/ # Flask API │ ├── routes.py # Основные эндпоинты (script, upload, chat, probe, sessions) │ ├── raw_elm.py # Командная очередь для raw-реле (SQLite table command_queue) │ ├── db.py # SQLite (sessions, device_profiles, command_queue) │ ├── scripts.py # Сборка диагностических скриптов L0/L1/L2 + dynamic │ ├── parser.py # Парсинг ответов ELM327 (PID, DTC, VIN) │ ├── dtc.py # Эндпоинты DTC │ ├── ping.py # Эндпоинты ping/ping-llm │ └── config.py # Загрузка config.yaml ├── brain/ # LLM-клиент │ ├── client.py # Diagnoser — HTTP к DeepSeek │ └── prompts.py # Промпты для диагностики ├── obd/ # ELM327 протокол (Python) │ ├── protocol.py # Стейт-машина AndrOBD (ElmProt.java) │ ├── connection.py, commands.py, classifier.py, probe.py, state.py, timing.py ├── web/ # Flask web │ ├── app.py # Точка входа, регистрация blueprints │ ├── templates/index.html # Страница загрузки APK │ └── static/ # APK-файлы ├── doc/ # ВСЯ документация ├── config.yaml # API-ключи, порты └── deploy.sh # Скрипт деплоя ``` **Стек**: Python 3, Flask, gunicorn (4 воркера, порт 8000), nginx (:443 → :8000), SQLite. **Сервис**: `sudo systemctl restart elmer` --- ## 4. ANDROID ### 4.1. Основное приложение (`app/`) — прямая диагностика **Пакет**: `ru.elmer.client` | **Версия**: 1.18.0-dev (versionCode 38) ``` app/src/main/java/ru/elmer/client/ ├── Config.kt # Константы: HOST, SCRIPT_URL, defaultScript(), client() ├── db/SessionDb.kt # SQLite: sessions, responses ├── elm/ │ ├── ElmProtocol.kt # Стейт-машина AndrOBD (1:1 с ElmProt.java) │ ├── ElmChecker.kt # Проверка ELM: checkDevice(), checkEcu(), scanDtc(), sendRaw() │ └── ObdDecoder.kt # Декодер PID/DTC/VIN (object-синглтон) ├── script/ │ └── DynamicCollector.kt # Циклический опрос PID с интервалом ├── server/ │ └── ServerClient.kt # HTTP к серверу (OkHttp): ping, pingLlm, chat, getSessions, uploadSession, downloadScript └── ui/ └── MainActivity.kt # UI: индикаторы, кнопка-трансформер, чат, диагностика, динамический тест ``` **8 классов**. Зависимости: OkHttp 4.12.0, AndroidX, org.json. БЕЗ Room, Coroutines, DI. **Поток диагностики**: MainActivity → ElmChecker → ElmProtocol → команды → ObdDecoder → SessionDb → ServerClient.uploadSession() → ответ от LLM. ### 4.2. Raw-реле (`raw/`) — ретранслятор команд **Пакет**: `ru.elmer.raw` | **Версия**: 0.4.1-dev (versionCode 18) ``` raw/src/main/java/ru/elmer/raw/ ├── ElmProtocol.kt # 1:1 копия app/ElmProtocol.kt ├── ElmActor.kt # Single-thread executor вокруг ElmProtocol ├── RawRelayService.kt # Foreground-сервис: BT→init→поллинг команд→ответ ├── RelayClient.kt # HTTP к /api/v1/elm/raw/* (OkHttp, БЕЗ X-Api-Key) └── MainActivity.kt # Минимальный UI (выбор BT, статус, счётчики) ``` **5 классов**. Отдельный APK (`applicationId: ru.elmer.raw`). **Поток**: RawRelayService → connectBt → ElmProtocol.init() → hello → цикл: pollCommand → sendCommand → postResponse. **Назначение**: тупой ретранслятор. Сервер диктует команды, телефон передаёт в ELM и возвращает ответы. Используется для интерактивной диагностики через Copilot и тестов 3 мин / 5 мин. --- ## 5. ANDROID — ЧТО СДЕЛАНО (рефакторинг 2026-07-10) Ветка `opus-fixes`, 8 коммитов: 1. **Config.kt** — единый источник хоста (`https://obdai.ru`), замена всех хардкодов 2. **default_script.json** → `assets/`, DEFAULT_SCRIPT из кода удалён 3. **ServerClient** — добавлены `chat()` и `getSessions()`, весь HTTP через OkHttp + X-Api-Key 4. **HttpURLConnection** выпилен из MainActivity 5. **ElmChecker.sendRaw()** — инкапсуляция ElmProtocol, `getElm()` удалён 6. **FQN → import** — все полные имена заменены на нормальные import'ы 7. **Удалён мёртвый код**: ScriptRunnerService, ScriptEngine, UploadProgress + FOREGROUND_SERVICE permissions **Результат**: 8 классов (было 10), 0 HttpURLConnection, 0 FQN, 0 getElm(), 0 obdai.ru вне Config, весь HTTP аутентифицирован. --- ## 6. ANDROID — ЧТО НЕ СДЕЛАНО (TODO) ### app/ - Разбить MainActivity (~750 строк) — вынести логику из UI - Разбить ElmChecker (372 строки) — отделить BT от ELM-команд - v1.5 клоны: деградация после 10-12 команд (ограничение железа) ### raw/ - **deviceId** генерится заново при каждом создании RelayClient — сохранить в SharedPreferences - **Нет аутентификации** — BuildConfig.API_KEY есть, но RelayClient его не шлёт - **Нет retry** при ошибках HTTP - **SERVER_URL** захардкожен в build.gradle.kts и дублируется в Intent extra - **drainInput() в write()** — потенциальный сдвиг буфера (Неудача #5 из failures-journal.md) ### Сервер - Script Engine для режимов «3 мин на месте» / «5 мин в движении» — НЕ РЕАЛИЗОВАН - Дублирование: routes.py и script_endpoint.py (script_endpoint.py — мёртвый) --- ## 7. РЕЖИМЫ ДИАГНОСТИКИ ### Режим 1: Прямая диагностика (app/) Однократный сбор данных: скрипт → батч ответов → сервер → LLM → диагноз. ### Режим 2: Динамический тест (app/) Циклический опрос PID. Кнопка СТАРТ/СТОП. Сервер подбирает тайминги через `/api/v1/test/next`. ### Режим 3: Raw-реле (raw/) Сервер управляет потоком команд. Телефон — тупой ретранслятор. ### Режим 4: Прогрев на месте (raw/, 3 минуты) 3 PID (RPM, темп, дроссель) каждые 2 секунды × 90 циклов = 270 запросов. Оценка прогрева, холостых, реакции на газ. ### Режим 5: В движении (raw/, 5 минут) Те же 3 PID каждые 2 секунды × 150 циклов = 450 запросов. Нагрузочный тест, динамика разгона. *Режимы 4 и 5 требует реализации Script Engine на сервере.* --- ## 8. API ЭНДПОИНТЫ ### Основные (app/) | Метод | Путь | Назначение | |-------|------|-----------| | GET | `/api/v1/ping` | Проверка сервера | | GET | `/api/v1/ping-llm` | Проверка LLM | | GET | `/api/v1/script?mode=test` | Скрипт диагностики | | POST | `/api/v1/session/upload` | Загрузка батча + LLM-анализ | | POST | `/api/v1/chat` | Чат с LLM | | GET | `/api/v1/sessions` | Список сессий | | POST | `/api/v1/test/next` | Следующий шаг динамического теста | | GET/PUT | `/api/v1/elm/profile/` | Профиль скорости ELM | ### Raw-реле (raw/) | Метод | Путь | Назначение | |-------|------|-----------| | POST | `/api/v1/elm/raw/hello` | Android: «я готов» (чистит старые команды) | | POST | `/api/v1/elm/raw/cmd` | Copilot/сервер: поставить команду в очередь | | GET | `/api/v1/elm/raw/cmd?device_id=X` | Android: забрать pending команду | | POST | `/api/v1/elm/raw/response` | Android: вернуть ответ | | GET | `/api/v1/elm/raw/response?device_id=X&seq=N` | Copilot: прочитать ответ | | GET | `/api/v1/elm/raw/status` | Статус устройства | --- ## 9. ДЕПЛОЙ ### 9.1. Сервер ```bash cd /home/naeel/elmer git add -A && git commit -m "..." && git push origin dynamic-tests ssh -i ~/.ssh/naeel_vm_id_ed25519 naeel@5.172.178.213 " cd /opt/elmer && git checkout dynamic-tests && git pull origin dynamic-tests pip install -r requirements.txt sudo systemctl restart elmer " ``` ### 9.2. Android APK (app) ```bash # 1. Bump версии в app/build.gradle.kts (versionCode и versionName) cd /home/naeel/elmer/android sed -i 's/versionCode = XX/versionCode = YY/' app/build.gradle.kts sed -i 's/versionName = "X.Y.Z-dev"/versionName = "X.Y+1.Z-dev"/' app/build.gradle.kts # 2. Закоммитить + запушить git add -A && git commit -m "bump vX.Y+1.Z-dev" && git push origin opus-fixes # 3. Залить исходники на сервер и собрать APK 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 " rm -rf /opt/elmer/android && tar xzf /tmp/android-src.tar.gz -C /opt/elmer/ cd /opt/elmer/android && gradle wrapper --gradle-version 8.7 export ANDROID_SDK_ROOT=\$HOME/android-sdk ./gradlew :app:clean :app:assembleDebug cp app/build/outputs/apk/debug/app-debug.apk /opt/elmer/web/static/ " # 4. Обновить версию в /opt/elmer/web/templates/index.html и /opt/elmer/templates/index.html ``` ### 9.3. Raw APK ```bash # Аналогично app, но: # - bump версии в raw/build.gradle.kts # - сборка: ./gradlew :raw:assembleDebug # - копия: cp raw/build/outputs/apk/debug/raw-debug.apk /opt/elmer/web/static/elm-raw-v022.apk ``` --- ## 10. ПРАВИЛА (НЕ НАРУШАТЬ) 1. **НИЧЕГО не делать без прямого указания пользователя.** Даже если видишь проблему — только сказать. 2. **На вопрос — только ответ.** Не продолжать «а ещё могу...», не предлагать помощь. 3. **После выполнения команды — сказать «готово» и ЖДАТЬ.** 4. **Коммит + push после КАЖДОЙ правки.** Один коммит = одна правка. Формат: `fix:`, `feat:`, `refactor:`, `bump:`, `docs:`, `style:`, `chore:`. 5. **При деплое — всегда bump версии.** Инкрементировать патч (Z в X.Y.Z-dev). 6. **ELM327 — только как AndrOBD (ElmProt.java).** Никакой самодеятельности в протоколе. Init: ATSP0→ATAT1→ATS0→ATL0→ATE0. Никакого drainInput() перед write(). 7. **Не материться.** Пользователь матерится — ты нет. 8. **Не гадать.** Если не уверен — проверить факты чтением кода. 9. **Код правит ТОЛЬКО пользователь или Copilot по команде.** Не исполнять советы Opus по ELM-командам — Opus специалист по архитектуре кода, а не по ELM327. --- ## 11. КЛЮЧЕВЫЕ ДОКУМЕНТЫ | Файл | Содержание | |------|-----------| | `AGENTS.md` | Этот файл — полное описание проекта | | `doc/architecture.md` | Архитектура сервера и Android | | `doc/diagnostic-logic.md` | 5 режимов диагностики | | `doc/failures-journal.md` | 12 провалов при разработке raw-реле | | `doc/SETUP.md` | Настройка окружения | | `STRUCTURE.md` | Полное дерево файлов | | `resume.txt` | Краткое резюме для нового чата | | `.github/copilot-instructions.md` | Правила для Copilot | | `android/doc/opus-arch-questions-2026-07-10.md` | Вопросы Opus по архитектуре | | `android/doc/opus-refactor-plan-2026-07-10.md` | План рефакторинга от Opus | --- ## 12. КОНТАКТЫ / ДОСТУП - **Сервер**: 5.172.178.213, SSH: `naeel@5.172.178.213`, ключ: `~/.ssh/naeel_vm_id_ed25519` - **Домен**: obdai.ru (SSL через certbot) - **Gitea**: gitea.services.ngcloud.ru/Nail/elmer - **GitHub**: github.com/Repinoid/elmer-android