Workout HR: log samples natively so recording survives screen-off
The JS 2s poll that stored workout HR samples is frozen by Android when the screen is off, so a sleep-long recording kept only the on-screen stretches (the strap and live display were fine — the persist path was the gap). The foreground service now appends every reading to ble_hr_log.jsonl; ble_read_hr_log exposes it; on stop the workout rebuilds its samples from that log (falling back to the poll array). ble_clear_hr truncates the log at start.
This commit is contained in:
parent
85d5e47972
commit
ee47af4479
6 changed files with 98 additions and 5 deletions
36
docs/session-logs/2026-10-20_native-hr-log.md
Normal file
36
docs/session-logs/2026-10-20_native-hr-log.md
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# Сессия 2026-10-20 - нативный лог ЧСС (запись воркаута переживает гаснущий экран)
|
||||
|
||||
## Причина (из разбора 21ч-прогона эксперимента)
|
||||
Сессия-воркаут 1792436740262 (19.10 22:05 -> 20.10 17:27) в сохранёнке имела дырки 11.6ч,
|
||||
НО пользователь видел живые цифры засыпая/просыпаясь/весь день. Проверка: шаг внутри
|
||||
покрытия ровно 2.0с (это JS-поллинг), границы дыр = сон/утро/обед (экран гас). Вывод: ремень
|
||||
и дисплей работали; молчал ПЕРСИСТ - историю сэмплов воркаута писал JS setInterval(2с),
|
||||
который Android замораживает в фоне/при гаснущем экране. Нативная часть клала только ТЕКУЩЕЕ
|
||||
значение (ble_hr_data.json, overwrite), истории не было.
|
||||
|
||||
## Сделано
|
||||
Нативный лог истории ЧСС (как GPS-точки пишутся foreground-сервисом):
|
||||
- Kotlin BleHrService: поле `logFile` = `ble_hr_log.jsonl`; в `writeData` каждая строка с
|
||||
`"hr":` дописывается (appendText) в лог. Пишет сам foreground-сервис -> переживает
|
||||
гаснущий экран.
|
||||
- Rust ble.rs: команда `ble_read_hr_log` (читает лог), `ble_clear_hr` теперь чистит и лог.
|
||||
Зарегистрировано в lib.rs invoke_handler.
|
||||
- JS gps.js: `GPS._readHrLogSamples()` - парсит лог в [[relSec,bpm]] относительно startTime
|
||||
(фильтр hr>0, rel>=0, дедуп по секунде, сортировка). На остановке воркаута сэмплы берутся
|
||||
из лога, если он полнее JS-массива (fallback на JS-массив, если лог пуст). Чтение - ДО
|
||||
`_stopHrMonitor` (который чистит лог). Лог чистится при старте воркаута (ble_clear_hr, 1453).
|
||||
|
||||
## Не делал (осознанно, по риску разовой ночной записи)
|
||||
Авто-реконнект ремня при обрыве BLE - НЕ добавлял сейчас. Причина дыр была в заморозке JS,
|
||||
а не в обрыве BLE (днём была длинная непрерывная связь). Ночью пользователь запишет сон -
|
||||
это проверит, рвётся ли BLE на самом деле. Если нативный лог покажет обрыв среди ночи -
|
||||
тогда добавим реконнект. Иначе он не нужен.
|
||||
|
||||
## Также отложено
|
||||
Разделение склеенного велотрека 1792506450721 (3 поездки по orig_session_id: 17:27-17:57,
|
||||
18:00-18:32, 18:44-18:49) - одобрено, но отложено ради срочного ночного фикса.
|
||||
|
||||
## Проверка
|
||||
Синтаксис JS ок. Rust/Kotlin компиляция - в сборке. На телефоне: старт воркаута "зарядка
|
||||
(пульс)", экран гаснет на ночь, утром стоп -> сэмплы должны быть сплошные (из нативного лога),
|
||||
включая сон. Живую проверку делает пользователь ночью.
|
||||
Loading…
Add table
Add a link
Reference in a new issue