- data-model: структура DTC-кода исправлена (буква + 2-битная категория + 3 hex, не «4 hex»; P0/P2 generic, P1/P3000-33FF производитель); module_voltage путь → Vehicle.OBD.ControlModuleVoltage (был неверный LowVoltageBattery) - plugin-sdk: пример id → dev.example.* (ru.shturman.* зарезервирован); i18n строк манифеста (per-locale, ru обязателен); ui_screens capability + гейт RegisterScreen - hardware: камера «фаза 2» → v2; требования к MCU-копилоту (обновляемость прошивки, fail-safe при его отказе, позиция в цепочке доверия) - tech-stack: карты «фаза 2» → v4 (нормализация фазовой номенклатуры) - C-shell: день/ночь v0 = время, GPS-восход v1 (был конфликт фаз); ui_screens-гейтинг Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
12 KiB
Контракт: модель данных машины (VSS-подобная)
Канонический каталог сигналов, которые публикует
VehicleData. Наполняет конкретикой ipc-контракт, кормит контекст ассистента, домен E и killer-фичу.
Статус: v1 (на ревью).
Связано с: ipc.md (VehicleData) · domains/ (E: Vehicle-Data) · hardware.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 |
каноническая единица (фиксированный набор, метрические/авто-конвенциональные — часть не-СИ: km/h, rpm, °C, V, %, g/s, kPa) |
range |
допустимый диапазон |
source |
откуда читается: OBD-PID / native-CAN(DBC) / computed |
availability |
статически: поддерживается ли PID данной машиной (пробинг на старте) |
quality |
рантайм-валидность значения: valid / stale / unavailable (таймаут, двигатель заглушен) — ортогонально availability |
max_age |
порог свежести (per-signal): старше → quality=stale |
ts |
метка времени значения |
Транспорт-агностичность (важно): сигнал каноничен, а источник — это
per-vehicle маппинг. Один и тот же Vehicle.Speed может читаться через ELM327
(OBD-PID 0x0D) или нативный SocketCAN (сигнал из DBC). Это и есть мост «ELM327 на
старте → SocketCAN в проде» и основа портирования под разные авто (см. hardware.md).
Единицы и локаль: в модели — канонический набор единиц; отображение (km vs miles) — дело shell/настроек, конвертация на презентации, не в модели.
3. Доступность сигналов (per-vehicle)
Не все машины отдают все PID. VehicleData при старте пробит поддерживаемые
PID (Mode 01, PID 0x00/0x20/0x40/… — битовые маски поддержки) и помечает
сигнал Unavailable, если его нет. Консьюмеры (ассистент, UI) обязаны это
учитывать — «нет данных», а не падение (принцип #4).
Сервисные функции (Mode 03/07/0A DTC) — детектятся отдельно: support-bitmask у них нет, feature-detection = trial-read (валидный ответ → есть; NACK/timeout → нет).
Если пробинг (PID 0x00) пуст/недоступен — НЕ каскадим «всё Unavailable»: fallback
на best-effort прямой опрос приоритетного набора PID + trial Mode 03. MVP killer-фичи
(mil_on PID 01 + DTC Mode 03) не зависит от bitmask-пробинга — доступность
определяется прямым чтением этих PID/сервисов.
Рантайм-устаревание (≠ статической доступности) несёт поле
quality(§2), синхрон с ipc.
4. Каталог стартовых сигналов (OBD-II Mode 01)
id— наш канонический путь (≈ VSS, точные VSS-листы сверяем со спецификацией при реализации). Базовый набор; расширяем по ходу домена E.
mil_on(PID 0x01) — ключевой для killer-фичи «почему горит чек»: это сам факт горящей лампы + число ошибок, отдельно от их чтения (Mode 03).module_voltage(0x42) — напряжение питания ЭБУ ≈ бортсеть (близко, но не ровно клеммы АКБ); property в ipc —ModuleVoltage.
| 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.OBD.ControlModuleVoltage |
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..127 (7-бит) |
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/C/B/U) + 2-битное поле категории (0–3, не полный hex) + 3 hex-цифры. Для P-кодов:P0/P2— generic (ISO/SAE),P1— производитель,P3— смешанный (P3000–P33FFпроизводитель,P3400–P3FFFSAE-reserved); у C/B/U своя разбивка — уточняем по SAE J2012 при реализации. - Статусы:
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) и на портирование силами автопроизводителей/энтузиастов (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 0x06–0x09) и данные O2 — диагностическое расширение. → домен E.
- Идентификация авто (VIN). Mode 09 PID 0x02 — даёт привязку к конкретной машине (память о водителе, вендорские базы кодов). Задел. → домен E + домен D.
- DBC для нативного CAN часто проприетарны или добываются реверсом (community-DBC, opendbc). Учесть в портировании. → hardware.md + домен E.
Журнал решений (data-model)
| Решение | Выбор | Дата |
|---|---|---|
| Глубина VSS | лёгкий VSS-aligned каталог (🟡 на подтверждение) | 2026-06-16 |
| Источник сигнала | транспорт-агностичен: канон + per-vehicle маппинг (PID / DBC / computed) | 2026-06-16 |
| Единицы | канонический набор единиц (метрич./авто-конвенц., часть не-СИ); конвертация на презентации | 2026-06-16 |
| Валидность значения | runtime-поле quality (valid/stale/unavailable) + max_age, ортогонально availability |
2026-06-16 |
| DTC | чтение Modes 03/07/0A; сброс (04) запрещён; расшифровка база + LLM | 2026-06-16 |