diff --git a/doc/architecture.md b/doc/architecture.md index d07ccfd..8f85d58 100644 --- a/doc/architecture.md +++ b/doc/architecture.md @@ -1,88 +1,102 @@ -# Архитектура Elmer (2026-05-25) +# Архитектура elmAI -## Принцип: тонкий клиент +> v0.28.0-dev, 29 мая 2026 -Клиент ничего не знает о диагнозе. Только транспорт: +## Общая схема ``` -ELM327 ←Bluetooth SPP→ Android Client ←HTTP JSON→ Сервер ←API→ DeepSeek +📱 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, статика ``` -## Режимы работы клиента - -### Режим «опрос» (основной) -Клиент сам читает VIN + DTC + PID'ы, шлёт готовый JSON серверу. -Быстро: один HTTP-запрос на сессию. - -### Режим «ретранслятор» (расширенный) -Сервер шлёт сырые AT-команды, клиент пересылает ответ. -Медленно (каждый PID — HTTP round-trip), но клиент вообще ничего не знает об OBD2. - -## Универсальность - -- Пользователь вводит URL сервера (или наш по умолчанию) -- Протокол HTTP/JSON документирован -- Любой backend может работать с этим клиентом - -## Десктоп (Windows/Linux) +## Структура сервера ``` -Браузер (Chrome) → локальный Flask → pyserial → ELM327 +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 ``` -- Отдельного «приложения» для Windows не нужно -- `web/app.py` — и тестовый UI, и прототип сервера -- Chrome на Android НЕ может: Web Bluetooth API только BLE, Web Serial API не поддерживается +## Взаимодействие модулей -## Открытость и доверие - -| Что | Где | Зачем | -|---|---|---| -| **Клиент (Android)** | GitHub (открытый) | Доверие — любой может проверить код, собрать сам | -| **Сервер (Python)** | Gitea (закрытый) | API-ключи, логика, коммерческая часть | -| **Публикация** | RuStore | Бесплатно, модерация = дополнительное доверие | - -## Git-стратегия - -- `gitea.services.ngcloud.ru/Nail/elmer` — разработка сервера (текущий репо) -- `github.com/Nail/elmer-android` — клиент (будет создан), лицензия MIT -- Серверный репо на GitHub НЕ публикуем - -## База данных - -### SQLite (MVP) ``` -cars — VIN, марка, модель, год, двигатель -diagnostic_tokens — id (PK), car_id (FK), created_at -llm_messages — token_id (FK), role, content, timestamp -ecu_parameters — token_id (FK), pid_code, value, unit, timestamp -dtc_codes — token_id (FK), code, description, status +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 ``` -### PostgreSQL (production) -Та же схема, миграция при переходе к production-серверу. +Каждый модуль можно тестировать отдельно. Циклических зависимостей нет. -## API (прототип) +## API эндпоинты -### POST /api/diagnose -```json -// Request (от клиента) -{ - "vin": "WVWZZZ1KZAW123456", - "dtc_codes": [{"code": "P0301", "status": "stored"}], - "parameters": [{"pid_code": "0105", "name": "coolant_temp", "value": 85.0, "unit": "°C"}] -} +| Метод | Путь | Описание | Время | +|---|---|---|---| +| 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с | -// Response (от сервера) -{ - "diagnosis": "## Краткий диагноз\n...", - "token_id": 42 -} +## 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 # (устарел) ``` -## Безопасность - -- Permissions Android: только BLUETOOTH + INTERNET -- Никаких SMS/контактов/файлов/звонков -- Пользователь видит permissions ДО установки (RuStore и sideload) -- Модерация RuStore — базовая проверка на вредоносный код +Планируется рефакторинг в пакеты: `elm/`, `server/`, `script/`, `db/`, `ui/`, `test/`.