docs(domain E): v2 — ретро-ревью pass-2 (5 находок) + tech-stack ISO-TP

- ISO-TP (ISO 15765-2): нативный CAN-OBD требует can-isotp/CAN_ISOTP для multiframe
  (Mode 03 DTC, Mode 09 VIN), не голый socketcan; адресация 0x7DF/0x7E8..0x7EF
- планировщик опроса: бюджет req/s на транспорт (ELM327 half-duplex) + приоритеты PID,
  round-robin при насыщении; эффективная частота = min(desired, потолок, доля бюджета)
- §5a безопасность активного опроса: гейт по движению, предпочтение passive listen-only,
  fail-safe при аномалиях шины, риск ретрофита; «безобидность» read-запросов условна
- §5b отказ/восстановление транспорта: bus-off + restart-ms, ELM327 reconnect,
  Online=false → unavailable, без зависания (#4)
- владение computed: core (состояние/мгновенный расход) vs плагин (trip-производные)
- tech-stack: CAN/OBD row + ISO-TP

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-21 01:27:25 +03:00
parent 02f13db1f3
commit 08d787d977
2 changed files with 39 additions and 6 deletions
+38 -5
View File
@@ -3,8 +3,8 @@
> Привилегированный core-сервис: **единственный владелец доступа к CAN/OBD**. Читает
> данные машины, публикует сигналы на шину, читает DTC. Сердце killer-фичи.
Статус: **v1 (на ревью).**
Связано с: [ipc.md](../contracts/ipc.md) (`VehicleData`) · [data-model.md](../contracts/data-model.md) · [hardware.md](../contracts/hardware.md) (CAN) · [security-privacy.md](../contracts/security-privacy.md) · [principles.md](../principles.md) (#2) · домен D (Assistant)
Статус: **v2 (на ревью).** v2 — после ретро-ревью (5 находок).
Связано с: [ipc.md](../contracts/ipc.md) (`VehicleData`) · [data-model.md](../contracts/data-model.md) · [hardware.md](../contracts/hardware.md) (CAN) · [security-privacy.md](../contracts/security-privacy.md) · [principles.md](../principles.md) (#1,#2,#4) · [plugin-sdk.md](../contracts/plugin-sdk.md) (trip — у плагина) · домен D
---
@@ -29,7 +29,8 @@
| Состояние машины (`off`/`acc`/`running`) | **MVP** | — | v2 |
| Подписка с rate-cap (~1020 Гц) | **MVP** | ipc | v2 |
| Pending/permanent DTC (Mode 07/0A) | later | — | v2+ |
| Производные (расход / trip) | later | trip-стейт, storage | v2/v3 |
| Мгновенный расход (computed, **core**) | later | fuel_rate/MAF | v2/v3 |
| Trip-производные (пробег/средний) | — | **у плагина** (свой trip-стейт, plugin-sdk §8) | — |
| Топливные коррекции (fuel trim 06–09) — «вырос расход» | later | — | later |
| VIN (Mode 09) | later | — | later |
| Пассивный сниффинг broadcast (DBC) | later | native CAN, DBC | later |
@@ -41,12 +42,22 @@
- **Публикует:** `ru.shturman.VehicleData` (методы/сигналы/properties — [ipc](../contracts/ipc.md) §3).
- **Сигналы** — по каталогу [data-model](../contracts/data-model.md); транспорт-агностичны.
- **Источник:** ELM327 (serial/BT) и нативный **SocketCAN** (крейт `socketcan`).
- **ISO-TP для нативного CAN-OBD (важно):** CAN-based OBD (ISO 15765-4) требует транспорт
**ISO-TP (ISO 15765-2)** — сегментация/сборка/flow-control multiframe-ответов (Mode 03 — много
DTC, Mode 09 — VIN): ядровой `can-isotp` (сокеты `CAN_ISOTP`), **не голый `socketcan`**.
Адресация: функц. запрос `0x7DF`, ответы ECU `0x7E8..0x7EF` (несколько ECU — собираем/дедупим
по source-ID). Голый `socketcan` — для пассивного сниффинга (DBC); OBD-поллинг — через ISO-TP.
ELM327 прячет ISO-TP в прошивке (касается только нативного пути).
- **Покрытие протоколов (важно для старых авто):** OBD-II ходит поверх разных нижних
протоколов. **Native SocketCAN — только CAN-based OBD** (авто ~2008+). Старые не-CAN
(K-line ISO 9141/KWP2000, J1850) — через **ELM327** (мульти-протокольный). Поэтому
ELM327-путь держим живым, не только «на старте» — это охват простых Lada/ретрофита.
- **Опрос коалесцируется:** один PID опрашивается раз на максимальной запрошенной
частоте, результат раздаётся всем подписчикам (не per-subscriber).
- **Опрос: коалесцирование + планировщик/бюджет.** Один PID опрашивается раз на макс.
запрошенной частоте, раздаётся всем (не per-subscriber). При насыщении (Σ подписок × Гц >
пропускной способности) — **бюджет req/s на транспорт** (ELM327 half-duplex, один запрос за
раз, несколько PID/с; нативный CAN выше) + приоритеты/веса PID, round-robin. Эффективная
частота PID = `min(desired_max_hz, потолок шины, доля бюджета)`; приоритетный набор
(`mil_on`+DTC) держит приоритет при насыщении. Управляет *получением*; доставку клиент прореживает сам.
- **DTC-база** (статическая, `vehicle/dtc/`) — живёт в этом домене.
## 4. Приоритизация под простые авто *(резолв routed-вопроса)*
@@ -68,6 +79,25 @@
- 🟡 *Выбор:* своя **RU-база из открытых списков** generic-кодов (рек.) vs готовая.
Vendor-коды (`P1xxx`) — later, через vendor-базы.
## 5a. Безопасность активного опроса
Потолок ~10–20 Гц (ipc) — *пропускная*, не safety-граница. На живой powertrain-шине:
- **Гейт по движению:** в движении снижаем интенсивность TX и набор PID (используем speed,
уже заведённый для distraction) — бюджет нагрузки на шину.
- **Предпочитаем пассивный listen-only** (broadcast/DBC), где сигнал доступен так, а не активный опрос.
- **Fail-safe:** при аномалиях шины / конфликтах диагностической сессии — backoff/стоп активного опроса.
- **Риск ретрофита на незнакомом авто** (капризные шлюзы/ECU, коллизии сессий) — Lada/энтузиаст целевые.
- Уточняет принцип #2: «безобидность» read-запросов **условна** — на ограниченный, motion-aware, fail-safe TX.
## 5b. Отказ и восстановление транспорта
- **Нативный SocketCAN:** детект error-passive / **bus-off**; авто-восстановление (re-init,
`restart-ms`), чтобы один сбой не глушил сервис навсегда; rate-limit попыток + лог error-storm (как домен A).
- **ELM327 (USB/BT):** детект потери линка; reconnect с backoff; re-probe при реконнекте (причуды клонов — §7).
- **ISO-TP/multiframe таймауты** — отдельно от single-frame `GetSignal`-таймаута.
- **При падении транспорта:** `Online=false` (ipc), затронутые сигналы → `unavailable` (не `stale`),
без зависания/краха (#4); при восстановлении — re-probe.
## 6. Зависимости
- **Вниз:** hardware (CAN-транспорт, listen-only/polling), data-model (каталог),
@@ -97,3 +127,6 @@
| MVP-ядро | `mil_on` (PID 01) + DTC (Mode 03) — универсально; богатые PID best-effort | 2026-06-16 |
| DTC-база | своя RU из открытых generic-списков (🟡); vendor-коды later | 2026-06-16 |
| Расшифровка | статическая база (код→описание) + LLM (человеческое объяснение) | 2026-06-16 |
| Транспорт нативного OBD | ISO-TP (`can-isotp`), не голый socketcan; адресация 0x7DF/0x7E8+ | 2026-06-16 |
| Опрос | бюджет req/s на транспорт + приоритеты; гейт по движению; fail-safe/recovery (bus-off) | 2026-06-16 |
| Computed | core: состояние/мгновенный расход; trip-производные — у плагина | 2026-06-16 |