Skip to content

Commit 0c843a6

Browse files
committed
HealthStatsSync: write per-weekday typical-step blobs to BlobDB
Wires computeAllWeekdayTypicalSteps into updateHealthStatsInDatabase so monday_steps..sunday_steps rows land in BlobDatabase.HealthStats alongside the existing *_movementData / *_sleepData rows. The @GenerateRoomEntity infrastructure on HealthStat pushes them to the watch on next sync. This fixes the missing percentage in the end-of-day activity summary notification on PebbleOS watches (firmware activity_insights.c prv_calc_percent_tier returns OnAverage when the typical sums to 0, and the corresponding copy variants have no "%d%%" placeholder).
1 parent 34376a9 commit 0c843a6

1 file changed

Lines changed: 30 additions & 0 deletions

File tree

libpebble3/src/commonMain/kotlin/io/rebble/libpebblecommon/services/HealthStatsSync.kt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,15 @@ internal suspend fun updateHealthStatsInDatabase(
117117
))
118118
}
119119

120+
// Per-weekday typical-step blobs (consumed by firmware activity_insights for the
121+
// "X% above/below typical" comparison in the end-of-day activity summary notification).
122+
val typicalsByWeekday = computeAllWeekdayTypicalSteps(healthDao, today, timeZone)
123+
for ((dayOfWeek, payload) in typicalsByWeekday) {
124+
val key = STEP_TYPICAL_KEYS.getValue(dayOfWeek)
125+
stats.add(HealthStat(key = key, payload = payload))
126+
}
127+
logger.d { "HEALTH_STATS: Wrote ${typicalsByWeekday.size} weekday typical-step rows" }
128+
120129
// Batch insert all stats
121130
healthStatDao.insertOrReplace(stats)
122131
logger.d { "HEALTH_STATS: Updated ${stats.size} stats in database for automatic syncing" }
@@ -231,6 +240,27 @@ internal fun buildWeekdayTypicalsFromData(
231240
return result
232241
}
233242

243+
/**
244+
* Queries the last [TYPICAL_STEP_HISTORY_WEEKS] weeks of HealthDataEntity rows (excluding today)
245+
* and bins them into per-weekday 15-min typical-step payloads via [buildWeekdayTypicalsFromData].
246+
*
247+
* Returns one entry per weekday that has at least [MIN_DAYS_FOR_TYPICAL] distinct matching days
248+
* in the queried window. Empty map when there's no data or no weekday clears the threshold.
249+
*/
250+
internal suspend fun computeAllWeekdayTypicalSteps(
251+
healthDao: HealthDao,
252+
today: LocalDate,
253+
timeZone: TimeZone,
254+
): Map<DayOfWeek, ByteArray> {
255+
val rangeEnd = today.atStartOfDayIn(timeZone).epochSeconds
256+
val rangeStart = today
257+
.minus(DatePeriod(days = TYPICAL_STEP_HISTORY_WEEKS * 7))
258+
.atStartOfDayIn(timeZone)
259+
.epochSeconds
260+
val allData = healthDao.getHealthDataForRange(rangeStart, rangeEnd)
261+
return buildWeekdayTypicalsFromData(allData, timeZone)
262+
}
263+
234264
// Extension functions
235265
private fun Long.kilocalories(): Long = this / 1000L
236266

0 commit comments

Comments
 (0)