VEU.WathBody/1-docs/4-modules/m13-fenix-data-field/module_reqs.md

179 lines
14 KiB
Markdown
Raw Permalink 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.

# Требования к модулю: m13-fenix-data-field
> Модуль — **FenixDataField** (архитектура разд. 1.1): поле данных
> Connect IQ (Monkey C) «Феникс» в штатном профиле «Силовая»: текущий
> пульс + зона цветом, метрики подхода (время, средний пульс),
> автономный таймер отдыха с вибрацией. Самодостаточная копия
> требований (d-dev-6). Источники: Ф-2.1–Ф-2.8 (requirements), errata
> Ф-2.4 (m12, автономный таймер), ОВ-7 (tech-req 1, таргеты),
> tech-req 6 п. 1 (UI/UX часов), 7 п. 1 (закрытие части «таймер»
> прототипа канала), ui-ux-recommendations разд. 2.
## 1. Назначение и границы
Поле данных на часах во время силовой активности: отображает пульс,
зону и метрики подхода, вибрирует в конце отдыха и при выходе пульса
в красную зону. Только отображение и вибрации — запись `.fit` ведёт
платформа Garmin (Ф-2.7); часы полностью автономны (Ф-2.4: не
зависимость — никаких требований к телефону).
### 1.1. Границы подхода (исследование API, 2026-10-19)
Ф-2.3 предполагала границами подхода «штатное событие нового подхода
(Strength Set) → событие Lap». Проверка по актуальной документации
Connect IQ API (вплоть до текущей версии платформы):
1. **События/данных повторений в Connect IQ API нет** — ни в
`Toybox.Activity` (6 классов: Info, ProfileInfo, SplitInfo,
WorkoutStep…; у `Activity.Info` нет полей сетов/повторов), ни
отдельным модулем; классов повторений нет в общем списке классов.
Это не ограничение fenix 6X — API не существует ни в одной версии
платформы: штатная детекция повторений «Силовой» сторонним кодом
недоступна.
2. **Доступно полю данных:** `compute(info as Activity.Info)` — раз
в секунду (`currentHeartRate` — Number|Null, API 1.0.0);
`onTimerLap()` — нажатие кнопки Lap (API 1.3.0); таймерные
колбэки `onTimerStart/Stop/Pause/Resume/Reset` (API 1.3.0);
`Attention.vibrate([VibeProfile(duty, мс)])` — до 8 профилей
подряд, поля данных поддержаны (API 1.0.0); собственная разметка
экрана (`onLayout` + отрисовка `dc`, параметрическая по
`dc.getWidth/getHeight`).
3. **Решение v1 (errata Ф-2.3, разд. 5):** границы подхода = между
нажатиями Lap — штатная семантика «Силовой» (Lap жмётся в конце
подхода, метки попадают в `.fit`, КУ-2 сохраняется). «Время
подхода» = интервал с последнего Lap (включает предшествующий
отдых — точное время «под нагрузкой» без детекции повторений
не измеряется); «средний пульс подхода» = среднее
`currentHeartRate` за тот же интервал. Lap обнуляет метрики и
стартует таймер отдыха.
**В границах модуля:**
- **проект Monkey C** `3-app\5-watch\FenixDataField`: манифест (тип
datafield, UUID, `minApiVersion` — не выше 2.1.0, чтобы поле
ставилось и на старые CIQ-устройства), таргетная матрица
`monkey.jungle` — якорь `fenix6x` (280×280); добавление модели —
строка таргета, код и макет не меняются (мультитаргет-инфраструктура,
указание владельца 2026-10-19);
- **ядро (чистые классы Monkey C, без UI):**
- `SetTracker` — метрики подхода: время с границы (Lap), средний
пульс интервала (накопление сэмплов из `compute`), обнуление по
`onTimerLap`; null-пульс пропускается;
- `RestTimer` — автономный таймер отдыха: старт по Lap,
длительность из настройки `restSec` (умолчание 120 =
`Rest.DefaultSec` телефона), обратный отсчёт, конец → вибрация;
пауза активности (`onTimerPause/Resume`) останавливает/ведёт
дальше;
- `ZoneCalc` — зоны от `maxBpm`: < 50 % синяя (recovery), 50–70 %
зелёная, 70–85 % жёлтая, > 85 % красная; `maxBpm` из настройки
`hrMaxBpm`, не задана (0) — формула Танаки
`208 − 0,7 × возраст` (настройка `age`); возвращает цвет
(MIP-палитра) и текстовую подпись зоны;
- **экран поля** — параметрическая разметка семейства квадратных
MIP-экранов (якоря + размеры от `dc`, без фиксированных
координат под конкретную модель): текущий пульс — крупнейшее
число (`FONT_NUMBER_*`), плашка/ободок зоны цветом + подпись зоны
текстом (цвет — не единственный носитель), строка состояния
«ПОДХОД мм:сс · ср N» / «ОТДЫХ мм:сс» (обратный отсчёт), прочерк
при отсутствии пульса;
- **вибрации:** конец отдыха — однократная лёгкая; красная зона —
двойная с гистерезисом (повторная не раньше 60 с, сброс при
возврате в жёлтую зону);
- **настройки поля** (стандартные properties, settings.xml):
`restSec` (30–600, умолчание 120), `hrMaxBpm` (0–250, умолчание
0 = расчёт по формуле), `age` (14–100, умолчание 45), подписи
ru/en; умолчания зашиты в сборку — работают без магазина;
- **тесты Toybox.Test** (модуль есть с API 2.1.0; asserts
компилируются out в release): зоны, таймер отдыха, трекер
подхода; прогон инструментарием SDK;
- **сборка и доставка:** `monkeyc` по всем таргетам без ошибок,
подпись developer-ключом, инструкция sideload на Fenix 6X
(developer mode + Garmin Connect Mobile) — в readme модуля.
**Вне границ модуля:** запись `.fit` (платформа Garmin), сетевой
обмен из поля (`Communications` на fenix 6X недоступен полям данных —
errata ОВ-3 m12; канал живого пульса — m12, BLE-трансляция),
редактирование настроек на часах (поля данных не имеют собственных
экранов настроек), публикация в магазине Connect IQ (опция владельца
— см. решение 3 гейта 1.3), добавление таргетов fenix6/6S (по
фактическому парку — строка конфигурации), пульс-оповещения
Safety.HrStrengthMax (абсолютный порог 120 — телефон, Ф-3/Ф-13;
часы красят по процентам Ф-2.2).
## 2. Решения интерфейса (ui-ux разд. 2, tech-req 6 п. 1)
- Один экран-поле, читается за 1–2 с (glanceable): пульс — главное
число; всё остальное — строкой состояния мельче.
- Семантика кнопок не меняется: Lap — конец подхода (штатно),
Start/Stop — пауза/стоп активности; поле не требует ни одного
нажатия и не перехватывает кнопки (Ф-2.5, Ф-2.6).
- Цвет зоны дублируется подписью (recovery/лёгкая/средняя/высокая —
те же названия, что на «Профиле» телефона m10).
- MIP-экран: тёмный фон, высокий контраст, крупные шрифты
(`FONT_NUMBER_*` для пульса), 64-цветная палитра; читаемость на
солнце не требует подсветки.
- Нет пульса (датчик не готов / null) — прочерк «—», остальное
живое; поле не падает (Ф-2.8).
## 3. Инварианты (🛡 — нарушать запрещено)
1. **Поле не пишет в сеть и не хранит историю** (Ф-2.7): только
отображение и вибрации; запись активности ведёт платформа Garmin.
2. **Кнопки не перехватываются** (Ф-2.5, Ф-2.6): Lap/Start/Stop —
штатная обработка; поле не блокирует паузу, остановку и
сохранение активности.
3. **Часы автономны** (Ф-2.4): поле не требует телефона и никак его
не вызывает; работа поля не зависит от наличия связи с чем бы то
ни было.
4. **Отсутствующая функция молча пропускается** (Ф-2.8): нет
пульса — прочерк; вибрация недоступна на модели — просто не
вызывается; поле не падает.
5. **Один исходный код** (Ф-2.8, указание владельца 2026-10-19):
функциональное поведение одинаково на всех таргетах; разметка —
параметрический макет семейства экранов; добавление модели часов
— конфигурация сборки без правок кода.
6. **Секретов нет:** поле ничего не передаёт — ключей, паролей и
персональных данных в коде/настройках нет (настройки — возраст,
макс. ЧСС, отдых).
## 4. Критерии приёмки модуля
1. `monkeyc` собирает все таргеты матрицы без ошибок и предупреждений
(кроме подавленных обоснованно); тесты `Toybox.Test` зелёные
(зоны, таймер отдыха, метрики подхода).
2. Симулятор Connect IQ: поле добавляется в профиль Strength;
пульс/зона/строка подхода отображаются и обновляются раз в
секунду; Lap обнуляет метрики и запускает отдых; вибрации
вызываются (видно в логе симулятора).
3. Приёмка на устройстве владельца (Fenix 6X, якорь): sideload
dev-сборки; «Силовая» с полем «Феникс»: пульс и зона на экране,
Lap — граница подхода, вибрация конца отдыха, двойная вибрация
в красной зоне; метки Lap присутствуют в `.fit` выгрузки Garmin
Connect (проверяется импортом m06/консолью m08).
4. Деградация: без пульс-данных — прочерк, поле живое; пауза
активности — таймер стоит; модель без вибрации — остальное
работает (Ф-2.8, смок владельца на имеющемся парке).
## 5. Errata НД (по утверждении гейта 1.3; ВНЕСЕНА 2026-10-19)
- requirements **Ф-2.1**: «время текущего подхода (под нагрузкой)» →
«время с последнего Lap (границы подхода — Ф-2.3; включает
предшествующий отдых — точное время „под нагрузкой“ не измеряется:
детекция повторений недоступна Connect IQ API, errata 2026-10-19)»;
- requirements **Ф-2.3**: «от штатного события нового подхода
(Strength Set) до события Lap» → «между нажатиями кнопки Lap
(штатная семантика „Силовой“: Lap — конец подхода, метки Lap
попадают в .fit, КУ-2): событие Strength Set в Connect IQ API
отсутствует (errata 2026-10-19 — класса повторений нет ни в одной
версии платформы, проверено по актуальному API); метрики подхода
считаются за интервал Lap→Lap и обнуляются на Lap»;
- requirements **Ф-2.2** — правка не потребовалась: норма уже
содержит «границы — из настроек поля данных (Connect IQ settings;
автоматическая передача с телефона — открытый вопрос 3)»;
- tech-requirements **7 п. 1**: дополнено «вибрация конца отдыха и
метрики подхода Lap→Lap — приёмка m13».
Волна внесена одним пакетом после «утверждаю» гейта 1.3 (без подъёма
версий документов — errata в телах разделов, версии поднимутся на
ближайшем ревью; прецедент — волна m12).