Profile
Back to NewsBack
GitHub Trending 34 min
Reader Mode
bvis/aegis-hass: Aegis — Unofficial Home Assistant integration for Ajax Security Systems and co-branded apps

bvis/aegis-hass: Aegis — Unofficial Home Assistant integration for Ajax Security Systems and co-branded apps

21 hours ago

Aegis for Ajax — Home Assistant Integration

HACS Custom</a> GitHub Release</a> Tests</a> Validate with hassfest</a> HACS Validation</a> License: MIT</a> Code style: ruff</a>

Disclaimer: This is an unofficial third-party integration and is not affiliated with, endorsed by, or supported by Ajax Systems. Use at your own risk. This integration communicates with Ajax Systems servers using the same protocol as the official mobile app. Ajax Systems may change their API at any time, which could break this integration without notice.

Aegis is a Home Assistant custom integration for Ajax Security Systems — works with any co-branded Ajax app (Protegim, ADT, G4S, and many more).

Communicates via gRPC (the same protocol the official mobile app uses). No Enterprise API key required — just your regular account credentials.

How It Works

Ajax Systems provides co-branded versions of their mobile app to security companies worldwide. Each co-branded app connects to the same Ajax cloud backend but uses a unique application label to identify itself. This integration emulates the mobile app's gRPC protocol, so it works with any co-branded variant.

You need to know the application label of your Ajax provider. This is an internal identifier that the app sends to the Ajax cloud (see the Known App Labels table below). If you use the main Ajax app, the label is Ajax.

