REM sleep detection for the Pebble 2 and Pebble Time 2, layered on top of Pebble Health.
Pebble Health auto-tracks sleep but has no REM concept and hides awake times. This app reads last night's Light/Deep sessions and per-minute heart-rate and movement data from Pebble Health, then carves out a REM stage and an awake timeline — viewable directly on the watch.
- Pebble 2 / Pebble 2 HR (
diorite), with HR monitor - Pebble Time 2 (
emery), color, with HR monitor - C SDK,
healthcapability enabled
The hypnogram uses color constants; on the color Emery display they show as intended, and on the black-and-white Diorite display they render in B&W.
Built on CloudPebble. To build with the local SDK instead:
pebble build
pebble install --emulator diorite # or emery, or --phone <ip>
health_service_activities_iterate()collectsHealthActivitySleep(Light) andHealthActivityRestfulSleep(Deep) sessions over the last 24h.- A per-minute array defaults to Awake; Light sessions mark Light, Deep overrides; gaps are Awake.
health_service_get_minute_history()supplies per-minute HR + movement (vmc).- REM is carved only from Light minutes using a Walch-feature-inspired weighted score (normalized HR, HR variability proxy, HR delta), gated by a REM latency window, a minimum episode length, and short-gap bridging.
App Deep == Pebble Deep. App Light + REM == Pebble Light. App Awake == gaps.
REM_SCORE_THRESHOLD (top of src/main.c) is the main dial — range 80–130,
default 100.
- Pebble minute data lags ~15 min.
- HealthService API is read-only; results cannot be written back to Pebble Health.
- True HRV (RR intervals) and respiration are not exposed by the Pebble API, so minute-averaged HR is the ceiling. This is a heuristic, not the trained Walch model.
Walch et al. 2019, "Sleep stage prediction with raw acceleration and PPG heart rate" (Sleep, zsz180).
MIT — see LICENSE.