# Архитектура elmAI > v0.77.0-dev, 7 июня 2026 ## Общая схема ``` 📱 Android (elmer-android) │ Bluetooth ▼ 🔌 ELM327 │ OBD-ответы ▼ 📱 Android (ScriptRunnerService) │ HTTPS POST /api/v1/session/upload ▼ 🌐 Сервер (5.172.178.213) ├── nginx :443 → gunicorn :8000 ├── obd/ — ELM327 протокол ├── brain/ — LLM-клиент ├── api/ — REST, БД, скрипты └── web/ — точка входа Flask, статика ``` ## Структура сервера ``` elmer/ ├── obd/ # Модуль 1: ELM327 протокол │ └── protocol.py # AndrOBD — стейт-машина (1:1 копия AndrOBD) │ # State, Rsp, AdaptiveTiming │ ├── brain/ # Модуль 2: LLM-взаимодействие │ ├── client.py # Diagnoser — HTTP к api.aillm.ru │ └── prompts.py # SYSTEM_PROMPT для диагностики │ ├── api/ # Модуль 3: REST API + БД │ ├── config.py # Загрузка config.yaml │ ├── db.py # SQLite (sessions, cars, dtc) │ ├── routes.py # Все эндпоинты (5 шт) │ ├── scripts.py # Сборка диагностических скриптов │ └── parser.py # Парсинг ответов ELM327 │ ├── web/ # Веб-интерфейс │ ├── app.py # Точка входа Flask │ ├── templates/index.html │ └── static/app-debug.apk │ ├── tools/ # Разработка │ ├── mock_elm327_v2.py # Мок ELM327 (TCP) │ └── test_androbd.py # Тесты стейт-машины │ ├── doc/ # Документация │ ├── architecture.md # Этот файл │ ├── roadmap.md │ └── session-*.md # Логи сессий │ ├── config.yaml # LLM API key, порты └── requirements.txt ``` ## Взаимодействие модулей ``` web/app.py └─ import api/routes.py ├─ import api/config.py → config.yaml ├─ import api/db.py → SQLite ├─ import api/scripts.py → сборка скриптов ├─ import api/parser.py → парсинг батча ├─ import brain/client.py → Diagnoser → api.aillm.ru └─ import brain/prompts.py → SYSTEM_PROMPT ``` Каждый модуль можно тестировать отдельно. Циклических зависимостей нет. ## API эндпоинты | Метод | Путь | Описание | Время | |---|---|---|---| | GET | /api/v1/ping | Проверка сервера | ~5мс | | GET | /api/v1/ping-llm | Проверка LLM | ~2с | | GET | /api/v1/script?mode= | Скрипт диагностики | ~50мс | | POST | /api/v1/session/upload | Загрузка батча + LLM | ~30-120с | | POST | /api/v1/chat | Вопрос к LLM | ~5-15с | ## Android (отдельный репо) ``` elmer-android/app/src/main/java/ru/elmer/client/ ├── ElmProtocol.kt # ELM327 стейт-машина ├── ObdDecoder.kt # Декодер PID/DTC/VIN ├── ServerClient.kt # HTTP к серверу (retry 3x) ├── ScriptEngine.kt # Движок скриптов ├── ScriptRunnerService.kt # Фоновая диагностика ├── SessionDb.kt # Локальная история ├── MainActivity.kt # UI ├── TestService.kt # (устарел) └── ElmForwardService.kt # (устарел) ``` ## CI/CD и деплой **Никаких сторонних CI/CD-сервисов (GitHub Actions, GitLab CI, Jenkins и т.д.). Всё вручную.** ### Сервер (elmer) ``` Локально: git push gitea master │ ▼ Сервер: ssh obdai.ru cd /opt/elmer && git pull origin master sudo systemctl restart elmer ``` - Репо: `gitea.services.ngcloud.ru/Nail/elmer` - Ветка: `master` - Сервис: `gunicorn -w 4 -b 127.0.0.1:8000 web.app:app` - Прокси: nginx :443 → 127.0.0.1:8000 - Конфиг: `/opt/elmer/config.yaml` ### Android APK (elmer-android) ``` Локально: cd android && ./gradlew assembleDebug scp app/build/outputs/apk/debug/app-debug.apk obdai.ru:/opt/elmer/web/static/ ``` - Репо: `github.com/Repinoid/elmer-android` - Сборка: `./gradlew assembleDebug` - Доставка: `scp` на сервер в `web/static/app-debug.apk` - Ссылка для пользователей: `https://obdai.ru/elmer.apk` - APK обновляется **только** при изменениях в Android-коде ### Версионирование | Где | Файл | |-----|------| | APK | `android/app/build.gradle.kts` → `versionName` | | Сайт | `web/templates/index.html` | | Документация | заголовки `.md` файлов | **Версию менять одновременно во всех трёх местах.**