@toharush/homebridge-redalert
v2.1.5
Published
Homebridge plugin for Israeli Red Alert (Pikud HaOref) notifications via HomeKit motion sensors
Maintainers
Readme
What's New in v2
- Multi-source alert pipeline — Alerts stream from Pikud HaOref (HTTP) and Tzofar (WebSocket) simultaneously. Custom HTTP/WebSocket sources can be added via the UI.
- Tzofar early warning & event-ended — Full SYSTEM_MESSAGE support: early warnings (
instructionType=0) and event-ended (instructionType=1) are parsed with city ID resolution from Tzofar's city database (fetched on startup). - Sliding-window deduplication — Identical alerts from different sources are merged using a 30-second sliding window so sensors only fire once, with no boundary edge cases.
- Automatic expiry — Cities auto-clear after the configured timeout (default 30 min) if no "Event Ended" is received. Zero per-poll overhead — scans only when needed.
- Coverage map — Interactive Leaflet map in the config UI shows all monitored cities with per-sensor color-coded markers.
- Active alert overlay — Pulsing red markers on the map show currently active alerts in real-time. Click an active alert in history to fly to its location.
- Live connection status — Green/red status dots on each built-in source card show real-time connectivity.
- Alert history — Collapsible panel with filters (city, active/ended) and configurable item limit. Auto-refreshes every 2 seconds.
- Collapsible UI — Sensors and source cards collapse/expand for a cleaner config experience.
- Duplicate sensor — One-click clone of any sensor to quickly set up multiple locations with similar settings.
- Inline validation — Real-time validation highlights missing sensor names or empty city lists before you save.
- Onboarding empty state — Friendly first-run experience guides new users through adding their first sensor.
- Category mapping UI — Custom sources now clearly show how to map source-specific IDs to plugin alert types, with a dedicated "Category ID Field" input.
- Prefix matching — Match sub-areas automatically (e.g. "תל אביב" matches "תל אביב - יפו").
- Webhooks — Fire HTTP POST/PUT to any URL when a sensor activates or deactivates. Payload includes sensor name, city, title, and timestamp. Configure multiple endpoints with a 10-second timeout per request.
- Health check accessory — Optional HomeKit switch that turns OFF when all sources are unreachable.
- Source marketplace (Beta) — One-click add pre-configured add-on sources from the config UI: Mako (HTTP), Prog.co.il (HTTP), and Telegram channels (Kumta Rockets, Kumta Terror). All add-on sources are in beta. Telegram sources use QR-based login — no bot tokens needed.
- Automatic config migration — v1.x comma-separated city strings and
custom_citiesfields are auto-migrated atomically on first launch.
v1 vs v2 Comparison
| Metric | v1 | v2 | Notes | |--------|----|----|-------| | Alert sources | 1 (Pikud HaOref HTTP) | 2+ (HTTP + WebSocket + add-ons) | Fastest alert wins | | Deduplication | None | Sliding 30s window | No duplicate sensor triggers | | Expiry | Per-sensor timer | Centralized ExpiryStage | Zero per-poll overhead | | Network connections | 1 HTTP poll | 1 HTTP poll + 1 WebSocket | +1 persistent connection | | Memory overhead | ~2 MB | ~4 MB | +dedup map, history buffer, WebSocket buffers | | Dependencies | lodash | lodash + ws | +1 production dep (~200 KB) | | Disk I/O | None | Status + history (on change only) | Async non-blocking writes | | Recovery time | Up to polling interval | WebSocket: instant reconnect with backoff; HTTP: next poll cycle | Dual-source redundancy | | Performance | Baseline | 0.64–0.90x (faster) | Pipeline overhead is negative at ≤50 alerts | | Test coverage | ~60 tests | 290 tests | ~5x increase |
Bottom line: v2 is 10-36% faster than v1 for realistic workloads (≤50 simultaneous alerts) while adding deduplication, automatic expiry, and full alert history. The pipeline eliminates redundant parsing by building ParsedAlerts as a free side effect of dedup.
How It Works
- The plugin creates one motion sensor per configured sensor in HomeKit.
- An alert pipeline ingests alerts from multiple sources simultaneously — Pikud HaOref (HTTP polling every 1s) and Tzofar (WebSocket push, ~50ms delivery) are built-in. Add-on sources (Telegram channels, Mako, Prog.co.il, or custom HTTP/WebSocket) can be added via the UI.
- On each poll, alerts first pass through an ExpiryStage — it reads the dedup's active city timestamps and injects synthetic "Event Ended" alerts for cities that haven't been refreshed within the configured timeout (default: 30 min). This scan runs every ~30 seconds with zero per-poll cost.
- Alerts (including any synthetic event-ended) then pass through a DeduplicationStage — a per-category city-level check (30s sliding window) ensures cross-source duplicates only fire once. The stage simultaneously builds a
ParsedAlertsstructure for downstream consumers (zero extra parsing). - Each sensor independently filters deduplicated alerts by its configured cities, categories, and optional prefix matching.
- When an alert matches, the sensor turns ON and webhooks fire. Nationwide alerts (
רחבי הארץ) activate all configured cities. - The sensor stays ON until an "Event Ended" message is received from any source, or ExpiryStage auto-clears it after the timeout.
- A health check accessory (optional HomeKit switch) monitors source connectivity and turns OFF when all sources are unreachable.
- Create HomeKit automations based on each motion sensor (e.g. flash lights, play a sound, send a notification).
Architecture
┌────────────────┐ ┌────────────────┐ ┌────────────────┐
│ Pikud HaOref │ │ Tzofar │ │ Add-on Source │
│ (HTTP poll) │ │ (WebSocket) │ │ (HTTP/WS/TG) │
└───────┬────────┘ └───────┬────────┘ └───────┬────────┘
│ │ │
└───────────────────┼────────────────────┘
▼
┌──────────────────────────────┐
│ AlertPipeline │
│ │
│ ┌────────────────────────┐ │
│ │ ExpiryStage │ │
│ │ (auto-clear 30 min) │ │
│ │ reads dedup's seen │ │
│ └───────────┬────────────┘ │
│ │ │
│ ┌───────────┴────────────┐ │
│ │ DeduplicationStage │ │──▶ AlertHistory
│ │ (30s sliding window) │ │
│ │ + builds ParsedAlerts │ │
│ └───────────┬────────────┘ │
│ │ │
│ ┌───────────┴────────────┐ │
│ │ Fan-out to all │ │
│ │ listeners │ │
│ └───────────┬────────────┘ │
└──────────────┼───────────────┘
│
┌──────────────────┼──────────────────┐
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ Sensor A │ │ Sensor B │ │ Sensor C │
│ filter │ │ filter │ │ filter │
└─────┬─────┘ └─────┬─────┘ └─────┬─────┘
│ │ │
┌────┴────┐ ┌────┴────┐ ┌────┴────┐
▼ ▼ ▼ ▼ ▼ ▼
┌───────┐ ┌──────┐ ┌───────┐ ┌──────┐ ┌───────┐ ┌──────┐
│HomeKit│ │Web- │ │HomeKit│ │Web- │ │HomeKit│ │Web- │
│Motion │ │hook │ │Motion │ │hook │ │Motion │ │hook │
│Sensor │ │(POST)│ │Sensor │ │(POST)│ │Sensor │ │(POST)│
└───────┘ └──────┘ └───────┘ └──────┘ └───────┘ └──────┘Adding sensors does not add API calls — all sensors share the same pipeline. ExpiryStage runs first (reads dedup's seen Map to detect stale cities), then DeduplicationStage ensures each city/category combination only triggers once per 30-second window, regardless of how many sources report it. Both stages share the same Map for zero per-poll overhead.
Installation
Search for redalert in the Homebridge plugin search, or install manually:
npm install -g @toharush/homebridge-redalertConfiguration
Configure via the Homebridge UI with the built-in searchable city selector, or manually in config.json:
{
"platform": "RedAlert",
"sensors": [
{
"name": "Home",
"cities": ["תל אביב - יפו", "חיפה"],
"categories": ["rockets", "uav", "earthquake", "terror"],
"prefix_matching": false
}
],
"turnoff_delay": 0,
"alert_timeout": 1800000,
"polling_interval": 1000,
"request_timeout": 3000,
"reconnect_interval": 10000,
"max_reconnect_interval": 60000,
"ping_interval": 60000,
"pong_timeout": 420000,
"health_check": false,
"health_check_threshold": 5,
"debug": false
}Migration note: Upgrading from v1.x? Your comma-separated
citiesstrings will be automatically migrated to the new array format on first launch. No action needed.
Multi-Sensor Example
Each sensor creates a separate motion sensor in HomeKit with its own cities, categories, and prefix matching:
{
"platform": "RedAlert",
"sensors": [
{ "name": "Home", "cities": ["תל אביב - יפו"], "categories": ["rockets", "uav"] },
{ "name": "Office", "cities": ["חיפה"], "prefix_matching": true },
{ "name": "Parents", "cities": ["באר שבע"], "categories": ["rockets"] }
]
}Alert Sources
Built-in Sources
The plugin ships with two built-in alert sources that run simultaneously:
| Source | Type | Description | |--------|------|-------------| | Pikud HaOref | HTTP polling | Official Home Front Command API, polled every second (configurable) with adaptive timeout | | Tzofar | WebSocket | Real-time push alerts from tzevaadom.co.il with automatic reconnection, keep-alive, early warning, and event-ended support (city IDs resolved from Tzofar's city database) |
Both sources feed into the same deduplication pipeline, so you get the fastest possible alert delivery without duplicates.
Source Marketplace (Beta)
The config UI includes a one-click marketplace for add-on sources. All marketplace sources are in beta and are not recommended as your sole alert source:
| Source | Type | Description | |--------|------|-------------| | Mako | HTTP | Mako/N12 news mirror of Pikud HaOref. No geo-restriction. | | Prog.co.il | HTTP | Independent alert mirror with per-city items and TTL. | | Kumta Rockets | Telegram | Kumta channel for rocket & missile alerts. Requires Telegram API credentials. | | Kumta Terror | Telegram | Kumta channel for terrorist infiltration alerts. Requires Telegram API credentials. |
Telegram Sources (Beta)
Telegram sources monitor alert channels and parse city names from message content. Setup:
- Get API credentials from my.telegram.org
- Add a Telegram source from the Source Marketplace (e.g. Kumta Rockets, Kumta Terror)
- Enter your API ID and API Hash when prompted
- Scan the QR code in Telegram (Settings > Devices > Link Desktop Device)
- Once connected, the session is saved — no re-authentication needed on restart
Each Telegram source has a default alert category (e.g. rockets, terror) used when no keyword is detected in the message header. City names are extracted from the message body and matched against the plugin's city database.
Custom Add-on Sources
You can add custom HTTP, WebSocket, or Telegram sources via the UI or config.json. Custom sources support category mapping to translate source-specific alert types to the plugin's categories — including eventended to signal that an alert has cleared:
{
"platform": "RedAlert",
"sensors": [{ "name": "Home", "cities": ["תל אביב - יפו"] }],
"custom_sources": [
{
"name": "My Alert API",
"type": "http",
"url": "https://my-alert-api.example.com/alerts",
"headers": { "Authorization": "Bearer ..." },
"category_field": "type",
"category_mapping": {
"ROCKET": "rockets",
"DRONE": "uav",
"CLEAR": "eventended"
}
},
{
"name": "My WS Feed",
"type": "websocket",
"url": "wss://my-ws-feed.example.com/alerts",
"message_type": "ALERT",
"message_data_field": "data",
"category_field": "threat",
"category_mapping": {
"0": "rockets",
"5": "uav",
"2": "terror",
"99": "eventended"
}
}
]
}category_field tells the plugin which JSON field holds the category ID in each alert object (defaults to "cat"). Then category_mapping maps each ID value from your source to a plugin alert type. Map a value to eventended to signal that an alert has cleared for the listed cities — this immediately deactivates matching sensors. If no eventended mapping is provided, the plugin's ExpiryStage will auto-clear alerts after the configured timeout.
For reference: Pikud HaOref uses field cat with values 1=rockets, 6=uav; Tzofar uses field threat with values 0=rockets, 5=uav.
Webhooks
Send an HTTP request when any sensor activates or deactivates. The payload includes the sensor name, city, alert title, event type, and timestamp — route or filter on the receiving end:
{
"platform": "RedAlert",
"sensors": [{ "name": "Home", "cities": ["תל אביב - יפו"] }],
"webhooks": [
{
"url": "https://my-server.example.com/alert-hook",
"method": "POST",
"headers": { "Authorization": "Bearer my-token" }
}
]
}Payload format:
{
"event": "alert",
"sensor": "Home",
"city": "תל אביב - יפו",
"title": "ירי רקטות וטילים",
"timestamp": 1700000000000
}The event field is "alert" when a sensor activates and "ended" when it deactivates. Multiple webhook URLs can be configured — all fire for every sensor event.
Options Reference
Sensor Options
| Option | Required | Default | Description |
|--------|----------|---------|-------------|
| name | Yes | — | Unique sensor name (appears in HomeKit) |
| cities | Yes | — | Array of city names in Hebrew. Select from the built-in list or type custom names |
| categories | No | All | Alert types to monitor. If empty, all categories are enabled |
| prefix_matching | No | false | City names match by prefix (e.g. "תל אביב" matches all Tel Aviv sub-areas) |
HTTP Source Options
| Option | Default | Description |
|--------|---------|-------------|
| polling_interval | 1000 | How often to poll HTTP sources in ms (500–5,000) |
| request_timeout | 3000 | Max time to wait for HTTP response in ms (1,000–10,000) |
WebSocket Source Options
| Option | Default | Description |
|--------|---------|-------------|
| reconnect_interval | 10000 | Initial delay (ms) before reconnecting after disconnect |
| max_reconnect_interval | 60000 | Maximum reconnect delay (ms) after repeated failures (exponential backoff cap) |
| ping_interval | 60000 | How often (ms) to send a keep-alive ping |
| pong_timeout | 420000 | Max time (ms) to wait for a pong response before terminating (default: 7 min) |
Sensor Behavior
| Option | Default | Description |
|--------|---------|-------------|
| turnoff_delay | 0 | Delay (ms) before turning off after alert ends. Resets if a new alert arrives (0–3,600,000) |
| alert_timeout | 1800000 | Auto-clear alerts (ms) if "Event Ended" is never received. Default: 30 min (600,000–3,600,000) |
Health Monitoring
| Option | Default | Description |
|--------|---------|-------------|
| health_check | false | Adds a Switch to HomeKit that turns OFF when all sources are unreachable |
| health_check_threshold | 5 | Consecutive failures per source before reporting unhealthy (2–30) |
Webhooks
| Option | Required | Default | Description |
|--------|----------|---------|-------------|
| url | Yes | — | The endpoint URL to call on alert/ended events |
| method | No | POST | HTTP method (POST or PUT) |
| headers | No | {} | Custom headers (e.g. {"Authorization": "Bearer ..."}) |
Telegram Options
| Option | Required | Default | Description |
|--------|----------|---------|-------------|
| telegram_api_id | Yes* | — | Telegram API ID from my.telegram.org. Required when using Telegram sources |
| telegram_api_hash | Yes* | — | Telegram API Hash from my.telegram.org. Required when using Telegram sources |
General
| Option | Default | Description |
|--------|---------|-------------|
| debug | false | Enable extra debug logging |
Available Categories
These categories can be selected per-sensor to filter which alert types trigger the sensor:
| Key | Description |
|-----|-------------|
| rockets | Rockets & Missiles (ירי רקטות וטילים) |
| uav | UAV Intrusion (חדירת כלי טיס) |
| nonconventional | Non-conventional Threat |
| warning | Heads-up Notice (התרעה מוקדמת) |
| earthquake | Earthquake (רעידת אדמה) |
| cbrne | Chemical / Bio / Nuclear |
| terror | Terrorist Infiltration (חדירת מחבלים) |
| tsunami | Tsunami (צונאמי) |
| hazmat | Hazardous Materials (חומרים מסוכנים) |
Note:
eventendedis a special mapping key available only in custom sourcecategory_mapping. It signals that alerts have cleared for the listed cities. It is not selectable per-sensor — event-ended is always processed automatically to deactivate sensors.
Documentation
For detailed docs, architecture, automation examples, and troubleshooting, see the Wiki.
Disclaimer
חשוב מאוד לקרוא!
התוסף איננו תוסף רשמי של פיקוד העורף או מערכת הבטחון. התוסף משתמש ב-API של פיקוד העורף לקבלת התרעות ולכן יתכנו שיבושים. בכל מקרה יש להמשיך להשתמש באמצעיים הרשמיים של מערכת הבטחון.
- This plugin is not an official Home Front Command product.
- The plugin uses the Pikud HaOref public API. There may be delays or disruptions.
- Always use the official alert systems alongside this plugin.
License
MIT

