Files
shturman/docs/contracts/data-model.md
T
kk0t9 3d13bb5827 docs: tech-stack + контракты ipc/data-model (+ ревью-фиксы)
- tech-stack: Rust-first (один прод-рантайм; Python — dev-only), полный стек, крейты
- architecture: ассистент Python→Rust для консистентности; boot-порядок
  (Broker+App-Host до Shell); потолок частоты сигналов ~10–20 Гц
- contracts/ipc: реестр D-Bus (сервисы ядра/апов, соглашения, портал-брокеринг)
  + открытые вопросы из self-review
- contracts/data-model: VSS-aligned каталог сигналов, OBD-PID маппинг, DTC-модель;
  добавлен MIL-статус (PID 0x01) для killer-фичи, состояние машины, расход-estimate

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 20:01:36 +03:00

136 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Контракт: модель данных машины (VSS-подобная)
> Канонический каталог сигналов, которые публикует `VehicleData`. Наполняет
> конкретикой ipc-контракт, кормит контекст ассистента, домен E и killer-фичу.
Статус: **v1 (на ревью).**
Связано с: [ipc.md](ipc.md) (`VehicleData`) · [domains/](../domains/README.md) (E: Vehicle-Data) · [hardware.md](hardware.md) · [principles.md](../principles.md) (#4)
---
## 1. Подход: VSS-aligned, но лёгкий
- Имена сигналов — в стиле **COVESA VSS** (иерархические пути), типы и единицы — по
VSS. Но держим **свой лёгкий каталог**, а не тащим полный VSS-тулинг (Franca/
генераторы). Достаточно совместимости «по духу», чтобы говорить на общем языке и
легко расширяться.
- 🟡 *Выбор на подтверждение:* лёгкий VSS-aligned каталог (рекомендую) vs полное
принятие VSS-спеки с тулингом (тяжелее, избыточно на старте).
## 2. Модель сигнала
Каждый сигнал описывается:
| Поле | Смысл |
|------|-------|
| `id` | канонический VSS-стиль путь (напр. `Vehicle.Speed`) |
| `alias` | короткое имя для эргономики (`speed`) |
| `type` | `float` / `int` / `bool` / `enum` |
| `unit` | каноническая единица (**SI-стиль**: km/h, rpm, °C, V, %, g/s, kPa) |
| `range` | допустимый диапазон |
| `source` | откуда читается: OBD-PID / native-CAN(DBC) / **computed** |
| `availability` | поддерживается ли данной машиной (динамически) |
| `ts` | метка времени значения (для свежести) |
**Транспорт-агностичность (важно):** сигнал каноничен, а **источник — это
per-vehicle маппинг.** Один и тот же `Vehicle.Speed` может читаться через ELM327
(OBD-PID `0x0D`) или нативный SocketCAN (сигнал из DBC). Это и есть мост «ELM327 на
старте → SocketCAN в проде» и основа портирования под разные авто (см. [hardware.md](hardware.md)).
**Единицы и локаль:** в модели — каноническая SI; отображение (km vs miles) —
дело shell/настроек, конвертация на презентации, не в модели.
## 3. Доступность сигналов (per-vehicle)
Не все машины отдают все PID. `VehicleData` при старте **пробит поддерживаемые
PID** (Mode 01, PID `0x00/0x20/0x40/…` — битовые маски поддержки) и помечает
сигнал `Unavailable`, если его нет. Консьюмеры (ассистент, UI) обязаны это
учитывать — «нет данных», а не падение (принцип #4).
## 4. Каталог стартовых сигналов (OBD-II Mode 01)
> `id` — наш канонический путь (≈ VSS, **точные VSS-листы сверяем со спецификацией
> при реализации**). Базовый набор; расширяем по ходу домена E.
>
> **`mil_on` (PID 0x01) — ключевой для killer-фичи** «почему горит чек»: это сам
> факт горящей лампы + число ошибок, отдельно от их чтения (Mode 03).
> `module_voltage` (0x42) — напряжение питания ЭБУ ≈ бортсеть (близко, но не ровно клеммы АКБ).
| alias | id (≈ VSS) | PID | type | unit | range |
|-------|-----------|-----|------|------|-------|
| `speed` | `Vehicle.Speed` | 0x0D | int | km/h | 0..255 |
| `rpm` | `Vehicle.Powertrain.CombustionEngine.Speed` | 0x0C | float | rpm | 0..16383 |
| `engine_load` | `…CombustionEngine.Load` | 0x04 | float | % | 0..100 |
| `coolant_temp` | `…CombustionEngine.ECT` | 0x05 | int | °C | -40..215 |
| `intake_temp` | `…CombustionEngine.IAT` | 0x0F | int | °C | -40..215 |
| `maf` | `…CombustionEngine.MAF` | 0x10 | float | g/s | 0..655 |
| `throttle` | `…CombustionEngine.TPS` | 0x11 | float | % | 0..100 |
| `intake_pressure` | `…CombustionEngine.MAP` | 0x0B | int | kPa | 0..255 |
| `fuel_level` | `Vehicle.Powertrain.FuelSystem.Level` | 0x2F | float | % | 0..100 |
| `module_voltage` | `Vehicle.LowVoltageBattery.Voltage` | 0x42 | float | V | 0..65.5 |
| `ambient_temp` | `Vehicle.Exterior.AirTemperature` | 0x46 | int | °C | -40..215 |
| `oil_temp` | `…CombustionEngine.EOT` | 0x5C | int | °C | -40..215 |
| `fuel_rate` | `…CombustionEngine.FuelRate` | 0x5E | float | L/h | 0..3212 |
| `run_time` | `…CombustionEngine.RunTime` | 0x1F | int | s | 0..65535 |
| `mil_on` | `Vehicle.OBD.IsMILOn` | 0x01 | bool | — | вкл/выкл |
| `dtc_count` | `Vehicle.OBD.DTCCount` | 0x01 | int | шт | 0..255 |
| `distance_mil` | `Vehicle.OBD.DistanceWithMIL` | 0x21 | int | km | 0..65535 |
## 5. Производные (computed) сигналы
Слой поверх сырых — считаются внутри VehicleData (или отдельного компонента):
- **Мгновенный расход** — если есть прямой `fuel_rate` (0x5E), берём его; иначе
**оценка** из MAF (предполагает бензин/стехиометрию — помечаем как `estimate`,
зависит от типа топлива).
- **Пробег поездки / средний расход** (интеграл по времени; нужен trip-стейт).
- **Состояние машины** (`off` / `accessory` / `running`) — грубо из RPM/зажигания;
нужно ассистенту, чтобы отличать «двигатель заглушен» от «сигнал недоступен» от «ноль».
- Помечаются `source = computed`; зависят от наличия исходных сигналов.
## 6. Модель DTC (диагностические коды)
- **Формат кода:** буква (`P` powertrain / `C` chassis / `B` body / `U` network) +
4 hex-цифры. Грубо: `0` — стандарт SAE/ISO, `1` — производитель (полная карта
сложнее: `P2xxx` тоже стандарт, `P3xxx` смешанные).
- **Статусы:** `confirmed` (Mode 03), `pending` (Mode 07), `permanent` (Mode 0A).
- **Чтение:** Modes 03/07/0A — это **чтение**, разрешено.
**Сброс (Mode 04) — НЕТ.** Read-only (принцип #2).
- **Расшифровка двухслойная:** статическая база `код → стандартное описание`
(живёт в домене E, `vehicle/dtc/`) + **LLM** даёт человеческое объяснение
по-русски в контексте машины. Manufacturer-specific (`P1xxx`) требуют вендорской
базы (задел, §7).
## 7. Расширение: вендорские сигналы и коды (задел)
- Нативный CAN конкретного авто описывается **DBC-файлом** → даёт сигналы сверх
стандартного OBD и вендорские DTC.
- Это per-vehicle/per-OEM маппинг, ложится на **HAL/board-support** ([hardware.md](hardware.md))
и на портирование силами автопроизводителей/энтузиастов (vision: «API под
конкретное железо/авто»). Плагин/порт может поставлять свой DBC + базу кодов.
---
## Открытые вопросы (найдено на self-review → роутинг)
- **Минимальный набор PID на простых авто.** Старые/простые машины (наша целевая
аудитория — Lada и т.п.) отдают мало Mode-01 PID. **MVP killer-фичи опирается на
универсальное:** `mil_on` + чтение DTC (Mode 03); богатые PID — best-effort. → домен E.
- **«Почему вырос расход».** Для этого кейса из vision полезны топливные коррекции
(Short/Long Term Fuel Trim, PID 0x060x09) и данные O2 — диагностическое расширение. → домен E.
- **Идентификация авто (VIN).** Mode 09 PID 0x02 — даёт привязку к конкретной машине
(память о водителе, вендорские базы кодов). Задел. → домен E + домен D.
- **DBC для нативного CAN часто проприетарны** или добываются реверсом
(community-DBC, opendbc). Учесть в портировании. → [hardware.md](hardware.md) + домен E.
---
## Журнал решений (data-model)
| Решение | Выбор | Дата |
|---------|-------|------|
| Глубина VSS | лёгкий VSS-aligned каталог (🟡 на подтверждение) | 2026-06-16 |
| Источник сигнала | транспорт-агностичен: канон + per-vehicle маппинг (PID / DBC / computed) | 2026-06-16 |
| Единицы | каноническая SI в модели; конвертация на презентации | 2026-06-16 |
| DTC | чтение Modes 03/07/0A; сброс (04) запрещён; расшифровка база + LLM | 2026-06-16 |