What inspired me
A lot of families have a relative who lives alone. Doorbell and motion apps tell them about everything (every delivery, every cat, every passing car), so the notifications end up muted, and the one morning that actually matters gets lost in the noise.
I wanted the opposite: something that stays quiet, learns what a normal morning looks like at one home, and speaks up once, with a reason, when today is different, without a camera watching anyone. The Ring track lists caretaking as a priority and calls a plain motion alert "obvious", and that pushed me toward a careful, non-security use of Ring.
That became Rhythm: a quiet morning check-in built only on Ring event metadata (activity times and device status, never video, images or sound). After 14 silent days of learning, it sends every family member one gentle email when her morning is later than usual. The email explains why, and family can reply with one tap: She's fine or She's away until…
Rhythm is a check-in aid, not a safety or medical device.
What I learned
- Times alone are enough to notice that a routine has changed. You don't need to watch anyone.
- "No events" is not the same as "device offline". Treating missing data as a quiet morning is exactly how monitoring tools lose trust, so Rhythm reports an offline device or a lost connection instead of raising a care alert.
- A minimum wait matters more than a clever statistic. My evaluation showed that without it, a 15-minute margin gives about 1.4 false alarms per month; with it, essentially zero.
- Real APIs have quirks you must design for. Event History only covers time after access is granted, and timestamps are UTC milliseconds with no timezone, so a real product has to plan for both from day one.
How I built it
Rhythm is a Python app: FastAPI for the dashboard, setup page and reply links, SQLite for storage, httpx for the Ring Partner API, and plain HTML/SVG/JavaScript on the front end. python -m rhythm starts everything with one command.
Ring integration. A client for the device list, device status and Event History, tested live against the Ring Developer Playground, plus a handler for signed Ring webhooks (HMAC-SHA256, de-duplicated by request ID).
The rule. For today's bucket b (weekday or weekend), with S_b the first-activity times of the last 8 weeks (excluding alert and away days), the cutoff is
$$ \text{cutoff}b = \max\big(Q{0.95}(S_b) + m,\; f_b\big) $$
where Q₀.₉₅ is the 95th percentile, m is a margin (15 minutes by default) and f_b is a minimum wait (10:00 on weekdays, 11:00 at weekends). With fewer than 5 mornings in a bucket, a conservative fixed cutoff is used instead. An alert fires if no activity is seen by the cutoff plus a 10-minute grace period, or if the first activity comes after the cutoff. Night events (before 05:00) and doorbell presses (usually visitors) never count as her activity.
Product. One email per day per family member, an activity follow-up that says "this may be her or a visitor", a setup page (up to three family members; English, Italian or French; Relaxed, Standard or Careful sensitivity), required consent, 8-week data retention, export and delete-everything, a weekly summary, and light, dark and high-contrast modes.
Evaluation. I ran Rhythm's own rule on 60 simulated households over 16 weeks, with realistic wake times, weekend shifts, noise, sleep-ins, night events, doorbell presses, trips, late mornings and silent days. All of this data is synthetic.
| Measure | Standard | Careful |
|---|---|---|
| False alerts per household per month | 0.00 | 0.07 |
| Silent days caught | 60 / 60 | 60 / 60 |
| Late mornings caught | 94 / 140 | 122 / 140 |
| Alerts during announced trips | 0 | 0 |
Testing. 53 automated tests cover the rule, time zones and daylight saving, one email per day per family member, signed links, webhooks, and the lost-connection case.
Challenges I faced
- No physical Ring device. The Playground gave me a fake doorbell and real API responses, but only a simulated live-view event (
on_demand), no past days and no offline transition. I didn't treat any of that as real motion data. The demo routine is simulated, and the README states exactly what is real and what isn't. - Missing data looks like a quiet morning. An expired token or an offline device produces silence, which a naive rule would read as a problem. Rhythm records every successful Ring contact and reports a lost connection instead of a false alarm.
- Time zones. Every local time is computed from UTC using the household's timezone, including across the daylight-saving change.
- Safe email replies. Email scanners open links automatically, so opening a link saves nothing; only the confirm button does. Links are signed, expire after 24 hours and work once.
- Bugs found by testing. Review and evaluation surfaced real bugs: a follow-up that never fired, repeat emails when one address failed, and an away period that also paused the days before it. Each one is fixed and covered by a test that failed before the fix.
Log in or sign up for Devpost to join the conversation.