🇮🇹 Leggi questa pagina in italiano
Brings the Vimar Elvox video intercom (2 Fili Plus / IP / 2FV2) into Home Assistant: get the doorbell ring, open the door or gate, view the camera on demand, control voicemail and do not disturb, and drive your plant's actuators (F1/F2, stair lights, relays) as buttons.
How it actually works. This integration does not use RTSP. It implements a custom SIP stack in Python/asyncio that emulates the official Vimar VIEW app ("TOGA"): same
User-Agent, same identity headers (Mobile-IMEI,MyName) and the proprietaryPandaheader. It talks either to the Flexisip instance running on the Tab (local UDP :5060) or to the Vimar cloud over TLS (SRV_sips._tcp). Video arrives on demand from the SIP call (H.264 RTP, decoded to MJPEG through ffmpeg), not from an always-on RTSP stream.
Developed on the Elvox Tab 7S 2F+ WiFi (art. 40507). Other Vimar 2F / 2FV2 / IP Tabs should work too — the configuration comes from the pairing QR code — and the table below is what has actually been reported so far.
| Model | Art. | Plant | Firmware | Connection | Status |
|---|---|---|---|---|---|
| Elvox Tab 7S 2F+ WiFi | 40507 | 2F | — | local UDP | Development platform: ring, call, answer/hang up, door open, on-demand video, actuators |
| Elvox Tab 5S UP 2 Wire WiFi | 40515 | 2FV2 | 2.1.0203 | cloud TLS | Working, reported by @CPietro — see the notes below |
| Elvox Tab 5S UP 2 Wire WiFi | 40515 | — | — | cloud TLS | Cloud registration working after the 1.0.1 fix, reported by @gtarraran992 (#1) |
What differs between plants. Both Tab 5S reports, plus the development plant, point at the same practical conclusion: what matters is the address you send to, and how much the Tab tells you back.
- Send state commands to the SGA. On the development plant (40507 / 2F),
VOICEMAIL;ON|OFFandDND;ON|OFFwork when they are sent to the SGA —55001there, taken from the phonebook'sSYSTEM.MAGIC_APT_INTERCOM. Sent anywhere else (the Tab's own address, the apartment group, the old60001default) they return a bare 200 OK and do nothing, or a 404. If your switches appear dead, the SGA/PICG options are the first thing to check — see the options table below. GET_INIT_STATUSreplies, but not with the same amount of detail. On the 40507 the reply is short:rubrica_ver,vm_ver,vm_level,dnd,voicemail. On the 40515 / 2FV2 plant it is the full payload —dnd,voicemail,rubrica_ver,vm_ver,vm_level,vm_timeout,vm_timeout_values,apt_names,GID,media_encand atoken. Which is why the integration parses what it finds and ignores what it doesn't, instead of assuming a fixed set.- Media encryption is a per-plant value, not a global default: the 40515 reports
media_enc: "srtp", while the development plant refused SRTP outright and runs plain RTP. - Still open on the 40515: voicemail switches on but not off, under investigation by the reporter.
Got it running on a different model, or on the same one with different results? Please open a hardware compatibility report — reports where everything just worked are as useful as the ones where something broke.
- Home Assistant 2024.1 or later, Python 3.11+.
- ffmpeg on the Home Assistant host (declared in the manifest) for the camera.
- The plant's pairing QR code (from the VIEW app) or the SIP parameters entered by hand (id, password, domain, cloud proxy).
- Python requirements: only
pycryptodomeandrequests— no external SIP library, the stack is custom.
- HACS → Integrations → ⋮ menu → Custom repositories → add this repo with category Integration.
- Install Vimar Intercom.
- Restart Home Assistant.
Copy custom_components/vimar_intercom/ into your Home Assistant config/custom_components/ folder
and restart.
If you reinstall or update by hand:
__init__.pyandsip_client.pycarry local logging patches (not present upstream — see the Logging section below). If you overwrite those files with a copy from somewhere else, reapply the patches: outside HACS nothing preserves them for you.
Settings → Devices & services → Add integration → Vimar Intercom.
- QR (recommended): paste the text of the Vimar pairing QR code. The integration decodes it
(
qr_decoder.py: Base64(AESkey|AES-CBC|IV) →KEY=VALUEpairs) and fills in id, password, domain, cloud/local proxy, GID, MAC and plant type. - Manual: enter
sip_user,sip_password,sip_domainandcloud_proxyyourself.
Settings → Vimar Intercom → Configure:
| Option | Description |
|---|---|
Intercom IP (local_proxy) |
IP address of the Flexisip instance on the Tab |
Use local SIP UDP (use_local_udp) |
ON = local UDP; OFF = cloud TLS |
Local UDP port (local_udp_port) |
default 5060 |
Actuators (JSON) (actuators) |
JSON list of {name, msg, target, icon}; creates dynamic buttons. Empty = no buttons |
SGA (sga_target) |
Recipient of VOICEMAIL;/DND; and of the "AUTO" door open. Empty = default 55001 |
PICG (picg_target) |
Recipient of GET_INIT_STATUS. On every plant verified so far it matches the SGA. Empty = default 55001 |
The actuator list and the SGA/PICG values come from your plant's phonebook (rubrica.db): in the
options menu pick "Import actuators from rubrica.db", upload the file (you can get it through the
VIEW app or with root access, see docs/RUBRICA.md) and confirm — actuators, SGA and PICG are then
set automatically. You can also enter the values by hand in the "Settings" step, which is handy if you
already know your plant's SGA or want to tweak the imported actuator list.
| Entity | Platform | Description |
|---|---|---|
| Intercom | camera |
On-demand video: opening the stream makes the hub place the SIP call, and the H.264 RTP video is decoded to MJPEG through ffmpeg (no RTSP) |
| Doorbell | event |
event entity (device class DOORBELL), event type ring, fired on ring (incoming INVITE) |
| Lock | lock |
Opens the door (OPEN_2F → outdoor unit); auto-relocks after 5 s (there is no physical feedback) |
| Call | button |
SIP call to the default outdoor unit |
| Call Video (outdoor) / Call Home (indoor) | button |
Call to 55001 / 55002 |
| Answer / Hang up | button |
Answer (200 OK) / end the call (BYE) |
| Open Door | button |
OPEN_2F to the outdoor unit |
| Dynamic actuators | button |
One per entry in options["actuators"] (F1/F2, stair lights, relays…); sends MSG with Panda: command |
| Voicemail | switch |
VOICEMAIL;ON/OFF (Panda: blue) to the SGA; state read from the Tab's announcements |
| Do Not Disturb | switch |
DND;ON/OFF (Panda: blue) to the SGA; real state |
| Intercom SIP | binary_sensor |
SIP registration active (connectivity) |
| Intercom In Call | binary_sensor |
A call is up |
| Intercom Ringing | binary_sensor |
ON while an outdoor unit is calling (attribute: caller) |
| Intercom Outgoing Call | binary_sensor |
ON while Home Assistant is calling |
| Intercom State | sensor (enum) |
offline / idle / ringing / in_call / calling (plus network attributes) |
| Intercom Last Caller | sensor |
Outdoor unit or monitor of the last ring |
| Intercom Last Ring | sensor (timestamp) |
Time of the last ring |
| Intercom Rings | sensor (counter) |
Rings since startup |
| Intercom Calls | sensor (counter) |
Connected calls |
| Intercom Last Call Duration | sensor (s) |
Duration of the last call |
| Intercom Last Door Open | sensor (timestamp) |
Last door opening (attributes: unit, outcome, counter) |
| Intercom Last Command | sensor |
Outcome of the last send_command |
| Intercom Last Received Message | sensor |
Last SIP MESSAGE from the intercom |
| Service | Description | Fields |
|---|---|---|
vimar_intercom.send_command |
Arbitrary SIP MESSAGE (for testing) | body, target, header_name, header_value |
vimar_intercom.call |
SIP call to an outdoor unit or monitor | target |
vimar_intercom.answer |
Answers the incoming call | — |
vimar_intercom.hangup |
Ends the active call | — |
vimar_intercom.open_door |
Door open command (OPEN_2F) |
target, command |
vimar_intercom.fetch_local |
HTTP Digest GET against the Tab's local interface (home mode) | path, save_as, host, scheme |
Example (Developer tools → Actions):
action: vimar_intercom.send_command
data:
body: OPEN_2F
target: "55001"
header_name: Panda
header_value: commandThe doorbell is exposed as an event entity (event.<...>_doorbell, event type ring), not as a
bus event. In automations, use a state trigger on the event entity (or on the ringing binary sensor).
On top of that, from the MESSAGEs the Tab sends, the integration fires these events on the Home
Assistant bus: vimar_intercom_missed_call, vimar_intercom_videomessage,
vimar_intercom_fuoriporta, vimar_intercom_call_info, vimar_intercom_phonebook_changed.
They are read-only — nothing is sent back. Example trigger:
automation:
- alias: "Intercom - Missed call"
trigger:
- platform: event
event_type: vimar_intercom_missed_call
action:
- service: notify.mobile_app_phone
data: { message: "Missed call at the intercom" }packages/vimar_intercom.yaml (copy it into config/packages/) contains a
"ring → notification" automation driven by the state change of the event entity, plus a safety
hang-up that closes a call left open for two minutes:
automation:
- alias: "Intercom - Ring → notification"
trigger:
- platform: state
entity_id: event.vimar_intercom_doorbell
action:
- action: notify.mobile_app_YOUR_PHONE
data:
title: "🔔 Someone at the door"
message: "Ring at {{ now().strftime('%H:%M:%S') }}."
data:
image: "/api/camera_proxy/camera.vimar_intercom_intercom"⚠ Don't add camera.snapshot to it. It appears to work — the service call succeeds — but it
writes no file and logs nothing, because the camera entity cannot produce an image on current code
(#8). camera.record doesn't work either: it needs the stream integration, which
an MJPEG camera doesn't provide. And don't work around it with a camera: platform: ffmpeg pointed
at /api/vimar_intercom/av: that hangs Home Assistant until the ffmpeg probe times out. The package
file carries the same warnings, with the details.
docs/lovelace_example.yaml has a basic Lovelace card with the answer / open door / hang up buttons.
Note that the video pane in it stays empty for the same reason as above.
- Cloud-only plants: the Tab's local HTTP interface (:80) may accept the TCP connection and then stay silent, so there is no local phonebook to read over the LAN. Camera, actuators, door opening and the state commands still work over SIP.
- Voicemail / DND: these are commanded through the SGA (
SYSTEM.MAGIC_APT_INTERCOMin the phonebook,55001on the plant used for development). Sent to any other address they are silently ignored, so getting the SGA right is what makes them work — set it in the options or let therubrica.dbimport fill it in. - Cloud phonebook: needs a
token. Plants that answerGET_INIT_STATUSwith the long form hand it over directly, and the phonebook can then be downloaded with a single authenticated request — seedocs/RUBRICA.md§0, verified on a 40515. Plants that answer with the short form (including the development one) don't carry a token, and there the manual extraction is still the way. Fetching it automatically isn't implemented yet (#5). - By-me actuators (e.g. stair lights on By-me home automation): these may not respond over SIP even when they are listed in the phonebook.
- Lock: no physical state feedback (optimistic auto-relock after 5 s).
- Phonebook: on cloud-only plants it has to be extracted once (see
docs/RUBRICA.md); the automatic import over the cloud depends on a token provisioned by the account.
The component keeps an internal circular buffer (_debug_log, in __init__.py) for its own
diagnostics, and raises its logger to DEBUG to fill it. By default that would propagate every
DEBUG line to the Home Assistant log too, overriding the level set in logger: in
configuration.yaml (Python loggers propagate to the root).
The patch: the custom_components.vimar_intercom logger stays at DEBUG for the internal buffer, but
with propagate = False; a dedicated handler forwards only WARNING and above to the HA log. Result:
internal diagnostics intact, HA log clean.
"Stale response 407" on the SIP keepalive: the periodic OPTIONS (_send_options_ping in
sip_client.py) did not register its own Call-ID among the expected responses, so the proxy's reply
(typically a 407) was logged as WARNING "Stale response ..." even though it is the normal outcome
of the keepalive. _dispatch_message now recognises Call-IDs prefixed with ping- and logs them at
DEBUG instead. With this fix and the one above, no logger: filter in configuration.yaml is
needed any more to silence these messages.
Known limitation: the trade-off cuts both ways. Because the component keeps its own logger at
DEBUG and forwards only WARNING and above, setting
logger: logs: custom_components.vimar_intercom: debug in configuration.yaml will not put this
component's DEBUG lines in the Home Assistant log — read them from
/api/vimar_intercom/debug instead. Making the forwarded level configurable is on the list.
If you update __init__.py or sip_client.py from an external source (not HACS, not versioned for
this component), check that both patches are still in place — see the note under
Installation → Manual.
- SIP credentials (password /
ha1) are stored encrypted in the Home Assistant config entry, never in plain text in the repo. - Internal HTTP endpoints:
/videoand/avare LAN-only (_is_local_request); the/audio_wsWebSocket requires Home Assistant authentication. The QR payload is never logged at INFO level. - No mandatory cloud dependency when running in local UDP mode.
See CONTRIBUTING.md. The short version: never guess SIP commands or tokens (a wrong
actuator token can physically open a door), keep credentials out of the repo and out of your logs, run
pytest before opening a PR, and say which hardware you tested on.
This project is not affiliated with or endorsed by Vimar S.p.A.. "Vimar", "Elvox" and "VIEW" are trademarks of their respective owners. You supply your own credentials for your own plant.
MIT — © Noise Heroes (upstream project) and the fork's contributors.