Features

  • Alarm Control Panel: Arm away, disarm, night mode, group arming with PIN code support. When the space is in group / zone mode, per-group panels are created and react to FCM push events instantly — arming or disarming a single group from the Ajax mobile app reflects in HA within seconds (whole-space transitions already worked this way; group-level transitions joined in 1.5.0). Each group panel also lists which devices belong to that group, in its member_device_ids and member_device_names attributes — Ajax group membership is otherwise only visible in the mobile app, and it is a separate taxonomy from rooms (a device has both, independently). Works with Alexa via Home Assistant Cloud (see Arm modes & voice assistants). Optionally shows the hub's exit / entry delays as arming / pending, driven by the hub's own signals (1.18.0, off by default — see Exit and entry delays)
  • Force Arm Services: aegis_ajax.force_arm and aegis_ajax.force_arm_night to arm ignoring open sensors
  • Binary Sensors: Door open/close, motion detection, smoke, steam (FireProtect 2 chamber discriminator), leak, tamper, CO, heat, glass break, vibration, tilt (DoorProtect Plus accelerometer), CRA monitoring status, cellular connection, lid tamper, external contact alert (wired reed switches on DoorProtect/Hub Hybrid inputs), external contact fault, MultiTransmitter wired-input alert with alarm category, anti-masking, interference detection, ethernet link, Wi-Fi link, mains power
  • Hub Network: Real-time hub network data — ethernet/wifi/gsm connection status, Wi-Fi SSID and signal strength, IP addressing, cellular signal strength and network type, power supply status
  • Sensors: Battery level, temperature, humidity, CO2, signal strength, GSM type (2G/3G/4G), Wi-Fi signal level, Wi-Fi SSID, Wi-Fi IP, IMEI, Ethernet IP/gateway/DNS, cellular signal/network, connection type
  • Electrical readings for WallSwitch / Socket family devices: live current draw (A), measured line voltage (V) when the firmware reports it, cumulative electric energy consumed (kWh, wired into HA's Energy dashboard via state_class=total_increasing), and instantaneous power (W). Power is a direct firmware reading on the Outlet Type E / F family and a derived current × measured voltage reading (opt-in, with a 230 V nominal fallback) on the WallSwitch family. Updates arrive on the hub's push channel; a per-hub 60 s STATUS refresh fills the gap on device families whose firmware emits live deltas sparsely (Outlet Type E / F). The sensors also persist across HA restarts so a constant load like a fixed-speed pump doesn't render as unknown after a reboot until the next state change.
  • Manual hub refresh button: one button._refresh_hub per configured hub. Pressing it (or calling button.press from an automation) forces an immediate STATUS refresh from the hub — useful after toggling an appliance, when waiting for the next 60 s periodic tick would feel sluggish. Rate-limited to one press per 60 s per hub so a stuck automation can't generate unusual traffic against Ajax's servers.
  • Switches: Relays, wall switches, sockets (multi-channel support) — turn on/off via DeviceCommandDeviceOn / DeviceCommandDeviceOff gRPC services
  • Lights: Dimmers with absolute brightness control via DeviceCommandBrightness
  • Locks: Ajax SmartLock and LockBridge (Yale) — lock and unlock. Hub-attached Jeweller locks (e.g. installer-added Yale modules) are commanded over the generic device on/off path. Unlatch (lock.open) isn't exposed: it requires Ajax's cloud SmartLock service, which the hub-attached locks seen so far aren't registered with — the Ajax app can't unlatch them either
  • Hub Chime switch: a per-hub Chime switch toggles the hub-wide chime — the tone the hub plays when a monitored door/window opens while disarmed (the Ajax app's bottom-left toggle). Only created for hubs that expose the feature, and requires the account's chime-edit permission. Changes made from the Ajax app are reflected in Home Assistant immediately.
  • Valves: Ajax WaterStop and WaterStop Fibra surface as native valve.* entities reflecting WaterStopChannel.state (open / closed), is_transitioning, and a stuck attribute pulled from the channel-level MALFUNCTION_IS_STUCK. Open and close are supported — the valve can be controlled from Home Assistant and automations
  • Siren settings: HomeSiren / StreetSiren devices expose two config entities — a Siren volume select (Very loud / Loud / Quiet / Disabled) and an Alarm duration number (seconds) — read from and written back to the same settings the Ajax app shows. Writing requires an account with device-edit permission; a successful write triggers a targeted re-read so the entity confirms the hub's actual value within seconds
  • Hub firmware update (read-only): each hub exposes an update._firmware entity that reports the firmware version the hub is actually running as its installed version — also shown under Firmware on the hub's device page — and whether Ajax has queued an update against it, with download progress when the cloud is pushing bytes. No install button is exposed on purpose — firmware updates remain Ajax-scheduled and the entity is informational. Hubs whose firmware doesn't report the running version behave as before (queued-update info only).
  • Per-device firmware update (read-only): each non-hub device gets an update._firmware counterpart sourced from the same read-only snapshot, surfacing the queued target version, download progress and a security-critical flag. Disabled by default (a typical install has 10-30 devices) — enable the ones you want to watch
  • Persistent notifications (optional): an option that surfaces selected security events as Home Assistant persistent notifications that stay visible until dismissed, as a built-in alternative to wiring your own persistent_notification.create automation. The event set is configurable and defaults to real incidents (alarm, panic, tamper, fire, CO, flood, glass break). Off by default; requires FCM push
  • Cameras: MotionCam alarm-photo sequences in HA, plus on-demand captures on PhOD models
  • Photo Storage: Captured photos saved to /media/ajax_photos/ with timestamp overlay, configurable retention
  • Media Browser: Browse captured photos per device via HA Media Browser
  • Event Platform: Security events from FCM push notifications (alarm, arm/disarm, tamper, panic, fire, flood, motion, and more)
  • Device automation triggers: every Ajax security event is a named device trigger on the hub device, selectable directly in the HA automation editor (no manual event-type strings)
  • Doorbell events: video-edge doorbells get a per-device event entity emitting HA's canonical ring event, and a doorbell motion push turns the doorbell's motion sensor on (30 s auto-off)
  • Button presses: an Ajax Button in control mode gets a per-device event entity that fires pressed — no push (FCM) needed, and it works while the system is armed or disarmed
  • Per-device bypass switches: each non-hub device can get a bypass switch to deactivate / reactivate it; gated by the bypass_switches option (auto / always / never). The switch reads on for a device deactivated anywhere — from Home Assistant, the Ajax app, or by an installer — and its deactivation_kinds attribute names the mode in force. Mind Ajax's own wording: temporary_deactivation_ is the permanent deactivation (until you re-enable it), one_time_deactivation_ lasts a single arming cycle, and a *_tamper variant means only the device's tamper protection is off. Both directions work from Home Assistant: switch on applies the same permanent deactivation the Ajax app does, switch off puts the device back under protection — and the integration re-reads the device after every write, so the switch never shows a state the hardware isn't in (#338)
  • Device removal follows the panel: deleting a device in the Ajax app removes it from Home Assistant within seconds — entities, device card and cache. Deletions that happen while Home Assistant is offline are picked up on the next reconnect: the device stops claiming state and its leftover card can be removed from its device page (Delete device — offered for any device the hub no longer reports; live devices are refused and a mistaken deletion re-creates itself from the next snapshot) (#422)
  • Logbook: Human-readable security event descriptions with icons
  • Real-time updates: Persistent gRPC stream for instant sensor state changes (< 1 second latency)
  • Push notifications: FCM integration for immediate event delivery
  • 2FA support (TOTP)
  • Reauth flow: when the Ajax session is rejected (password rotated, 2FA newly enabled, server-side logout), HA shows the orange "Reconfigure" banner with a guided password prompt — entity ids, areas, automations and history survive untouched
  • HA Repairs: diagnosable conditions surface as cards under Settings → Repairs instead of being buried in home-assistant.log — hub offline > 24h, sustained HTS reconnect failure, FCM credentials rejected (with one-click fix flow), a push connection repeatedly killed by an unreadable message (the integration renews its own push registration to recover), or grpcio version below the floor on Home Assistant OS
  • System Health card: one-line snapshot under Settings → System → Repairs → System Information with gRPC reachability, HTS / FCM connection ratios, last push / last poll ages — replaces log archaeology as the first triage step
  • DHCP discovery: Ajax hubs on the same LAN appear as a "Discovered" card in Settings → Devices & Services, no need to search by name
  • MDI icons for all entity types
  • Automation Blueprints: Ready-to-use automation templates (see below)

Requirements

  • Home Assistant 2024.1.0 or later
  • An Ajax Security account (email + password)
  • At least one Ajax hub online
  • The application label of your co-branded Ajax app

Installation

HACS (Recommended)

Open HACS Repository</a>

Click the button above, or manually:

  1. Open HACS in Home Assistant
  2. Click the three dots menu (top right) and select Custom repositories
  3. Add https://github.com/bvis/aegis-hass with category Integration
  4. Search for "Aegis for Ajax" in HACS and click Install
  5. Restart Home Assistant
  6. Add the integration:
Add Integration</a>

Manual

  1. Download this repository
  2. Copy custom_components/aegis_ajax/ to your Home Assistant config/custom_components/ directory
  3. Restart Home Assistant
  4. Go to Settings > Devices & Services > Add Integration and search for "Aegis for Ajax"

Configuration

  1. Enter your Ajax account email and password
  2. Enter the App Label of your co-branded app (see table below, or type your own)
  3. If 2FA is enabled, enter your TOTP code
  4. Select which spaces (hubs) to add
  5. Done
Recommended: use a dedicated Ajax account, separate from the one on your phone.
Instead of your primary admin login, create a separate Ajax account, invite it to
your space (Ajax app → space → Users → Invite) and grant it only what the
integration needs. A non-admin User role is enough to read device state and
arm / disarm — but to also receive push events, the role's notifications toggle
is not enough: Ajax filters event delivery server-side by permission level, and
a User role with notifications turned on still receives zero events (#234, #319);
in practice the account needs admin / full access (see the FCM troubleshooting
note below). You can also revoke its
photo / video access if you don't use
Photo on Demand or alarm photos, so Home Assistant never has access to camera images. This keeps
your main credentials out of HA and limits what a compromised HA host could reach
in your Ajax installation.
> This also matters for real-time updates. Running the same Ajax account in
both your phone app and Home Assistant can prevent instant push notifications from
reaching HA — real-time event notifications (alarm, doorbell, motion and other
sensor events) would then not reach HA reliably. Giving HA its own account avoids
this contention. (Arm / disarm panel state still follows within ~1 s via the hub's
status channel, with or without push.)
> Trade-offs to know: without photo / video permission the MotionCam Photo-on-Demand
button won't work, and per-device bypass switches need the account to hold the
device-deactivation (DEVICE_EDIT) permission — the default bypass_switches: auto
simply won't create them for an account that lacks it. As a safety net, the
integration re-reads the device a few seconds after every bypass write and logs
a warning when the panel disagrees, so the switch never shows a state the
hardware isn't in.

Options

After setup, configure these in Settings > Devices & Services > Aegis for Ajax > Configure:

| Option | Default | Description | |---|---|---| | Poll interval | 300s | Fallback polling interval, allowed range 60-300 seconds (real-time stream handles most updates) | | Force arm | disabled | Arm ignoring open sensors and malfunctions (bypasses hub safety checks) | | Show "Arm Home" button | enabled | Whether the alarm panel advertises Arm Home. It duplicates Ajax's single partial (Night) mode and exists mainly so the Nabu Casa / Alexa skill discovers the panel. Disable to hide the redundant button if you don't use Alexa / Home Assistant Cloud — Arm Away and Arm Night are unaffected. | | Show exit / entry delays as panel states | disabled | Shows the hub's per-detector Delay when leaving as the panel's arming state and Delay when entering as pending, driven by the hub's own signals. Opt-in because automations waiting for armed_away then fire once the exit delay completes. See Exit and entry delays. | | PIN code | disabled | Require PIN for arm/disarm from HA UI | | FCM credentials | — | Firebase credentials for push notifications (optional) | | I don't use push notifications | disabled | Enable if you intentionally run without push. Hides the recurring "FCM not configured" reminder and Repair card (and the WARNING log). Real-time events (doorbell, arm/disarm, alarm) still won't reach Home Assistant until you configure FCM — this only silences the reminder. | | Photo retention (days) | 30 | How many days to keep captured photos (1-365) | | Max photos per device | 100 | Maximum photos stored per camera (0 = unlimited) | | Auto-create labels | enabled | Create and assign aegis_* labels (camera, hub, door, motion, …) to your entities for easy grouping in dashboards/automations. Disable if you prefer to manage labels manually — with the option enabled the integration re-creates the labels on every restart. | | Bypass switches | auto | Whether to create a bypass switch per device. auto only creates them if your Ajax account has the DEVICE_EDIT permission (required to deactivate devices); always creates them unconditionally; never skips them. Note: Home Assistant does not auto-remove entities when a platform stops providing them — if switching from always (or upgrading from an older version that always created them) to auto/never on an account that can't deactivate devices, the existing switch.*_bypass entries linger as unavailable until you delete them manually (Settings → Devices & Services → device → entity → Delete). |

Known App Labels

Each co-branded Ajax app uses an internal label name to identify itself to the Ajax cloud. This label is not always the same as the app's display name. The integration includes all known labels in a dropdown during setup.

| App Label | App Name | Region | |---|---|---| | Ajax | Ajax Security System | Worldwide | | ajax_pro | Ajax PRO | Worldwide | | AIKO | AIKO | Estonia | | 3dAlarma | 3D Alarma | Spain | | E-Pro | E-Pro | — | | G4S_SHIELDalarm | G4S SHIELDalarm | Europe | | GSS_Home | GSSecurity | — | | HomeSecure | HomeSecure | — | | Hus_Smart | Hus Smart | Scandinavia | | Novus_alarm | Novus | — | | Protegim_alarma | Protegim | Spain | | Protecta | Protecta | — | | SecureAjax | SecureAjax | — | | Smart_Secure | Smart & Secure | — | | Verux | Verux | — | | Videotech_alarm | Videotech | — | | kale_alarm_x | Kale Alarm X | Turkey | | ADT_Alarm | ADT Alarm | — | | ADT_Secure | ADT Secure | — | | Yoigo_ADT_Alarma | Yoigo ADT Alarma | Spain | | Masmovil_ADT_Alarma | Másmóvil ADT Alarma | Spain | | Euskaltel_ADT_Alarma | Euskaltel ADT Alarma | Spain | | Elotec | Elotec Ajax | Norway | | Yavir | Yavir | Ukraine | | Oryggi | Oryggi | Iceland | | acacio | acacio | — | | esahome | esahome | — |

How to find your app label

If your provider is not in the list above, you can find the correct label by:

  1. Check the app's Google Play URL — search for the package name (e.g. com.ajaxsystems.yourapp) and cross-reference with the table
  2. Check the app's resources — the label is stored as ajax_app_name in strings.xml
You can type any custom label during setup if yours is not listed.

Supported Devices

| Type | Devices | Entities | |---|---|---| | Hub | Hub, Hub Plus, Hub 4G, Hub Lite, Hub 2, Hub 2 Plus, Hub 2 4G, Hub 3, Hub Hybrid (2 / 4G), Hub Mega, Hub Fibra, Hub Yavir / Yavir Plus, Hub Fire, Hub Superior | Alarm panel, battery, GSM type/connected, CRA monitoring status, CRA company (diagnostic), lid tamper, IMEI, hub network sensors (Ethernet/Wi-Fi/GSM, IP data, cellular signal/network, mains power) | | Door Sensors | DoorProtect, DoorProtect Plus, DoorProtect Fibra, DoorProtect S, DoorProtect S Plus, DoorProtect Plus Fibra, DoorProtect Plus G3 Fibra, DoorProtect G3 | Door open/close, tamper, vibration (Plus), tilt (Plus, accelerometer), battery, temperature, signal, external contact alert (wired contact triggered), external contact fault (wiring broken) | | Motion Sensors | MotionProtect, MotionProtect Plus, MotionProtect Outdoor, MotionProtect Curtain (and outdoor / mini / plus base variants), MotionProtect S / S Plus, MotionProtect G3 family (incl. Fibra), MotionProtect Plus Fibra / G3 | Motion detected (real-time), tamper, battery, temperature, signal | | Cameras | MotionCam, MotionCam Outdoor, MotionCam Fibra (& base), MotionCam G3, MotionCam HD, MotionCam PhOD, MotionCam PhOD Fibra, MotionCam Outdoor PhOD, MotionCam Outdoor 2/4 PhOD, MotionCam S PhOD (& AM), MotionCam Superior PhOD | Photo on-demand capture + storage (PhOD models), motion detected, tamper, battery; internal temperature on MotionCam Outdoor PhOD (confirmed on hardware) | | Glass Break | GlassProtect, GlassProtect S, GlassProtect Fibra | Glass break detection, tamper, battery | | Combi | CombiProtect, CombiProtect S, CombiProtect Fibra | Motion, glass break, tamper, battery | | Fire/Smoke | FireProtect, FireProtect Plus, FireProtect 2 (all sub-models — heat-only hrb/hsb, CO-only crb/csb, multi-sensor hcrb/hcsb, AC-powered _ac, UL-listed _ul) | Smoke, steam (FireProtect 2 only — chamber discriminator), CO, high temperature, tamper, battery — sub-models without a given sensor expose only the relevant entity | | Water Leak | LeaksProtect | Leak detected, tamper, battery | | Air Quality | LifeQuality | Temperature (°C), humidity (%), CO₂ (ppm), battery, signal | | Relays/Switches | Relay, WallSwitch, Socket (and outlet variants) | On/off per channel; electrical readings (current, voltage, energy) across the WallSwitch / Socket family. Power is exposed as a direct reading on the Outlet Type E / F family (the firmware reports it natively) and as a derived current × voltage reading on the WallSwitch family. The dry-contact Relay switches a potential-free contact and has no load metering — its Voltage sensor reports the module's own supply voltage (~12 V on a 12 V PSU), and Current / Energy read 0 by design. | | Light switches | LightSwitch (Jeweller / Fibra) | On/off per channel | | Lights | LightSwitch Dimmer | Brightness control | | Locks | SmartLock, LockBridge (Yale) | Lock and unlock; state surfaces locked / unlocked. Hub-attached Jeweller locks (e.g. installer-added Yale modules on a third-party backend) are commanded over the generic device on/off path (#206 / #219). _Note:_ unlatch (lock.open) isn't exposed on these — it's only available through Ajax's cloud SmartLock service, which they aren't registered with (the Ajax app can't unlatch them either) | | Hub Chime | Hubs that expose the chime setting | switch._chime toggles the hub-wide chime tone (door-open alert while disarmed); reflects app-side changes instantly. Requires the account's chime-edit permission | | Doorbells | Wireless DoorBell (standalone Jeweller ring button), MotionCam Video Doorbell, SmartLock / LockBridge variants with integrated ring button | doorbell_pressed on the hub's security event entity, plus a per-device event entity (device_class: doorbell) that emits Home Assistant's canonical ring event; a doorbell motion push also flips the doorbell's motion_detected on (30 s auto-off). SmartLock variant exposes lock state on the lock entity. Requires FCM credentials configured. _Note:_ the video doorbell has no photo capture in Home Assistant. For live view, if the doorbell is bridged through an Ajax NVR you can reach its stream over ONVIF — see Video cameras (ONVIF / RTSP). | | Keypads | Keypad, KeypadPlus, KeypadCombi, KeypadTouchscreen | Battery, tamper, temperature, signal, NFC status | | Buttons | Button (Jeweller) | In panic mode, panic on the hub's security event entity (requires FCM). In control mode, a per-device event entity (device_class: button) that fires pressed on every press — this one rides the hub's status channel, so it works without FCM. Short and long click are indistinguishable in everything the hub reports, so there is one event rather than two. The DoubleButton is panic-only and reports nothing in control mode | | Keyfobs (experimental) | SpaceControl, SpaceControl S | Grouped under a single Keyfobs device, with one Active binary sensor per keyfob (diagnostic). The active/inactive value is experimental and not yet confirmed — see Keyfobs (experimental). Who armed/disarmed via a keyfob already appears in the logbook regardless | | Sirens | HomeSiren, HomeSiren S, HomeSiren Fibra, HomeSiren G3, StreetSiren, StreetSiren S, StreetSiren Plus, StreetSiren Plus Fibra/G3, StreetSiren Fibra, StreetSiren Double Deck (& S / Fibra) | Battery, tamper, signal, siren volume (select) and alarm duration (number) on all models; internal temperature on the HomeSiren / StreetSiren family including the Double Deck variants, except StreetSiren S, StreetSiren Fibra and StreetSiren Plus Fibra, which report only their settings on this path | | Range extenders | ReX, ReX 2, ReX 2 Fire | Battery, signal | | Wired-Input Modules | MultiTransmitter, MultiTransmitter Fibra, Hub Hybrid wired inputs | Tamper of the module itself; each registered wired sensor appears as its own device with an alert binary sensor and an alarm_type attribute (intrusion / fire / glass_break / vibration / …) |

Siren temperature matches the value shown in the Ajax app and updates live over the hub's push channel (it moves in ~1 °C steps, as in the app). Earlier versions sourced it from the siren's internal board sensor, which read a few degrees high on a sun-exposed StreetSiren and refreshed only every 15 minutes; since 1.12.1 it reads the same internal-temperature value the app shows (#312).

Photo on Demand

MotionCam PhOD (Photo on Demand) models support capturing photos remotely:

  1. Press the "Capture photo" button entity in HA
  2. The hub triggers the camera, and the photo URL is retrieved via the Ajax notification system
  3. The photo is downloaded, a timestamp overlay is burned into the image, and it's saved to /media/ajax_photos/{device_name}/
  4. View photos in the camera entity or browse all captures via Media Browser → Aegis Security Photos
Note: Regular MotionCam models (without PhOD) do not support on-demand photo capture. The button entity is only created for PhOD models.

Photos are automatically cleaned up based on your retention settings (configurable in integration options).

Alarm photos in Media Source

MotionCam models, including PhOD, can display photos attached to real alarms. This does not trigger a new capture: regular MotionCam models still have no on-demand capture button. The camera entity shows the latest alarm's contact sheet (one, two or three frames, depending on the camera configuration); a newer PhOD capture can also update that entity. Historical imports never replace a newer preview.

Open Media Browser → Aegis Security Photos → device → alarm album to browse each sequence. Albums are saved under /media/ajax_photos/{device_name}/YYYY-MM-DD_HH-MM-SS-ffffff/, using the alarm's timestamp in Home Assistant's timezone, with numbered frames (01.jpg, 02.jpg, 03.jpg) and preview.jpg. The device's last.jpg is the latest preview. PhOD captures remain separate files named YYYY-MM-DD_HH-MM-SS-ffffff.jpg; microseconds avoid same-second collisions. Retention removes whole expired albums as well as old captures.

New camera-alarm pushes add one Ajax gRPC streamNotificationMedia call using the notification and hub IDs from the push. That same stream waits for pending frames to finish; it never queries history or reopens the stream. Completed local albums are skipped, including after restart. Existing PhOD capture behavior is unchanged.

For missed events, call aegis_ajax.refresh_alarm_images manually. Per space, each invocation adds one findNotifications query against the Alarm folder (up to 50 events) and at most 10 media streams, skipping completed local albums before opening a stream. A five-minute per-space cooldown rejects repeated calls before any network request. Both paths also download available frames using their signed image URLs. There is no periodic history polling; unavailable or incomplete sequences can be recovered with a later manual backfill.

Video cameras (ONVIF / RTSP)

Ajax video hardware (the NVR and the IP cameras / doorbell channels bridged through it) exposes a local ONVIF/RTSP service. This integration does not stream or proxy that video itself — instead it reads the connection details so you can point Home Assistant's built-in ONVIF integration at each camera and get a real camera entity with live view.

Local network only. The stream goes straight from Home Assistant to the camera/NVR on your LAN — it never travels through the Ajax cloud. Home Assistant must be on the same network (or reachable to it over a VPN). There is no cloud/remote live view.

Steps:

  1. Enable ONVIF in the Ajax app for the NVR (and/or each camera). It's off by default. Create an ONVIF username and password there — Home Assistant will need them, and the integration never sees them.
  2. Add the ONVIF integration in Home Assistant (Settings → Devices & services → Add Integration → ONVIF). Home Assistant usually auto-discovers the Ajax cameras on your LAN, so you can just pick the discovered device and enter the ONVIF user/password from step 1 — no need to type the IP. Home Assistant then creates the camera entity with live view.
  3. If a camera isn't auto-discovered (or to verify the connection details), get its IP and ports from the integration diagnostics: Settings → Devices & services → Aegis for Ajax → ⋮ → Download diagnostics, under the video_edge_onvif_rtsp section. Each VideoEdge lists:
- network → the camera's LAN ip (and mac) - onvif.http_port → the ONVIF port (typically 8080) - rtsp.http_port → the RTSP port (typically 8554) - onvif.user_auth_enabledtrue once you've created an ONVIF user (if false, finish step 1 first)

Then add the ONVIF integration manually with that IP, the ONVIF port (8080), and the ONVIF user/password.

That's it — from there the camera behaves like any other ONVIF camera in Home Assistant (live view, snapshots, recording, use in automations), while Aegis keeps providing the device's motion/tamper sensors and the doorbell ring event.

If your Home Assistant can't reach the camera on its LAN IP, ONVIF discovery will fail — this is a network reachability issue, not an integration one. As a fallback you can also point the Generic Camera integration at the RTSP stream directly (port 8554).

Custom Services

| Service | Description | |---|---| | aegis_ajax.force_arm | Arm the system ignoring open sensors and active alarms. Supports entity target to arm a specific panel. | | aegis_ajax.force_arm_night | Arm night mode ignoring open sensors and active alarms. Supports entity target to arm a specific panel. | | aegis_ajax.disarm_night_mode | Exit night mode while leaving any independently armed (away) groups armed — the native Ajax "disarm night mode" operation. Unlike a panel-level disarm (which stands the whole space down), this only disarms the night-mode groups. Supports entity target; if omitted, applies to all panels. | | aegis_ajax.set_photo_on_demand_mode | Enable/disable Photo on Demand mode on a hub: user (hub users may request photos from the app) and/or scenario (scenarios/automations may trigger captures). Target a space via entity_id; leave a field unset to keep its current value. | | aegis_ajax.refresh_alarm_images | Import recent alarm-photo albums without triggering a capture. Target an alarm panel with entity_id, or omit it for all spaces. One history query + at most 10 media streams per space, once per five minutes; completed albums are skipped. | | aegis_ajax.press_panic_button | ⚠️ SOS / panic button. See dedicated section below before using. |

Both force_arm services accept an optional entity_id target (alarm control panel entity). If no target is specified, all panels across all configured accounts are armed.

Arm modes & voice assistants (Alexa via Home Assistant Cloud)

Ajax has a single partial-arm mode (the app calls it Night mode) plus full arm. The panel exposes Arm Away (full arm) and both Arm Home and Arm Night for that one partial mode — so "Arm Home" and "Arm Night" do the same thing and both settle the panel to armed_night. "Arm Home" is advertised mainly so the Nabu Casa / Alexa skill discovers the panel (it won't discover a panel that exposes Night without Home).

If you don't use Alexa / Home Assistant Cloud, the Arm Home button on the Lovelace alarm card is a redundant duplicate of Arm Night. Turn off the Show "Arm Home" button option (Configure) to hide it; Arm Away and Arm Night stay available.

Notes for Alexa:

  • The skill only exposes a panel that does not require a code to arm. If you enable the PIN option (use_pin_code), the panel won't be discovered by Alexa.
  • Alexa requests a PIN only on disarm, and only supports a 4-digit numeric code — Ajax PINs longer than 4 digits won't work for voice disarm.
  • When a PIN is configured, the panel reports code_format: number, which also makes the Home Assistant Lovelace alarm card render a numeric keypad.
  • A bare "Alexa, arm \" arms _Home_, not Away. This is Alexa's own default for an unqualified "arm" (it requests Armed Stay / Home), and since Arm Home maps to Ajax's partial mode the panel ends up partially armed. Home Assistant only forwards the mode Alexa asks for — the integration can't change Alexa's default. To arm fully: say "Alexa, arm \ in away mode", or create an Alexa Routine that maps your phrase (e.g. "arm the house") to the action set panel → Armed Away.

Exit and entry delays (arming / pending)

Ajax runs the Delay when leaving and Delay when entering you configure per detector inside the hub: the moment you arm, the hub reports armed, and the delay only decides when the delayed detectors start raising alarms. So by default the panel goes straight from disarmed to armed_away — the one-second arming you may see is the Ajax app's own arm confirmation, not the detector delay (#443).

The hub does report both ends of the delay on the always-on status channel the integration already keeps open, so with the Show exit / entry delays as panel states option (Configure, off by default) the panel adds two states driven by those signals, never by a timer of ours:

| Panel state | Starts | Ends | | --- | --- | --- | | arming | The space is seen arming (app, keypad, keyfob or Home Assistant) and at least one of its detectors has a "Delay when leaving" | The hub reports the exit delay complete; disarm; alarm. As a safety net the longest configured delay bounds it, so a missed hub frame can't leave the panel stuck | | pending | The hub reports an entry delay started (a delayed detector triggered while armed) | The expiry the hub announced with it; disarm; alarm (triggered always wins) |

What the states mean, plainly: during arming only the detectors with a delay are still quiet — detectors in Instant Alarm mode are already live, so the state describes the exit route, not the whole system. pending means someone is inside the entry delay: disarm before it runs out or the hub raises the alarm.

With the option on, the panel also carries three attributes: hub_state (the state as the hub reports it, without the overlay), exit_delay_seconds (the longest "Delay when leaving" among the space's detectors) and delay_ends_at (the expected end of the running delay, or null). Nothing is persisted: after a restart the panel shows the hub's plain state until the next arm. Night mode shows arming only for detectors whose delays are set to apply in night mode; per-group panels are not covered yet.

Panic button (SOS)

The integration exposes the same panic button that the official Ajax mobile app does. It calls the underlying SpaceService/pressPanicButton endpoint.

⚠️ READ THIS BEFORE USING IT — FALSE PANIC ALARMS HAVE LEGAL AND FINANCIAL CONSEQUENCES.
> Pressing the panic button forwards a Panic / Hold-up alarm to your monitoring station (CRA). On most professional monitoring contracts this means immediate police dispatch with no verification window — the operator is not allowed to call you back to confirm. False activations may result in fines, breach of your monitoring contract, and in some jurisdictions criminal liability.
> Use this service only for genuine emergencies. Do not wire it to noisy automations such as "trigger when my NVR detects motion" — for that case, route the trigger through a hardware path (e.g. an Ajax Transmitter Fibra connected to a relay controlled from HA), so the hub's normal alarm engine and verification rules apply.

What it does (controlled by hub configuration):

  • Always fires regardless of whether the system is armed or disarmed.
  • Triggers a panic_button_pressed event on the hub (mapped to event type panic on the integration's security event entity).
  • Forwards the panic to the monitoring station.
  • Optionally activates sirens depending on the hub setting panic_siren_on_panic_button.
Whether sirens sound is decided entirely by the hub — the panic request carries no siren field, so the integration cannot influence it. To see what your hub will do, enable the diagnostic binary sensors Siren on panic button and Siren on tamper on the hub device (disabled by default). They are read-only mirrors of the hub configuration; changing the behaviour is done in the Ajax app, and a change made there becomes visible after the integration reloads.

Service: aegis_ajax.press_panic_button

| Field | Required | Description | |---|---|---| | confirm | Yes (must be true) | Safety lock. The service refuses to run unless explicitly set to true to prevent accidental triggers from automations. | | entity_id | No | Alarm panel entity for the space whose panic button to press. If omitted, the panic is sent to every configured space. | | latitude | No | Optional caller latitude forwarded to Ajax. Use together with longitude. | | longitude | No | Optional caller longitude forwarded to Ajax. Use together with latitude. |

Example:

service: aegis_ajax.press_panic_button
target:
  entity_id: alarm_control_panel.aegis_home
data:
  confirm: true

Example Dashboard

An example Lovelace dashboard is included in docs/dashboard.yaml with sections for:

  • Alarm control panel + system status, with the exit / entry delay card (hub state, exit delay, countdown to the end of a running delay — needs the option described in Exit and entry delays)
  • Hub network (Ethernet, Wi-Fi, cellular, power)
  • Door & window sensors with batteries
  • Cameras & motion detectors with photo capture buttons
  • Temperature overview with 24h history
  • Tamper, connectivity, and problem diagnostics
  • Alarm, door, window, motion, and hub connectivity history
To use it, copy the YAML into a new dashboard view in Settings → Dashboards → Edit → Add View → YAML mode, and replace the example entity IDs with your own.

An example automations file is also available with 24 automation examples covering common security scenarios.

Entity Details

Hub sensors

  • CRA connection — binary sensor showing whether the space has at least one approved monitoring company (CRA)
  • CRA company — disabled-by-default diagnostic sensor showing the approved monitoring company name; returns multiple if more than one approved CRA is attached
  • Cellular connected — binary sensor for GSM/4G connection status
  • GSM type — sensor showing connection type (2G/3G/4G)
  • Hub network sensors — Ethernet/Wi-Fi connectivity, Wi-Fi SSID/signal, Ethernet/Wi-Fi IP addressing, cellular signal/network, and mains power status
  • Siren on panic button / Siren on tamper — disabled-by-default diagnostic binary sensors mirroring the hub's siren behaviour settings (read-only; configured in the Ajax app, refreshed on integration reload)
  • Delay when leaving — disabled-by-default diagnostic binary sensor on door, motion and combi detectors and MotionCams, mirroring whether the detector has an exit delay configured in the Ajax app (read-only). Note that the hub-side exit delay itself does not surface as an arming panel state; see #443
  • Lid opened — tamper detection for the hub enclosure
  • Battery — hub battery level
  • IMEI — hub cellular modem identifier
Note on hub network sensors: These entities are backed by the HTS connection. If HTS is unavailable or reconnecting, they may temporarily become unavailable instead of showing stale data.

Real-time event sensors

Door open/close and motion detection are transient events — they appear when the event occurs and clear automatically. The integration uses a persistent gRPC stream for instant delivery (typically < 1 second latency).
Note on motion detection: Ajax motion sensors only report motion events when the system is armed. This is a firmware-level behavior — when disarmed, motion detectors are inactive for battery conservation.

Security event entity

Each hub has a Security event entity that fires events from FCM push notifications: alarm, arm/disarm, tamper, panic, fire, flood, motion, glass break, CO, and more. Use these in automations to trigger actions on security events.

Each event includes enriched data attributes:

| Attribute | Description | Example | |-----------|-------------|---------| | raw_tag | Original protobuf event tag | intrusion_alarm, door_opened | | transition | Event transition state | triggered, restored | | device_name | Name of the device that triggered the event | Front Door, Hallway Cam | | device_id | Hex ID of the source device | A1B2C3D4 | | device_type | Type enum of the event's source. For arm/disarm this names what performed the action: a person (SPACE_MEMBER), a keyfob (SPACE_CONTROL), a keypad (KEYBOARD) or a scenario | DOOR_PROTECT, SPACE_MEMBER | | room_name | Room the device is assigned to (when available) | Kitchen, Entrance |

Use these in automation templates, e.g. {{ trigger.event.data.device_name }}.

Security sensors

  • Case tamper — physical manipulation of device enclosure
  • Device problem — device malfunction or communication issue
  • Anti-masking — detector obstruction attempt
  • Case drilling — enclosure drilling attempt
  • Interference — RF jamming detection
  • Glass break — glass break detection (GlassProtect, CombiProtect)
  • Vibration — vibration/shock detection (DoorProtect Plus)
  • Tilt — accelerometer tilt / device removed from wall (DoorProtect Plus family)
  • Steam — chamber-level steam vs. smoke discriminator (FireProtect 2 with smoke chamber). Lets automations distinguish a real fire from cooking/shower steam false positives
  • External contact alert — triggered state of an externally wired contact (e.g. reed switch on a window) connected to a DoorProtect's input terminals; toggles open/closed
  • External contact fault — circuit-fault indicator for the same external wiring (cable disconnect or short)
  • Wire input alert — triggered state of a third-party sensor wired into a MultiTransmitter or a Hub Hybrid wire input. Exposes an alarm_type attribute reflecting the category Ajax assigned to that input (intrusion, fire, glass_break, vibration, etc.). Available on wire_input_mt and wire_input device types

Keyfobs (experimental)

SpaceControl keyfobs are grouped under a single Keyfobs device (one per hub), with one Active binary sensor per keyfob, named after it (using the keyfob name set in the Ajax app).
Not every hub produces these sensors, and that is expected. Some hubs report the keyfob as an ordinary device instead, in which case it gets its own device page — with the usual bypass switch, which already shows whether it is deactivated — and no Active sensor. The Keyfobs device only appears on hubs that report their keyfobs solely over the status channel.
The active/inactive state is experimental and not yet confirmed. On every install that produces the sensor each keyfob reports as active, and a keyfob can only be deactivated server-side by an installer or monitoring company, so there has been no inactive example to validate against — the sensor may not yet reflect a genuinely deactivated keyfob. The Ajax app's forced deactivation on a keyfob is a different mechanism (it is the same temporary exclusion as the bypass switch) and does not produce that example.
> You can help finalize it: if you have a keyfob that your installer/CRA has deactivated, a Download diagnostics (Settings → Devices & Services → Aegis for Ajax → ⋮ → Download diagnostics) plus a debug log (custom_components.aegis_ajax: debug) attached to a GitHub issue would let us confirm the indicator and get it right. See Help Wanted.

Who armed or disarmed the system with a keyfob already appears in the logbook ("Disarmed (via …)") and on the hub's security event entity — that's independent of these sensors.

Automation Blueprints

Aegis includes 8 ready-to-use automation blueprints. Import them via URL in Settings → Automations → Blueprints → Import Blueprint:

| Blueprint | Description | Import URL | |-----------|-------------|------------| | Security Event Notification | Push notification with emoji-labeled event type, device name and room. Optional inputs for a tap-through dashboard URL and for translating/customising the per-event-type labels. Ignores stale events on reload. | Import | | Intrusion Alarm + Capture | Capture all cameras and send critical notification when intrusion alarm fires | Import | | Tamper Alert | Critical notification when device tampering is detected | Import | | Door Opened While Armed | Preventive alert when a door opens with the alarm armed, with optional warning script | Import | | Nobody Home Remind Arm | Notification when nobody is home and the alarm is disarmed, with optional TTS | Import | | Remind Arm with TTS | Push + voice announcement when someone is home and alarm is disarmed | Import | | Low Battery Weekly | Weekly summary of devices with battery below threshold | Import | | Connectivity Loss Escalation | Progressive alerts on hub connectivity loss (warning → critical → restored) | Import |

You can also manually copy the blueprint files from custom_components/aegis_ajax/blueprints/automation/ to your config/blueprints/automation/aegis_ajax/ directory.

Note: Blueprints are templates — existing automations created from them are not updated automatically. After updating the integration, delete and re-import the blueprint in Settings → Automations → Blueprints to get the latest version, then recreate the automation.

Troubleshooting

| Problem | Solution | |---|---| | "Invalid credentials" | Verify email/password work in your Ajax app | | "Cannot connect" | Check internet connection; Ajax servers may be down | | Hub shows offline | V

... (README truncated for length)

Chat with me