INAV: откуда брать справку по настройкам и элементам OSD (AD-807)
Статус: research + реализованный срез 1. Тикет требовал сначала выяснить,
откуда вообще берутся описания настроек с привязкой к версии прошивки, и
только потом делать. Здесь — проверенные факты об источниках, разбор развилки
из тикета и граница того, что сделано в срезе 1.Проверено 31.07.2026 против настоящего репозитория
iNavFlight/inav(запросы
кapi.github.com/raw.githubusercontent.comвручную, из агентской сессии).
Ни один из этих запросов НЕ выполняется в рантайме продукта и НЕ выполняется
в тестах — см. § 4.
1. Что просил основатель
Фидбэк 21.07 по AD-800 (часть 4, выделена в AD-807): у каждого импортированного
пункта дампа — значок «?»; наведение даёт короткое описание ЭТОГО пункта,
клик ведёт на страницу документации INAV по нему. Источник справки
привязан к версии прошивки — версия у нас уже есть, парсер диффа (AD-799)
достаёт её из строки # INAV/<плата> <semver>.
Ключевое требование — именно привязка к версии: параметры INAV появляются,
исчезают и меняют смысл между релизами, и справка «вообще» здесь хуже, чем
отсутствие справки: человек настраивает реальный аппарат.
2. Источник описаний параметров set — docs/Settings.md
Есть, и он идеален для задачи. В репозитории прошивки лежит
docs/Settings.md — автогенерируемый справочник ВСЕХ CLI-параметров
(140 КБ на теге 8.0.0). Генерится из src/main/fc/settings.yaml, то есть из
того же файла, из которого собирается таблица настроек прошивки: расхождения
между документацией и поведением по построению нет.
Формат — по одному блоку на параметр:
### 3d_deadband_high
High value of throttle deadband for 3D mode (when stick is in the deadband
range, the value in 3d_neutral is used instead)
| Default | Min | Max |
| --- | --- | --- |
| 1514 | PWM_RANGE_MIN | PWM_RANGE_MAX |
Отсюда сразу три вывода:
- Описание пункта — абзац сразу под заголовком
### <имя>; - Якорь ссылки — GitHub делает из заголовка
### 3d_deadband_highякорь
#3d_deadband_high. Имена параметров INAV состоят только из[a-z0-9_],
поэтому якорь совпадает с именем побуквенно — угадывать ничего не нужно; - Дефолт и диапазон тут же таблицей — потенциально полезно (показать, что
значение в дампе отличается от заводского), но это уже за рамками AD-807.
3. Привязка к версии решается ТЕГОМ, а не реестром
Главная находка ресёрча, которая обрушила первоначальную оценку задачи.
Тикет предполагал «реестр описаний по версии + серверный кэш + снапшот».
Для ссылки ничего этого не нужно: документация лежит В ТОМ ЖЕ репозитории,
что и прошивка, и тегируется вместе с ней, а имя тега совпадает с semver из
дампа. Проверено:
| Запрос | Ответ |
|---|---|
git/ref/tags/8.0.0 |
200 |
git/ref/tags/7.1.2 |
200 |
git/ref/tags/9.1.0 |
200 (в списке тегов) |
То есть адрес нужной страницы — чистая функция от версии:
https://github.com/iNavFlight/inav/blob/<semver>/docs/Settings.md#<имя параметра>
Ни сети, ни кэша, ни снапшота в репозитории. Это и реализовано в срезе 1
(web/static/js/tools/inav_help_links.js).
Два правила, без которых такая ссылка становится вредной:
- Версия из дампа — недоверенный вход. Это текст, вставленный
пользователем, и он подставляется в URL. Принимается строгоX.Y.Z
(SEMVER_RE); всё остальное (v8.0.0,8.0.0-RC1,../../…) уходит на
master. masterобязан быть ВИДЕН пользователю. Функция возвращает
{ref, pinned}, и приpinned: falseподпись у «?» прямо говорит, что
версию определить не удалось и показывается актуальная документация. Молча
показать справку другой версии — ровно та ошибка, ради предотвращения которой
тикет и просил привязку.
4. Почему справка не ходит в сеть в рантайме
- Ссылка (срез 1) сети не требует вовсе — адрес вычисляется из версии.
- Тесты ходить наружу не имеют права (
tests/outbound_network_guard.py),
поэтому проверяются формулы адресов, а не доступность страниц. Проверка
«тег существует» сделана РУЧНО при ресёрче и записана здесь — это факт об
источнике, а не то, что должен проверять CI. - Любой будущий слой описаний (§ 5) обязан быть серверным и кэшируемым:
дёргать GitHub из браузера пользователя на каждый рендер таблицы в сотни
строк нельзя ни по скорости, ни по rate-limit (60 запросов/час на IP без
токена).
5. Описания при наведении — что осталось и чем это стоит делать
Срез 1 даёт клик (ссылка на нужный пункт нужной версии), но НЕ даёт
наведение (короткий текст описания). Это отдельный слой, и он честно
дороже:
- Текст описания есть только в
Settings.md, то есть его нужно ДОСТАВИТЬ к
пользователю. Файл — 140 КБ на версию (сырой markdown), после извлечения
только пар «имя → описание» ужимается примерно вчетверо, но это всё ещё
сотни килобайт на КАЖДУЮ поддерживаемую версию. - Отсюда развилка, которая упирается в решение основателя (§ 7).
Механически слой выглядит так: разбор Settings.md по ### <имя> + абзац
под ним → словарь {имя: описание} → отдача клиенту одним запросом на версию
(с ETag/кэшем), а не по параметру.
6. Элементы OSD — источник другой и БЕДНЕЕ
Отдельная находка, важная для ожиданий: описаний элементов OSD в
документации INAV нет.
docs/OSD.md § «OSD Elements» содержит таблицу:
| ID | Element | Added | Notes |
|-----|------------------------|--------|-------|
| 0 | OSD_RSSI_VALUE | 1.0.0 | |
| 1 | OSD_MAIN_BATT_VOLTAGE | 1.0.0 | |
То есть по элементу доступны: числовой id, символьное имя, версия, в
которой элемент появился, и изредка примечание. Связного текста «что это
показывает» — нет. Следствия:
- Ссылка по элементу OSD ведёт на раздел
OSD.md#osd-elements, а не на
конкретную строку: элементы перечислены строками таблицы, а не заголовками,
и якоря на них не существует. Выдумывать якорь нельзя. - Колонка Added — самостоятельная ценность на будущее: она позволяет
честно сказать «этого элемента в вашей прошивке ещё нет» при импорте дампа с
более новой версии. Отдельный тикет. - Человеческие названия элементов у нас УЖЕ свои (
OSD_ELEMENTSв
web/static/js/tools/inav_msp.js) и они лучше, чемOSD_RSSI_VALUE. Тянуть
из INAV тут нечего.
7. Развилка для основателя (инженерная часть сделана)
Тикет просил согласовать MVP при взятии: «(a) ссылка без version-pin» либо
«(b) полноценный version-bound реестр». Ресёрч эту развилку сдвинул:
- вариант (a) оказался не нужен — version-pin достался бесплатно, потому
что документация тегируется вместе с прошивкой. Срез 1 даёт сразу
привязанную к версии ссылку, а не «общую доку»; - вариант (b) в исходном виде («реестр по версии») остаётся нужен только
ради текста при наведении, и его цена — доставка сотен килобайт на версию.
Что решает основатель:
- Нужен ли hover-текст вообще, если клик уже ведёт в точное место нужной
версии, а таблицаmaster/setв реальном дампе — сотни строк. - Если нужен — какие версии поддерживаем: снапшот в репозитории (быстро,
офлайн, но растёт с каждой версией) или серверный кэш по требованию
(свежо, любые версии, но нужна фоновая загрузка и место под кэш). - Нужна ли отметка «параметра нет в вашей версии прошивки» (по
Added
у OSD и по отсутствию имени вSettings.mdу настроек) — это самостоятельная
польза при импорте чужих дампов, дешевле полного hover-текста.
8. Что сделано в срезе 1
web/static/js/tools/inav_help_links.js— чистый построитель адресов
(тег из версии, якорь параметра, раздел OSD, честныйmaster-фолбэк);- «?» у каждой строки таблицы
master/setна вкладке «Импорт диффа» — ссылка
на конкретный параметр; «?» на карточке «OSD-раскладка» — ссылка на раздел
«OSD Elements» (якоря на элемент не существует, см. § 6). Подпись у обоих
различает «справка вашей прошивки» и «версия не определена»; - тесты
tests/test_inav_help_links.js(в т.ч. на то, что вставленный
пользователем текст не уезжает в URL) и разметочные —
tests/test_inav_connect_route.py::TestSettingHelpLinks.
Чего срез 1 НЕ делает: описания при наведении (§ 5), значок у строк
профилей (profile/mixer_profile/battery_profile показываются одной
склеенной ячейкой, а не строкой на параметр — нужна переделка таблицы),
отметка «параметра нет в вашей версии» (§ 7 п. 3).