- obd/probe.py: трехуровневый каскад (L0/L1/L2) - obd/commands.py: каталог всех AT-команд с метаданными - obd/classifier.py: классификация ответов + определение уровня - obd/connection.py: транспортный слой (SerialTransport) - obd/protocol.py: init() только база, без ATAT1/ATST - api/db.py: таблица device_profiles по BT MAC - api/scripts.py: три уровня скриптов (l0/l1/l2) - api/routes.py: /elm/probe, /elm/profile/<mac>, /script?level= - web/templates/index.html: v0.48.0 - CHANGELOG.md, doc/architecture.md, resume.txt: версии
5.3 KiB
5.3 KiB
Архитектура elmAI
v0.48.0, 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 файлов |
Версию менять одновременно во всех трёх местах.