- 🛡 Hysteresis - Prevent flapping between states with separate enter/exit thresholds
- ⏱ Debounce - Wait for stable readings before triggering alerts
- ❄️ Cooldown - Block repeat alerts during specified periods
- 📈 Rate-of-change - Detect spikes/drops with velocity-based triggers
- 💪 Type-safe - Built with strict TypeScript and full documentation
npm install @adametherzlab/threshold-alert
# or
bun add @adametherzlab/threshold-alert// REMOVED external import: import { Alerter, AlertCondition } from "@adametherzlab/threshold-alert";
// Configure temperature alerts with hysteresis
const alerter = new Alerter({
thresholds: [{
condition: AlertCondition.Above,
value: 30, // Alert when >30°C
hysteresis: 2, // Only clear when drops below 28°C
debounceMs: 2000, // Wait 2 seconds of sustained high temps
}],
onAlert: (event) => {
console.log(`${event.triggered ? 'ALERT' : 'CLEARED'}: ${event.value}`);
}
});
// Simulate sensor input
alerter.feed(29); // No alert
alerter.feed(31); // Starts debounce timer
setTimeout(() => alerter.feed(31), 2000); // Triggers alert after 2 secondsConstructor
new Alerter(options: AlerterOptions)
type AlerterOptions = {
thresholds: ThresholdConfig[];
onAlert: AlertCallback;
cooldownMs?: number; // Global cooldown between alerts (default: 0)
};.feed(value: number): UpdateResult
.getState(): AlertState
.reset(): void
type ThresholdConfig = {
condition: AlertCondition; // Comparison type (Required)
value: number; // Threshold value (Required)
hysteresis?: number; // Hysteresis gap (default: 0)
debounceMs?: number; // Stabilization delay in ms (default: 0)
rateWindowMs?: number; // Time window for rate calculations (required for Rising/Falling)
};enum AlertCondition {
Above, // Static upper bound
Below, // Static lower bound
Rising, // Rate-of-change positive
Falling // Rate-of-change negative
}Industrial Freeze Detection
const freezerAlerter = new Alerter({
cooldownMs: 300_000, // 5 minutes between repeat alerts
thresholds: [
{ // Rapid temperature drop
condition: AlertCondition.Falling,
value: 5, // °C/minute drop
rateWindowMs: 60_000,
debounceMs: 30_000 // Confirm sustained trend
},
{ // Absolute low temperature
condition: AlertCondition.Below,
value: -20,
hysteresis: 2, // Clear when back above -18°C
debounceMs: 120_000
}
],
onAlert: ({ threshold, value }) => {
sendSMS(`Freezer ${threshold.uid}: ${value.toFixed(1)}°C`);
}
});
// Simulate compressor failure
freezerAlerter.feed(-15);
freezerAlerter.feed(-18);
freezerAlerter.feed(-21); // Triggers low temp alert after 2 minutesSee CONTRIBUTING.md for development setup and guidelines.
MIT (c) AdametherzLab