Important
This is an unofficial, community-developed project. It is not affiliated with, endorsed by, sponsored by, or supported by Cogelec. "Intratone" is a registered trademark of Cogelec, used here solely to describe which intercom system this software is compatible with. For support with your Intratone hardware or account, contact Cogelec or your building manager — not this project.
Unofficial Home Assistant integration for the Intratone intercom system (manufactured by Cogelec, widely deployed in French apartment buildings). Exposes your apartment intercom as native HA entities and as a HomeKit accessory so calls ring directly on your iPhone, with one-way audio + video and a door-unlock button. It also exposes Intratone's Clé mobile / mobipass remote-open accesses as lock entities, so you can open your building's gate on demand without anyone ringing — including hands-free via a voice assistant.
After pairing, the integration creates these entities under one device:
| Entity | What you can do |
|---|---|
event.intratone_<ID>_doorbell |
Fires every time a visitor rings the intercom. Payload includes door_name, door_number (NBPORTE), caller, call_id. Usable as automation trigger. |
camera.intratone_<ID>_intercom |
Placeholder image when idle. Live audio + video stream during a call. Only created when the Enable video (VP8) option is on (asked at pairing, changeable in the integration options). |
lock.intratone_<ID>_door |
Tap Unlock → opens the door (sends opendoor:<code> SIP MESSAGE, same backend as the official Intratone app). Only works during an active call (see Caveats). |
lock.intratone_<ID>_<access> |
One per data-openable access — Intratone's Clé mobile / mobipass (data/4G) and ble accesses. Tap Unlock to open that gate/door on demand, no visitor needed (POST /api/access/open/clemobil). Created at setup from GET /api/access (one per residence × door). Voice-assistant & HomeKit friendly for hands-free opening. Legacy 2G clemobil accesses are not exposed — the app opens those by placing a real phone call, which HA can't do. Absent if your account has no data-openable accesses, or until you transfer the Clé mobile to HA (single-owner since mid-2026). |
switch.intratone_<ID>_backlight |
Toggle ON during an active call to ask the intercom hardware for its backlight / illuminator mode (low-light conditions). One-shot — the server resets it on call end. Some hardware models don't support it; in that case the signal is silently ignored. Only created when the Enable video (VP8) option is on (it illuminates the visitor for the camera). |
binary_sensor.intratone_<ID>_push_channel_connected |
Diagnostic — on while the FCM push channel is up. If it goes off, you won't be notified of rings. |
button.intratone_<ID>_test_go2rtc_relay |
Diagnostic — publishes a short synthetic stream to go2rtc and reads it back, validating the exact path a real call uses. Raises/clears a repair issue with the result. Only created when the Enable video (VP8) option is on. Refuses to run during an active call. |
The camera plays in the HA frontend, the HA Companion apps (iOS & Android) and — via HA's HomeKit Bridge — on the iPhone Home.app camera tile:
- Doorbell push notification < 2 s after a visitor rings (FCM) — native on HomeKit, one blueprint import on the Companion apps
- One-way audio (visitor → phone): G.711 µ-law transcoded to Opus on the fly
- Video (VP8 → H.264 baseline transcoding) — opt-in via the integration options (⚙️). Enable only if your Intratone subscription includes the visiophone (intercom with actual camera).
- Lock tile to open the door
flowchart TD
A[Visitor presses intercom] -->|FCM push ~1 s| B[HA doorbell event\nphone push notification]
B -->|user taps tile| C[HA: SIP INVITE → 200 OK + SDP]
C --> D[Intratone server\nRTP µ-law audio + VP8 video]
D -->|audio_bridge.py\nSTUN-respond · depacket RTP| E[ffmpeg\nµ-law → Opus 16k mono\nVP8 → H.264 baseline]
E -->|RTSP push| F[go2rtc]
F -->|HomeKit Bridge| G[SRTP → iPhone Home.app]
F -->|HA go2rtc integration| H[WebRTC / HLS →\nHA frontend & Companion apps]
The FCM listener stays connected for the lifetime of the integration and reconnects with exponential backoff on failure. The SIP dialog opens only when the user actually taps the camera tile or the lock — mirrors the Cogelec app, which doesn't dial until you tap Pick Up. See INTRATONE_API.md for the full REST + SIP reverse-engineering notes.
The integration also reacts to two additional FCM push types Cogelec emits:
callCancel— the visitor walked away before any device picked up. We abort the in-flight SIP call (if any) and clear pending state so a subsequent tap on the iPhone tile doesn't open a stale stream. Apple's iOS doorbell notification itself can't be dismissed remotely — it will fade out on its own.unregister— the Intratone server invalidated our credentials (account reset, building operator unbound the device, …). HA's reauth flow is triggered; if the silent JWT refresh succeeds (it usually does as long as the phone/device_id are still on file), pairing continues seamlessly. Otherwise you'll see a Repair card asking for a new invitation code.
- Intercom door unlock requires an active call.
lock.intratone_<ID>_doorsends a SIP MESSAGE inside the active call dialog, so it only works in the ~25-second window starting when the visitor presses the button and ending when the intercom hangs up. To open a gate/door without anyone ringing, use the remote-open access locks (Clé mobile / mobipass,lock.intratone_<ID>_<access>) instead — those work any time. - Audio quality: bounded by G.711 µ-law @ 8 kHz (Intratone's wire codec). Some accounts receive only comfort-noise µ-law from the server during a call rather than the real microphone stream — same behaviour observed on the official Intratone iOS app for those accounts, only the GSM fallback carries real audio. Not a bug in this integration; it's a server / account-side condition.
- Video quality: bitrate is set by the intercom hardware (~5-10 kbps observed, ~2–5 fps). Equivalent quality to the official app — there's no client-side knob to request higher quality.
- Video startup delay: The Intratone server schedules VP8 keyframes infrequently. After tapping the HomeKit tile, audio starts right away over a “Call in progress — waiting for video…” placeholder picture, and the live video replaces it once the first I-frame arrives (typically 5–15 s). If the server sends no video at all (or it stalls mid-call), the placeholder stays up and audio and door opening keep working. The picture is fitted into a 640×480 frame, with black bars if the camera's aspect ratio differs. If no video appears after ~20 s, see Troubleshooting.
- Live view only during a call: the camera streams from the moment a visitor rings until ~60 s after the call ends. Tapping the tile outside that window shows the placeholder (HomeKit) or a "no stream" error (HA frontend) — there's no on-demand view, the intercom only streams during calls.
- France only: tested against
sip.intratone.info. Other Cogelec deployments untested. - Both devices ring in parallel. The official Intratone app on your phone continues to receive rings alongside HA. Whichever device opens first triggers the relay; the other still rings.
- The Clé mobile remote-open key is single-owner (since ~mid-2026). Only one device per phone number can hold it, so the on-demand access locks live on either your phone or HA — not both. Ringing and in-call door unlock are unaffected. See Transferring the Clé mobile to Home Assistant.
- Talkback (iPhone microphone → visitor). The "Talk" button shows in HomeKit but does nothing. Blocked on upstream: Home Assistant's HomeKit Bridge and HAP-python don't expose camera microphone input at all today. We'll add it when one of them does.
- Call history, multiple intercoms in one config entry, HomeKit Secure Video.
- Home Assistant Core 2026.5.x (the only version actually tested — older versions may work but YMMV).
ffmpegbinary available to HA, built withlibx264andlibopus. Pre-installed on HA OS and HA Container.- HA's built-in HomeKit Bridge integration configured (used to expose entities to iPhone Home.app).
- A reachable go2rtc instance the integration can push its transcoded stream to. There are three common setups — pick whichever you already have, then point the integration at it (see go2rtc setup).
- Access to the official Intratone account that's already paired to your apartment, on a phone where the Intratone app is logged in. You'll use that app to generate a one-time invite code for the HA pairing (see below).
The integration pushes its transcoded RTSP stream (audio + optional VP8 video) to a go2rtc server and HA's HomeKit Bridge pulls from the same URL. You need go2rtc running, with a stream slot named intratone pre-declared (go2rtc rejects publishes on undeclared stream names).
There's no standalone "go2rtc" add-on in HA's default Add-on Store. Use one of:
The smallest dependency. Add a custom add-on repository:
- Settings → Add-ons → Add-on Store → ⋮ → Repositories, add
https://github.com/AlexxIT/hassio-addons - Install the go2rtc add-on
- Configure it with the stream slot:
streams: intratone: ""
- Start the add-on. It listens on
rtsp://127.0.0.1:8554(no env var needed — this is the integration's default).
Frigate bundles go2rtc on 127.0.0.1:8554. Add to your frigate.yaml:
go2rtc:
streams:
intratone: ""Run go2rtc binary or container yourself with:
rtsp:
listen: "127.0.0.1:8554"
streams:
intratone: ""If your go2rtc isn't on 127.0.0.1:8554, change the go2rtc RTSP relay URL in the integration options (⚙️ on the Intratone integration card).
HA Core ships a bundled go2rtc binary that auto-starts in Docker / HA OS environments on port 18554. Its config is HA-managed and doesn't accept user streams: declarations, so it can't accept our RTSP publish — the standalone instance above stays required. The embedded go2rtc has a different role: it's the pull/viewer side of native HA viewing — it pulls the stream from your standalone instance and serves WebRTC to the HA frontend.
Besides HomeKit, the camera plays natively in the HA frontend: Lovelace cards, the more-info dialog, and the HA Companion apps (iOS & Android) — via WebRTC (sub-second) with an HLS fallback (~5 s latency). Same semantics as HomeKit: tapping the camera answers the call (marks it picked up at Intratone and opens the SIP audio/video stream), and outside a ring the tile shows the placeholder image.
How it works: HA core's own go2rtc integration acts as the WebRTC provider — it pulls the RTSP stream this integration publishes to your standalone go2rtc, and serves it to the frontend. Two supported layouts:
| Layout | Config needed | go2rtc instances |
|---|---|---|
| HA OS / Container (default) | none — HA's embedded go2rtc auto-starts and pulls from your standalone instance | 2 |
| Single instance | point HA at your existing standalone go2rtc in configuration.yaml (below) |
1 |
# configuration.yaml — single-instance layout, and REQUIRED for WebRTC on HA Core (venv/pip)
go2rtc:
url: "http://127.0.0.1:1984" # HTTP API of the same go2rtc the integration publishes toThe AlexxIT add-on and Frigate both expose the go2rtc HTTP API on port 1984. Without a reachable go2rtc for HA (e.g. HA Core without the go2rtc: block), the camera still plays over HLS.
Notes:
- Tapping the tile at idle (nobody ringing) shows an immediate "no stream" error — there's no video to show outside a call, by design.
- Do not use
camera_view: livecards or stream preload with this camera. A wall panel in live mode would auto-answer every ring the moment the visitor presses the button. Keep the defaultcamera_view: auto— the tile shows the placeholder image and only starts the stream when tapped. - Remote access through Nabu Casa may fall back to HLS depending on WebRTC connectivity.
- The 5–15 s placeholder picture before live video (VP8 keyframe scheduling, see Caveats) applies to every client — HomeKit, Companion, Lovelace alike.
HomeKit pushes doorbell notifications on its own; on the Companion apps it's one automation. Import the ready-made blueprint:
Pick your doorbell event entity and your phone, then optionally:
- Camera — tapping the notification opens its live view (which answers the call, like picking up).
- Door lock — adds an "Open door" action button to the notification (on iOS, long-press to reveal it): unlock straight from the notification, without opening the camera. Works with the intercom door lock (during the call window) or a Clé mobile access lock (any time).
- Critical — rings through silent mode (the ring window is only ~25 s).
The notification itself never answers the call; only opening the camera view answers it (and Open door on the intercom door lock dials just long enough to send the unlock — a Clé mobile lock opens without any call).
Prefer an explicit automation? The equivalent YAML:
automation:
- alias: "Doorbell for Intratone — notification"
triggers:
- trigger: state
entity_id: event.intratone_XXXX_doorbell
not_from: ["unknown", "unavailable"]
not_to: ["unknown", "unavailable"]
actions:
- action: notify.mobile_app_your_phone
data:
title: "Intratone"
message: >-
{% set door = state_attr(trigger.entity_id, 'door_name') %}
{{ 'Someone is ringing at ' ~ door if door else 'Someone is ringing at the door' }}
data:
# Tap → camera live view in Companion = answer the call
clickAction: entityId:camera.intratone_XXXX_intercom # Android
url: entityId:camera.intratone_XXXX_intercom # iOSClick the button below to open HACS directly on this integration:
Or manually:
- HACS → ⋮ menu → Custom repositories
- Add
https://github.com/GuiHash/ha-intratonewith category Integration - Search Doorbell for Intratone (unofficial) → Install
- Restart Home Assistant
The integration code lives at custom_components/intratone/ inside the repo, so don't clone the repo directly into your custom_components folder — clone it elsewhere and copy (or symlink) the inner directory:
git clone https://github.com/GuiHash/ha-intratone.git /tmp/ha-intratone
cp -r /tmp/ha-intratone/custom_components/intratone <your HA config>/custom_components/intratone
# Or download a release archive and extract to custom_components/intratone/The integration identifies itself with the official app's credentials: an Intratone API app id + token and the app's Firebase project (used to receive doorbell pushes). They are not part of this repository.
- If they are missing, the first setup step asks for them (and an existing entry asks for them through a re-authentication).
- To change them: Settings → Devices & Services → Doorbell for Intratone (unofficial) → Configure → App credentials (advanced). Changing a Firebase value needs a re-pair for doorbell pushes to keep working.
In Home Assistant: Settings → Devices & Services → Add Integration → Doorbell for Intratone (unofficial). Pick one of two paths.
Which path should I pick? If you want ring-free remote opening (the Clé mobile / CléMobil, exposed as
lock.intratone_<ID>_<access>), use Path B (invitation code). SMS pairing only ever gets you the doorbell and opening a door during a call — an SMS-registered device is never provisioned for the Clé mobile (see issue #61).
You'll be asked for your phone number (the one tied to your Intratone account) and the country code (default 33). Intratone texts you a 4-digit code; type it on the next screen. Same flow as the official mobile app's first-time login. Mirrors POST /api/auth/register → POST /api/auth/validate → POST /api/auth/device.
⚠️ SMS pairing cannot enable the remote-open Clé mobile. If you want it, use Path B instead (you can remove and re-add the integration to switch).
Generate an invite code from the official Intratone app → Mes infos → Ajouter un appareil (format 448789-1206) and paste it. This is the method that provisions the device for the Clé mobile / remote opening; it's also the path for installer-managed accounts without a phone.
The integration registers an FCM push subscription and obtains a long-lived device JWT (rotated every 12 h). Both your existing phone and HA receive ring notifications in parallel; both can open the door.
If HA detects expired credentials it triggers a re-authentication flow that silently refreshes the JWT from the stored phone + device_id — you should not need to re-pair in normal use. The form only appears if the backend has unbound your device (rare, e.g. account reset on the Intratone side).
Since ~mid-2026 Intratone lets only one device per phone number hold the remote-open key (Clé mobile / mobipass). If the key currently lives on your phone (the usual case), the lock.intratone_<ID>_<access> entities won't appear — GET /api/access returns nothing until the key is moved to HA. See issue #61.
Requires invitation-code pairing (Path B). Only a device registered with an invitation code is provisioned for the Clé mobile; if you paired via SMS, the reconfigure step below will tell you to remove and re-add the integration with an invitation code first (issue #61).
To move it onto Home Assistant:
- Settings → Devices & Services → Doorbell for Intratone (unofficial) → ⋮ → Reconfigure.
- Read the warning and confirm. Intratone texts a one-time transfer code to your account's phone number.
- Enter the code. On success the access locks appear within a few seconds.
This revokes on-demand remote opening in the official Intratone app on your phone (only one device can hold it). Doorbell ringing and opening a door during a call (lock.intratone_<ID>_door) are unaffected on both devices — this only concerns the ring-free Clé mobile opening. To move the key back, redo the transfer from the official app.
Add to your configuration.yaml:
homekit:
- name: HA Bridge
filter:
include_entities:
- camera.intratone_<ID>_intercom
- event.intratone_<ID>_doorbell
- lock.intratone_<ID>_door
- lock.intratone_<ID>_<access> # remote-open accesses (Clé mobile / mobipass), one per gate/door
- switch.intratone_<ID>_backlight # optional, only on hardware that supports it
entity_config:
camera.intratone_<ID>_intercom:
support_audio: true
linked_doorbell_sensor: event.intratone_<ID>_doorbell
# HomeKit ffmpeg encodes Opus at 24 kbps with frame_duration 60 ms
# → 180-byte frames. Default RTP packet size 188 (= 176 max payload)
# rejects them, killing the audio output. Bump to fit + margin.
audio_packet_size: 384Replace <ID> by the suffix HA uses in your entity IDs — it derives from the config entry title, which is the phone number you paired with (e.g. Intratone (+33612345678) → event.intratone_33612345678_doorbell); it's visible in any of the entity names. Restart HA so the Bridge picks up the new config.
To opt into VP8 video, open the integration options (⚙️ on the Intratone card) and enable Enable video (VP8).
The integration intentionally only ships the entities listed above. Common observability needs (last ring time, count today, "currently ringing" flag, per-door routing) compose cleanly out of HA's built-in template helpers — pick what you actually need.
Last ring timestamp. No helper needed — event.intratone_<ID>_doorbell already exposes the timestamp of its last fire as its native state. Reference it directly in cards or templates:
{{ states('event.intratone_<ID>_doorbell') }}
"Currently ringing" pulse. Useful for HA conditions (state: on) or mobile notifications that want a stateful trigger. Add to configuration.yaml:
template:
- trigger:
- platform: state
entity_id: event.intratone_<ID>_doorbell
binary_sensor:
- name: Intratone ringing
state: "on"
auto_off: "00:00:08" # match your intercom's ~8 s ring windowRings today (counter, resets at midnight). No YAML — create a History Statistics helper from the UI: Settings → Devices & services → Helpers → "+ Create Helper" → History statistics. Pick event.intratone_<ID>_doorbell as entity, type Count from start of day, state-changes.
Which door rang last (multi-door installs). NBPORTE is in the event payload as door_number. A trigger-based template sensor captures it:
template:
- trigger:
- platform: state
entity_id: event.intratone_<ID>_doorbell
sensor:
- name: Intratone last door
state: "{{ trigger.to_state.attributes.door_number }}"You can also branch automations directly on {{ trigger.event.data.door_number }} inside a platform: event trigger on event_type: state_changed for the entity, if you don't need the value to persist as its own sensor.
Add to configuration.yaml and restart HA:
logger:
logs:
custom_components.intratone: debugAt debug level the integration logs every SIP message sent and received (TX/RX, credentials, SIP identities and door code redacted), every FCM push received, the exact ffmpeg command lines and the per-call media markers (FFMPEG_PUSH_READY, AUDIO_RX_SUMMARY…) referenced below. Use these to diagnose ring delivery, audio, or video problems before opening an issue.
The integration registers an intratone.simulate_ring service (Developer Tools → Actions) that injects a fake FCM ring payload into the coordinator, as if a visitor had pressed the button. By default it only fires the doorbell event (the fake call_id means the in-call door unlock would be rejected by the server). If you also set sip_server_ip, the full call pipeline fires — SIP INVITE → RTP → ffmpeg → go2rtc → HomeKit — which is designed for end-to-end testing against dev/mock_asterisk.py, a tiny mock SIP server that answers the INVITE and streams a 440 Hz sine over G.711 µ-law.
Main fields:
door_name— human label carried in the event payload (defaultPORTE TEST)call_id— override the generated fake call id, for repeatable testsentry_id— target a specific config entry (defaults to all loaded entries)sip_server_ip— when set, triggers the real SIP flow against this IP (use127.0.0.1with the mock)sip_target_user,sip_user,sip_pass— SIP Request-URI user and Digest credentials for the mock flow
The default SIP credentials in the schema (
cogelecTest/CogeleC) are test values matchingdev/mock_asterisk.py— they are not real Intratone credentials.
Ring doesn't reach iPhone — verify event.intratone_<ID>_doorbell fires in HA (Developer Tools → Events) when someone rings. Check the FCM listener heartbeat in logs (firebase_messaging lines every ~20 s). Make sure your HomeKit Bridge accessory is paired and the linked_doorbell_sensor is set. If rings silently stopped after working fine, Google may have rotated HA's FCM push token — Intratone keeps sending pushes to the old one. The integration detects this and raises a fixable Repair (Settings → System → Repairs) that asks for a fresh invitation code to re-register the new token.
Tile opens but loading spinner forever — go2rtc must be running with the intratone slot declared. With debug logs enabled, look for FFMPEG_PUSH_READY: ... consumable (the marker confirming our ffmpeg pushed successfully); if absent, look for ffmpeg errors.
Video enabled but the tile stays on “Call in progress — waiting for video…” — the Intratone server hasn't sent a VP8 keyframe yet (or sent no video at all). In the STATS debug lines, vp8= counts real video packets forwarded to ffmpeg and placeholder= the placeholder frames; video_stun=0 vp8=0 for the whole call means no video packet reached HA at all. VIDEO_PLACEHOLDER: real VP8 keyframe — switching ffmpeg to the live stream marks the moment live video takes over.
Tile opens but no audio — look for Packet size 180 too large in HA's homekit ffmpeg logs. If present, the audio_packet_size: 384 setting is missing from the HomeKit entity_config above. During a call, the AUDIO_RX_SUMMARY debug log line shows how many audio packets the integration received and whether their content was real audio or comfort-noise.
Door doesn't open — the unlock action only works during the active call dialog (see Caveats). Open the camera tile first to trigger the call, then tap the lock within ~25 s.
JWT expired — auto-refreshed every 12 h. If HA detects an irrecoverable auth failure it triggers a re-authentication flow which silently mints a fresh JWT from the stored phone + device_id; the form only appears if the backend rejects that, in which case you'll need a new invite code from the official app.
The integration stores in the HA config entry:
- The JWT issued by Intratone (rotated every 12 h, or silently re-minted on auth failure).
- The FCM credentials handed back by Google's MCS (used to keep the push channel open across restarts).
- The device id generated locally during pairing (a random 16-character hex string, mimicking an Android
ANDROID_ID). - The numeric account id and phone number associated with the Intratone account that was paired.
- The app credentials you entered, if any (in the entry options — see App credentials).
No call history, audio, or video is persisted to disk by the integration — RTP frames are transcoded and forwarded to go2rtc/HomeKit in real time, then dropped.
Settings → Devices & Services → Doorbell for Intratone (unofficial) → ⋮ → Download diagnostics produces a JSON dump for issue reports; phone number, JWT, FCM token + credentials, app credentials, device id, numeric id and the caller SIP login are redacted automatically before download.
Reverse-engineered from the official Cogelec / Intratone Android app (APK 4.6.3, plus the mobipass transfer flow from 4.6.4) and iOS app (IPA 4.4.10). HTTP, SIP and RTP behaviour mirrors what the official app does so the integration cohabits cleanly alongside it on the same account. See INTRATONE_API.md for the full API notes, including the Clé mobile / mobipass remote-open and transfer endpoints.
"Intratone" and "Cogelec" are trademarks of Cogelec. This project is independent and is not affiliated with, endorsed by, or sponsored by Cogelec. All product names are used for identification purposes only.
MIT.