diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 9237ae7..ffe873e 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -39,3 +39,67 @@ versionName = "0.42.0-dev" → versionName = "0.43.0-dev" - `refactor: ...` — переработка кода - `bump: ...` — повышение версии - `docs: ...` — документация + +## 4. Контекст проекта (РЕЗЮМЕ для нового чата) + +### Что это +elmAI — Android-приложение + Python-сервер для диагностики авто через ELM327. + +### Текущая версия +**v0.47.0-dev** (APK: https://obdai.ru/elmer.apk) + +### Репозитории +- Сервер: https://gitea.services.ngcloud.ru/Nail/elmer (ветка master) +- Android: https://github.com/Repinoid/elmer-android (ветка master) +- Сервер живёт на 5.172.178.213 (SSH: naeel@5.172.178.213, ключ ~/.ssh/naeel_vm_id_ed25519) + +### Деплой +```bash +# ВСЕГДА сначала bump версии в android/app/build.gradle.kts! +cd /home/naeel/elmer/android && git add -A && git commit -m "..." && git push origin master +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 \ + "cd /opt/elmer && rm -rf android && tar xzf /tmp/android-src.tar.gz && \ + cd android && gradle wrapper --gradle-version 8.7 && \ + export ANDROID_SDK_ROOT=\$HOME/android-sdk && \ + ./gradlew clean assembleDebug && \ + cp app/build/outputs/apk/debug/app-debug.apk /opt/elmer/web/static/" +``` + +### Структура проекта +``` +elmer/ + android/ — Android-приложение (Kotlin) + app/src/.../elm/ — ElmProtocol.kt, ElmChecker.kt + app/src/.../ui/ — MainActivity.kt + api/ — Flask API (Python) + brain/ — LLM-клиент (Python) + obd/ — ELM-протокол (Python) + doc/ — Документация, сессии + web/ — Flask web, статика +``` + +### Ключевые файлы +- `android/app/build.gradle.kts` — versionName (менять при КАЖДОМ деплое) +- `android/.../elm/ElmProtocol.kt` — стейт-машина AndrOBD (init, sendCommand) +- `android/.../elm/ElmChecker.kt` — checkDevice, checkEcu, scanDtc +- `android/.../ui/MainActivity.kt` — UI (~470 строк, надо разбить) + +### Что уже исправлено (сессия 2026-06-06) +- ELM v1.5 совместимость (init без ретраев, skip v2-команд) +- Статус-строка: append вместо overwrite +- BT-подключение: connect() идемпотентный +- Все таймауты сокращены (2000-3000мс вместо 5000-10000мс) + +### Что НЕ сделано (TODO) +- Разбить MainActivity.kt (~470 -> <=200 строк) +- Разбить ElmChecker.kt (~270 -> <=200 строк) +- Подробные комментарии перед функциями +- Полевой тест на машине + +### Важные правила +- ELM327 v1.5 — фейк (клоны v1.0/v1.4), НЕ слать ATAT1/AT@1/AT@2/ATST +- Все статусы через appendStatus("\n..."), не tvStatus.text = +- Таймер инита макс 14 секунд (было 88) +- Подробности: doc/session-2026-06-06.md diff --git a/doc/session-2026-06-06.md b/doc/session-2026-06-06.md index 7402920..b52139f 100644 --- a/doc/session-2026-06-06.md +++ b/doc/session-2026-06-06.md @@ -1,69 +1,53 @@ -# 2026-06-06 — Полевой тест и финальная проверка ELM +# 2026-06-06 — Полная сессия (полевой тест + 9 багов + фиксы) -## Контекст -Выезд к машине. Приложение показывает "No ELM", хотя сторонние приложения (Torque, Car Scanner) подключаются нормально. +## Текущий статус +- **Версия:** v0.47.0-dev +- **APK:** https://obdai.ru/elmer.apk +- **Сервер:** https://obdai.ru (5.172.178.213, nginx+gunicorn) +- **Android repo:** github.com/Repinoid/elmer-android +- **Server repo:** gitea.services.ngcloud.ru/Nail/elmer -## Найденные баги (и их исправления) +## Хронология коммитов (Android) -### 1. 🔴 КРИТИЧЕСКИЙ: `checkDevice()` не вызывал `connectAndInit()` -**Файл:** `ElmChecker.kt:69` -**Симптом:** Кнопка "🔌 ELM" показывала ❌ ELM не отвечает -**Причина:** В ходе рефакторинга `checkDevice()` был вынесен как отдельный метод, но вызов `connectAndInit()` был убран. AT-команды слались в никуда — BT-сокет не открывался. -**Исправление:** Вернул `if (!connectAndInit()) return null` в начало `checkDevice()`. -**Коммит:** `6a33048` +| Коммит | Описание | +|--------|----------| +| `6a33048` | fix: checkDevice() забыл connectAndInit() | +| `739afa9` | fix: connect() идемпотентный + run() без двойного connect | +| `94b890f` | bump v0.43.0-dev | +| `71618c6` | fix: статус-строка — append вместо overwrite | +| `d49f6d6` | fix: все appendStatus с \n, таймер на своей строке | +| `3ef3532` | fix: scriptRegistered сброс в onDestroy | +| `dead66c` | fix: init без ретраев, v1.5-совместимость | -### 2. 🟡 `connect()` не идемпотентный -**Файл:** `ElmChecker.kt:189` -**Проблема:** Повторный вызов `connect()` пытался открыть новый сокет поверх уже открытого → IOException. -**Исправление:** Добавлена проверка `if (socket?.isConnected == true) return` в начале `connect()`. -**Коммит:** `739afa9` +## Все 9 багов -### 3. 🟡 `run()` — двойной connect -**Файл:** `ElmChecker.kt:133` -**Проблема:** `run()` вызывал `connectAndInit()`, затем `checkDevice()` тоже вызывал `connectAndInit()` → двойное подключение. -**Исправление:** Убрал `connectAndInit()` из `run()`, так как `checkDevice()` сам подключается. -**Статус:** `run()` сейчас не используется в продакшене (UI вызывает методы по отдельности), но исправлен на будущее. -**Коммит:** `739afa9` +1. checkDevice без connectAndInit — AT-команды без BT-сокета +2. connect не идемпотентный — guard socket.isConnected +3. run двойной connect +4. Статус-строка overwrite — всё на appendStatus(\n...) +5. Таймер съедал заголовок — \n вместо пробела +6. scriptRegistered не сбрасывался после поворота +7. init() 70 секунд на ATAT1 — write+tryRead(2s) вместо exec +8. checkDevice слал v2-команды на v1.5 — проверка isV2 +9. recover/updateAtst/handle длинные таймауты — 2000-3000мс -## Архитектура вызовов (финальная) +## ELM327: версии и команды (Wikipedia) -Три пути в UI: +- **v1.5 НЕ СУЩЕСТВУЕТ** — клон v1.0/v1.4 с фейковой версией +- ATAT1 (adaptive timing): с v1.2 +- AT@1/AT@2 (device ID): с v1.3 +- ATST (set timeout): с v1.2 +- Базовые (ATI, ATDP, ATRV, ATSP, ATE0, ATL0, ATS0, ATWS): с v1.0 -### Путь 1: 🔌 ELM → 🚗 ЭБУ -``` -checkElm() → findElmDevice() → ElmChecker(dev, bt).checkDevice() - → connectAndInit() → connect() → elm.init() - → ATI, AT@1, AT@2, ATDP, ATRV, ATAT1 - → возвращает DeviceInfo - → checker сохранён в elmChecker (сокет НЕ закрыт) +## Правила для Copilot -checkEcu() → elmChecker.checkEcu() - → send("0100"), send("0902") - → возвращает EcuData - → сокет остаётся открытым (GC закроет) -``` +1. Коммит после каждой правки: git add -A && git commit -m "..." && git push +2. При деплое bump версии в android/app/build.gradle.kts +3. Формат: fix:/feat:/refactor:/bump:/docs: -### Путь 2: ⚠️ DTC -``` -scanDtc() → findElmDevice() → NEW ElmChecker(dev, bt).scanDtc() - → connectAndInit() → connect() → elm.init() - → send("03"), send("07") → parseDtcCodes() - → disconnect() ← сокет ЗАКРЫВАЕТСЯ - → возвращает List -``` +## TODO -### Путь 3: run() (не используется) -``` -run() → checkDevice() → connectAndInit() → ... → checkEcu() → disconnect() -``` - -## Текущее состояние -- Версия: **v0.42.0-dev** -- APK: https://obdai.ru/elmer.apk -- BT permissions: Android 12+ запрашиваются в onCreate() -- Сервер: работает, ping ОК -- Тесты: 133 шт (118 pass, 1 expected fail SQLite) - -## Не исправлено (потенциальные проблемы) -- После 🔌ELM → 🚗ЭБУ сокет не закрывается. Если потом нажать ⚠️DTC, создаётся второй сокет к тому же устройству. Некоторые ELM-клоны не держат два соединения. -- Нет таймаута на `checkElm()` — если ELM завис, поток висит бесконечно. +- [ ] Разбить MainActivity.kt (~470 -> <=200 строк) +- [ ] Разбить ElmChecker.kt (~270 -> <=200 строк) +- [ ] Подробные комментарии перед каждой функцией +- [ ] Полевой тест v0.47.0-dev на машине