Back to blog
FILE 0xFE·SENSOR OFFLINE ALERTS WHILE TRAVELING, TWICE

Sensor Offline alerts while traveling, twice

April 19, 2026 · aws, lambda, debugging, alerts

A safety app I run pinged me every hour with "Sensor Offline — no data from IFTTT in the last 24 hours" while I was on a trip. That sensor is the motion detector at home. Of course it's quiet — I'm not home. Took two fix passes to actually shut up.

What was happening

The cron that watches "expected sources" (IFTTT, smart-home hubs, etc.) was flagging the home motion source silent. The dedupe key was hourly, so a new alert was created every hour for the same ongoing condition.

Real cause: there was no away-from-home check at all. If you leave the house, all the home-tied passive sources go quiet by design. The cron didn't know that.

What I found

Pass one (2026-04-18):

Smoke-tested, deployed, looked clean. Then woke up the next morning and got "Sensor Offline" again.

Pass two (2026-04-19):

The suppression was conditional on status === 'away'. But after an overnight gap of >4 hours, the last GPS fix was stale enough that getUserHomeStatus returned 'unknown' (with a reason of location_stale). The check bypassed the suppression and the alert fired again.

There was also a separate latent issue — my home geofence in the DB had been left at a default (a Manhattan lat/lon, not my actual home). So even with fresh GPS, "home" would never match. The stale case is what slipped through, but the geofence default needed fixing too.

The fix

One line change in the condition:

// before
if ($homeStatus['status'] === 'away') {
    $silentSources = array_diff($silentSources, HOME_TIED_SOURCES);
}

// after
if ($homeStatus['status'] !== 'home') {
    $silentSources = array_diff($silentSources, HOME_TIED_SOURCES);
}

Home-tied sources are now suppressed whenever we're not certain the user is home. Hard safety alerts (SOS, deadman switch, real inactivity threshold) ride a different code path, so failing closed on Sensor Offline doesn't mask anything actually dangerous.

Also bumped the log line to include the unknown reason so the next time I'm reading CloudWatch I can tell at a glance whether suppression was based on away vs location_stale.

Deployed by patching the file directly into the existing Lambda zip and pushing via aws lambda update-function-code — no full serverless deploy needed for a one-file change.

What I'd do differently

When you have a tri-state (home / away / unknown), default to the safe behavior on unknown. The original code defaulted to "suppression off" on unknown, which is the less safe behavior for a Sensor Offline alert — you want fewer false pages, not more.

Also: when something is "fixed" after pass one but reproduces the next morning, the pass-one fix didn't cover the case. Don't mark it shipped, mark it shipped-for-the-condition-I-saw. The overnight stale-GPS path was identical from the suppression code's perspective but different from getUserHomeStatus's.