Show HN: SignalFusionKit – a watchOS sensor-fusion library for risk detection

Ember_Wipe1 pts0 comments

GitHub - izetg/SignalFusionKit: A reference pattern for fusing watchOS HealthKit + CoreMotion signals into a risk classification. Extracted and generalized from Ember's anomaly-detection architecture. · GitHub

/" data-turbo-transient="true" />

Skip to content

Type / to search

Sign in<br>Sign upAppearance settings

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

izetg

SignalFusionKit

Public

Notifications<br>You must be signed in to change notification settings

Fork

Star

master

BranchesTags

Go to file

CodeOpen more actions menu

Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit

History<br>1 Commit<br>1 Commit

Sources/SignalFusionKit

Sources/SignalFusionKit

Tests/SignalFusionKitTests

Tests/SignalFusionKitTests

.gitignore

.gitignore

LICENSE

LICENSE

Package.swift

Package.swift

README.md

README.md

View all files

Repository files navigation

SignalFusionKit

A reference pattern for fusing multiple watchOS sensor signals — HealthKit<br>vitals, CoreMotion accelerometer data, optional CoreLocation speed — into a<br>single risk classification, with a debounce/cooldown primitive for the<br>notification side.

Extracted and generalized from the anomaly-detection pipeline built for<br>Ember, a biometric dead man's switch app. This<br>package shares the architecture , not Ember's production configuration —<br>see What this is / isn't below.

Why

Most watchOS "something bad might be happening" features (fall detection,<br>crash detection, panic triggers) end up solving the same three problems:

Combine several independent, asynchronously-arriving signals into one<br>decision, without letting a single ambiguous signal drown out a<br>single unambiguous one (e.g. a confirmed fall shouldn't be diluted by<br>averaging it against calm vitals).

Detect a sudden motion anomaly from raw accelerometer data using both a<br>"sustained" check (filters noise) and a "sharp delta" check (catches<br>instantaneous impacts a duration gate would smooth over).

Debounce the result so the user isn't re-alerted every few seconds while<br>the underlying condition persists.

SignalFusionKit is those three pieces, written as small, pure, unit-tested<br>types with zero dependency on HealthKit/CoreMotion in the parts that matter —<br>plus one thin, documented (but untested) adapter showing how to wire them to<br>real sensors.

Install

Swift Package Manager:

.package(url: "https://github.com/izetg/SignalFusionKit.git", from: "1.0.0")

Usage

.high (SpO2 below the example "low" threshold)

// 2. Feed raw accelerometer magnitude samples to detect motion anomalies.<br>let detector = MotionAnomalyDetector(config: .example)<br>let anomalyDetected = detector.ingest(magnitudeG: 4.2, at: Date())

// 3. Debounce repeated triggers.<br>let cooldown = CooldownGate(window: 60) // seconds<br>if cooldown.attempt() {<br>// safe to alert / act<br>}">import SignalFusionKit

// 1. Combine signals into a risk level.<br>let snapshot = SignalSnapshot(<br>oxygenSaturation: 93,<br>heartRateVariability: 40,<br>fallDetected: false,<br>motionAnomalyDetected: false<br>let assessment = RiskEngine.evaluate(snapshot, config: .example)<br>// assessment.level -> .high (SpO2 below the example "low" threshold)

// 2. Feed raw accelerometer magnitude samples to detect motion anomalies.<br>let detector = MotionAnomalyDetector(config: .example)<br>let anomalyDetected = detector.ingest(magnitudeG: 4.2, at: Date())

// 3. Debounce repeated triggers.<br>let cooldown = CooldownGate(window: 60) // seconds<br>if cooldown.attempt() {<br>// safe to alert / act

See WatchKitAdapter.swift<br>for a worked (but untested — see below) example wiring this to real<br>HealthKit + CoreMotion callbacks in a watchOS app.

What this is / isn't

Is: a reusable architecture for combining multi-sensor watchOS signals<br>into a risk decision, with the interesting logic (RiskEngine,<br>MotionAnomalyDetector, CooldownGate) fully unit-tested and free of Apple<br>framework dependencies.

Isn't: Ember's production configuration. The threshold values in<br>RiskEngineConfig.example and MotionAnomalyConfig.example are round,<br>illustrative numbers picked for readability in tests and docs — not the<br>tuned, validated values Ember actually ships with. Real thresholds need<br>real-world data collection, false-positive/negative tradeoffs specific to<br>your use case, and ideally domain-expert review. Treat the example configs<br>as the seam where your own calibration plugs in, not as a recommendation.

Isn't tested end-to-end on a Watch. RiskEngine, MotionAnomalyDetector,<br>and CooldownGate are pure Swift and covered by swift test.<br>WatchKitAdapter is real HealthKit/CoreMotion glue that needs Xcode and a<br>device/simulator to exercise — verify it there before relying on it.

Testing

swift test

Runs on any platform with the Swift toolchain — the tested types don't<br>import HealthKit or...

signalfusionkit example swift watchos healthkit risk

Related Articles