7a30ed7a7d
Существенная переработка power-lifecycle: - детект running по НАПРЯЖЕНИЮ бортсети (~14В генератор vs ~12.4В покой), не RPM (v2); Power.IgnitionState — единственный канон lifecycle-состояния - триггер shutdown ≠ rate-of-change: ACC-off / under-voltage-held / thermal-trip; cold-crank до ~6В — НОРМА (ride-through), не индикатор обрыва - SoC↔MCU shutdown-протокол специфицирован СЕЙЧАС: hold-up-таймер + heartbeat + safe-to-cut + fail-safe при потере линка (обе стороны); MCU — fail-safe-авторитет - abort при re-power до PONR (ShutdownAborted); shutting-down разбит abortable/committed - НОВОЕ: thermal shutdown (триггер/гистерезис/UX); ordered teardown (E закрывает ISO-TP); таблица MCU-vs-supercap; battery deep-discharge cutoff; монотонные часы для таймеров; первый boot без времени; периодическое сохранение времени - watchdog по фазам (runtime + shutdown RebootWatchdogSec/MCU-дедлайн + boot-окно); v0=SoC+MCU+reboot, bootcount=v4 - фазы: MCU HW fail-safe-таймер = v0 (не v1); save-time = v0 - кросс-док: security-privacy (mic power-gated), ipc Power (enum/reason/ShutdownAborted), e/data-model (engine_running не дублирует IgnitionState), a-base §7 (периодич. save) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
135 lines
12 KiB
Markdown
135 lines
12 KiB
Markdown
# Домен E — Vehicle-Data (OBD/CAN, read-only)
|
||
|
||
> Привилегированный core-сервис: **единственный владелец доступа к CAN/OBD**. Читает
|
||
> данные машины, публикует сигналы на шину, читает DTC. Сердце killer-фичи.
|
||
|
||
Статус: **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
|
||
|
||
---
|
||
|
||
## 1. Назначение и границы
|
||
|
||
- **Что делает:** читает OBD-II (PID/DTC) и/или broadcast-кадры (native CAN + DBC),
|
||
перемалывает в digested-сигналы ([data-model](../contracts/data-model.md)),
|
||
публикует через `ru.shturman.VehicleData` ([ipc](../contracts/ipc.md) §3).
|
||
- **Единственный, кто трогает CAN** → архитектурно держит red-line (принцип #2).
|
||
- **Границы (точный red-line):** только диагностические **read-запросы** + пассивное
|
||
чтение; **никаких** управляющих/actuator/write/Mode-04. Человеческую расшифровку
|
||
НЕ делает (это LLM/ассистент) — отдаёт код + стандартное описание.
|
||
|
||
## 2. Функции
|
||
|
||
| функция | MVP/later | зависит от | фаза |
|
||
|---------|-----------|------------|------|
|
||
| Live-сигналы (стандартные PID) | **MVP** | data-model, hardware(CAN) | v2 |
|
||
| **MIL-статус + DTC count** (PID 01) | **MVP** | — | v2 |
|
||
| Чтение DTC (Mode 03) + расшифровка по базе | **MVP** | dtc-база | v2 |
|
||
| Пробинг поддерживаемых PID | **MVP** | — | v2 |
|
||
| `engine_running` (running/stopped/unknown, из RPM) — НЕ дублирует `Power.IgnitionState` | **MVP** | — | v2 |
|
||
| Подписка с rate-cap (~10–20 Гц) | **MVP** | ipc | v2 |
|
||
| Pending/permanent DTC (Mode 07/0A) | later | — | v2+ |
|
||
| Мгновенный расход (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 |
|
||
| Vendor DTC (`P1xxx`) через vendor-базу | later | vendor DB | later |
|
||
| Лог поездок | later | storage | later |
|
||
|
||
## 3. Данные и интерфейсы
|
||
|
||
- **Публикует:** `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). При насыщении (Σ подписок × Гц >
|
||
пропускной способности) — **бюджет req/s на транспорт** (ELM327 half-duplex, один запрос за
|
||
раз, несколько PID/с; нативный CAN выше) + приоритеты/веса PID, round-robin. Эффективная
|
||
частота PID = `min(desired_max_hz, потолок шины, доля бюджета)`; приоритетный набор
|
||
(`mil_on`+DTC) держит приоритет при насыщении. Управляет *получением*; доставку клиент прореживает сам.
|
||
- **DTC-база** (статическая, `vehicle/dtc/`) — живёт в этом домене.
|
||
|
||
## 4. Приоритизация под простые авто *(резолв routed-вопроса)*
|
||
|
||
- **MVP killer-фичи опирается на универсальное:** `mil_on` (PID 01) + DTC (Mode 03) —
|
||
поддержано почти везде, даже на простых Lada.
|
||
- Богатые PID — **best-effort** по результату пробинга.
|
||
- **ELM327 медленный** (несколько PID/сек) → на старте опрашиваем малый приоритетный
|
||
набор + DTC; native CAN быстрее.
|
||
|
||
## 5. DTC-расшифровка
|
||
|
||
- **Структура кода информативна сама по себе** (буква = подсистема, см. [data-model](../contracts/data-model.md) §6)
|
||
— даёт базовую категоризацию даже для незнакомого кода.
|
||
- **Статическая база:** не обязательно ВСЕ тысячи generic-кодов сразу — стартуем с
|
||
частых + алгоритмический разбор структуры, пополняем. RU-описания, `vehicle/dtc/`.
|
||
- **LLM (ассистент)** даёт человеческое объяснение (модели знают стандартные коды);
|
||
**офлайн-режиму нужна статическая база** — для надёжности и против галлюцинаций кода.
|
||
- 🟡 *Выбор:* своя **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.
|
||
- **На `ShutdownImminent` (от Power, домен B §4):** немедленно **гасим активный OBD-TX и закрываем
|
||
ISO-TP-сессии** (не оставить ECU в открытой диагностической сессии) — до снятия питания.
|
||
|
||
## 6. Зависимости
|
||
|
||
- **Вниз:** hardware (CAN-транспорт, listen-only/polling), data-model (каталог),
|
||
ipc (контракт сервиса), principles #2 (red-line), security-privacy (привилегированное
|
||
ядро, единственный владелец CAN).
|
||
- **Потребители:** Assistant (D) — контекст в промпт; Shell (C) — датчики/виджеты;
|
||
плагины — `vehicle_read`.
|
||
|
||
## 7. Открытые вопросы
|
||
|
||
- 🟡 **DTC-база:** своя RU из открытых списков (рек.) vs готовая.
|
||
- ◻️ **Точность производного расхода** (зависит от типа топлива) — см. [data-model](../contracts/data-model.md) §5.
|
||
- ◻️ **«Вырос расход»:** набор диагностических сигналов (fuel trim, O2) — later.
|
||
- ◻️ **Vendor DBC/коды** — порт под конкретное авто (HAL/BSP, [data-model](../contracts/data-model.md) §7).
|
||
- ◻️ **OBD-порт ≠ все шины.** Powertrain-шина на порту; кузов/комфорт/кнопки руля —
|
||
на других CAN-шинах, нужен тап конкретной шины. → [hardware.md](../contracts/hardware.md) + data-model §7.
|
||
- ◻️ **ELM327-клоны** капризны (баги прошивки, тайминги) — симулятор должен эмулировать их причуды. → [dev-environment.md](../dev-environment.md).
|
||
- ◻️ **Runtime-staleness:** таймаут ответа / двигатель заглушен → помечать сигнал `stale`/`unavailable`, не висеть.
|
||
|
||
---
|
||
|
||
## Журнал решений (домен E)
|
||
|
||
| Решение | Выбор | Дата |
|
||
|---------|-------|------|
|
||
| Транспорт | ELM327 (старт) → нативный SocketCAN; транспорт-агностичные сигналы | 2026-06-16 |
|
||
| 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 |
|