Files

15 KiB
Raw Permalink Blame History

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.jsonassets/, 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/<mac> Профиль скорости 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. Сервер

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)

# 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

# Аналогично 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 Этот файл — полное описание проекта
PLANS.md Мастер-план: что сделано, что предстоит
doc/architecture.md Архитектура сервера и Android
doc/diagnostic-logic.md 5 режимов диагностики
doc/failures-journal.md 12 провалов при разработке raw-реле
doc/SETUP.md Настройка окружения
doc/CHANGELOG.md История версий
doc/STRUCTURE.md Полное дерево файлов
doc/QUICKSTART.md Быстрый старт
doc/resume.txt Краткое резюме для нового чата
.github/copilot-instructions.md Правила для Copilot
android/README.md Документация Android-проекта
android/RAW-FIX-PLAN.md План исправлений raw-реле
android/doc/opus-response-arch-2026-07-10.md Анализ архитектуры от Opus
android/doc/opus-response-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