Skip to content

Repository files navigation

Home Assistant Integration for EZVIZ HP7 / CP7 Intercom

EZVIZ HP7 / CP7

release license HACS HA python last commit closed issues

Live video (H.264 / HEVC + AAC) • Door/gate unlock • Multi-monitor chime • Unlock events (RFID / face / palm / code / app) • 2FA SMS login

🇮🇹 Versione italiana


Custom Home Assistant integration for the EZVIZ HP7 and CP7 video intercoms (and their close siblings — HP5, CP5, DP1, DP2). HP7 is the original target; CP7 shares the same cloud APIs and live-stream protocol, so it works through the same code path. The device model is auto-detected from the cloud (deviceSubCategory / deviceType) and shown in the Home Assistant device card.

Unlock door / gate remotely, watch the live stream, hear the visitor on the intercom audio, manage the chime sound and volume on both the doorbell and every indoor monitor, react to RFID / face / palm / code / app unlocks in automations.

  • Minimum Home Assistant: 2025.9.0
  • Languages: Italian, English, Spanish, French, Polish (fallback English)

Note

EZVIZ allows only 10 active devices per account. If login fails:

EZVIZ app → User → Login settings → Manage terminals

Remove unused devices to free at least one slot.

Running the official EZVIZ integration (or another fork) at the same time counts against that limit and the two compete for the same account session, which shows up as random login failures or entities dropping out. Users hitting this have had best results removing the other integration, restarting Home Assistant, then adding this one (#35).


✨ Features

ℹ️ Hardware coverage. Everything below is confirmed working on real HP7 / HPD7 hardware unless marked otherwise. Support varies by model and firmware, especially for the local LAN stream — see Model / firmware support for what is actually verified, and Troubleshooting for the problems reported most often. Reports with log lines are always welcome.

  • Auto-discovery and registration of paired EZVIZ HP7 / CP7 devices.
  • Buttons
    • 🔑 Unlock door (lock #2 by default)
    • 🚪 Unlock gate (lock #1 by default)
  • Cameras
    • 📷 Last-alarm snapshot (fetched from EZVIZ cloud)
    • 🔐 Encrypted streams are decrypted — doorbells that scramble the video (increasingly the default, and not disableable at all on some firmware) play normally once the integration has the device key
    • 🎥 Live video (camera.<...>_live) — H.264 and HEVC, via the EZVIZ VTM cloud relay (works over WAN) or a direct LAN stream (CPD7, bypasses the cloud, lower latency). Delivery is auto by default (probes the codec and picks for you), or force WebRTC/HLS (with audio) or MJPEG (codec-agnostic, robust for HEVC + multiple viewers). See the Live video section below for the full option matrix.
  • Switches — (beta) below means wired against the EZVIZ API and working for the author, but not yet confirmed by a second user on different firmware; report back either way
    • 🔔 chime_sound — doorbell button chime on the camera unit
    • 🔔 chime_sound_monitor — chime on each configured indoor monitor (multi-monitor friendly — HP7 bifamigliare)
    • 🛎️ chime_pir / chime_pir_monitor — motion sound notification on / off
    • 💡 label_light — the LED that illuminates the name-tag plate. On HPD7 this is the IoT LightCtrl/NightLightEnable property (read and write confirmed on hardware); older HP7 firmware uses switch type 611
    • 🌙 dnd — (beta) Do-Not-Disturb mode
    • 🕶️ privacy — (beta) privacy / camera blackout
    • 🛡️ defence — (beta) armed / disarmed motion detection
  • Number sliders
    • 🔊 chime_volume / chime_volume_monitor — chime volume 0–7
    • 🎵 chime_ringtone / chime_ringtone_monitor — (beta) ringtone selector 0–15 for the doorbell press
    • 🎵 chime_pir_ringtone / chime_pir_ringtone_monitor — (beta) ringtone selector 0–15 for motion events
  • Sensors
    • Device name, firmware version, online/offline status
    • Wi-Fi signal (%), SSID, local IP, WAN IP
    • Motion state, last alarm timestamp, alarm name, seconds since last trigger
    • 🎙️ mic_volume — microphone volume (diagnostic, read-only)
  • Diagnostic binary sensors (read-only device settings, added only when the device reports them)
    • feature_mute, feature_loitering, feature_stranger_detection, feature_human_detection
    • These are not writable: the doorbell rejects cloud writes for them, so they are exposed as state only. The night light is the one setting of this family that is writable — see label_light above.
  • Binary sensors (each pulses for 3 s on a fresh event)
    • Motion (device_class: motion)
    • Smart Detection Alarm, Intelligent Detection Alarm
    • Doorbell ringing, Gate open, Lock unlocked
    • 🆔 (HP7 Pro / HPD7) unlock_rfid, unlock_face, unlock_palm, unlock_code, unlock_app
  • HA event: ezviz_hp7_unlock — fired on every recognised unlock with {category, alarm_name, alarm_time, serial} so automations can react to RFID / face / palm / code / app unlocks without polling state.
  • Services
    • ezviz_hp7.unlock_door / ezviz_hp7.unlock_gate
    • 🔓 ezviz_hp7.set_video_encryption — turn the device's Image/Video Encryption on or off, for firmware that still allows it
    • 🔑 ezviz_hp7.fetch_encryption_key — retrieve the camera's encryption key (EZVIZ guards it behind a one-time password) and store it, so encrypted streams decrypt
  • Login
    • Account / password / region
    • 🔐 2FA SMS step — the config flow now prompts for the verification code EZVIZ pushes when MFA is enabled, no need to disable 2-step login
  • Regions: eu, us, cn, as, sa, ru

📦 Installation via HACS

This integration is not in the default HACS store — add it as a custom repository using the steps below (the one-click badge does this for you).

  1. Open Home Assistant
  2. Go to HACS → Integrations → Custom repositories
  3. Add https://github.com/Bobsilvio/ezviz_hp7 with type Integration
  4. Search for Ezviz Hp7 and install
  5. Restart Home Assistant
  6. Go to Settings → Devices & Services and add the integration

📦 One-click install

Open in HACS


⚙️ Configuration

  1. Go to Settings → Devices & Services → Add Integration.
  2. Search for EZVIZ HP7 / CP7.
  3. Enter your EZVIZ account credentials:
    • Username (email used for the EZVIZ app)
    • Password
    • Region (one of eu, us, cn, as, sa, ru)

The integration logs in through the EZVIZ API, lists every paired device on the account and lets you pick the HP7 / CP7 serial.


🛠 Usage

After setup, a device card for the EZVIZ HP7 / CP7 intercom appears with the entities listed above (the displayed model label tracks whatever the cloud reports for that serial).

Four services are exposed:

Service What it does
ezviz_hp7.unlock_door Opens the door (lock #2)
ezviz_hp7.unlock_gate Opens the gate (lock #1)
ezviz_hp7.set_video_encryption Turns the device's Image/Video Encryption on or off
ezviz_hp7.fetch_encryption_key Retrieves the camera's encryption key (needs a one-time password) and stores it

serial is optional on all three — omit it with a single configured device.

Example automation:

alias: Unlock gate on RFID card
trigger:
  - platform: state
    entity_id: sensor.rfid_reader
    to: "CARD_1234"
action:
  - service: ezviz_hp7.unlock_gate
    data:
      serial: BEXXXXXXXX-BEXXXXXXXX

Reacting to unlocks in automations

The unlock_* binary sensors pulse for 3 s, which is convenient for dashboards but easy to miss in an automation. For anything that must not be missed — disarming an alarm, logging who came in — trigger on the event instead: it carries the category and the raw alarm name in one payload, and can't be missed between polls.

alias: Disarm alarm when someone unlocks the door
trigger:
  - platform: event
    event_type: ezviz_hp7_unlock
condition:
  - condition: template
    value_template: "{{ trigger.event.data.category in ['unlock_rfid', 'unlock_face', 'unlock_palm'] }}"
action:
  - service: alarm_control_panel.alarm_disarm
    target:
      entity_id: alarm_control_panel.home

What the unlock event can and cannot tell you

✅ How the door was opened category — unlock_rfid, unlock_face, unlock_palm, unlock_code, unlock_app
✅ Which credentials are enrolled keys — the list from the device, with the names you gave them in the app ("Badge 1", "RFID Anna")
⚠️ Who used it card_name is included only when exactly one credential is enabled, where it is a safe inference. With two or more enrolled, it is omitted
❌ Identifying the specific card with several enrolled Not possible — see below

EZVIZ simply does not publish the link between an unlock event and the credential that caused it: cardNo, userId, recExtraInfo and analysisResult all come back null, and customerInfo is just {"object":"Card"}. This was confirmed by packet-capturing the official app while opening an event's detail view — the app itself shows no more than we do (#32). So with two or more cards, treat RFID as "someone with a valid card", not as identification.

Encrypted streams

Many doorbells ship with Image/Video Encryption enabled. It is deceptive when it bites: the MPEG-PS container, the PES packets and the NAL framing all stay perfectly readable, and only the NAL bodies are scrambled — so the stream looks structurally valid while ffmpeg decodes nothing but garbage, and every source/mode/codec combination fails identically.

Since 0.16.x the integration decrypts these streams, so encryption no longer has to be switched off. When it detects the condition it needs the device's encryption key, and how you supply it depends on the firmware.

1. Paste the code (works on most devices — there the key simply is the verification code):

Configure → Encryption key = the 6-character code from the device label → Submit

2. Answer the Repairs prompt (for firmware where the key is not the verification code — the label code is rejected there with 1011).

On these devices the cloud refuses to hand the key to a normal session, and that refusal is what makes EZVIZ e-mail you a 4-digit code — subject [Device Encryption] Security Code, sender service…@hicloudcam.com, valid about 30 minutes. It arrives when you open the live view, which is when the integration asks for the key.

Since 0.17.0 that mail is expected rather than mysterious: the integration raises a prompt under Settings → Repairs, you paste the code, and it exchanges it for the real key, stores it and reloads. If the code has already expired, submit the field empty and a fresh one is sent.

The same thing is available as an action if you prefer, from Developer Tools → Actions — call it once with no code to trigger the mail, then again with the code:

# first call: EZVIZ e-mails you the code
action: ezviz_hp7.fetch_encryption_key
# second call: hand it the code you received
action: ezviz_hp7.fetch_encryption_key
data:
  code: "1234"

Either way the key lands in the integration's options and the entry reloads into a decrypting stream. Clear the manual Encryption key field first so a wrong value can't take precedence.

Turning encryption off instead

Still possible on most firmware, and it avoids the decryption step entirely. Normally you do it in the EZVIZ app, but some app versions no longer show the toggle (#47) — the cloud API still accepts it:

action: ezviz_hp7.set_video_encryption
data:
  enable: false
  verification_code: "ABCDEF"   # label code (6 characters), or the code EZVIZ e-mailed you

The verification code is the one the app asks for when opening the camera view — not your account password. It is required by design, since this changes a security setting, and the integration never touches it on its own.

⚠️ If this fails with 1011 verification code incorrect, the label code is not what EZVIZ wants here. On firmware that no longer shows the encryption toggle in the app — seen on V5.3.6 build 250825 and V5.4.0 build 260115 — the label code is rejected on every serial and field variant the integration tries. What was accepted on V5.4.0 is the short numeric code EZVIZ e-mails to the account: with that in verification_code the call succeeded immediately and the live view started (#47). So if you have such an e-mail, use that code here instead of the one on the label. Exactly what triggers the e-mail is still being pinned down — reports welcome on #47.


🚧 Limitations

  • One doorbell per config entry. Several devices work fine — add the integration once per serial; they share the account session.
  • Switch state is read back via cloud polling, so a change made in the EZVIZ app appears after the next poll cycle. Changes made from Home Assistant apply immediately: the switch holds the value you set for a short grace window, because the EZVIZ cloud takes a few seconds to report a write back and would otherwise make the toggle appear to bounce.
  • Two-way audio (talkback) is not implemented. Inbound audio is carried on the webrtc stream mode (AAC); the mjpeg mode is video-only.

📺 Live video

The HP7 / CP7 don't expose RTSP or ONVIF and don't register on the Hik-Connect UDP P2P cloud. A camera.ezviz_hp7_<serial>_live entity exposes the live stream, and the integration can pull it two ways — pick per device in Settings → Devices → EZVIZ HP7 / CP7 → Configure.

Stream source: cloud vs local vs auto

Source How it works When to use
cloud (default) EZVIZ VTM cloud relay — a TCP ysproto session delivering MPEG-PS over a regional EZVIZ server. Built on RenierM26/pyEzvizApi. HA isn't on the same LAN as the doorbell, or the firmware pushes cleanly to the cloud.
local Direct LAN stream (CPD7 protocol — ports 9010/9020, AES-128-CBC control, ECDH + ChaCha20 media). Bypasses the cloud entirely. Reverse engineered by albrzmr. HA is on the same network as the doorbell. Works on firmware whose VTM channel never pushes (CP5 / some HP7). Lower latency, no cloud.
auto Try local first, fall back to cloud. Default-friendly choice when on the LAN.

If the doorbell encrypts the video, local needs the encryption key — see Encrypted streams. Since 0.16.x the integration decrypts the stream rather than requiring you to switch encryption off.

Stream mode: auto / webrtc / mjpeg

Mode Delivery Audio HEVC Notes
auto (default) picks the mode from the detected codec — — Probes the video codec once at startup: H.264 → webrtc, HEVC → mjpeg. Falls back to mjpeg if the codec can't be determined. You don't need to know your doorbell's codec.
mjpeg per-viewer ffmpeg → motion-JPEG, piped straight to the browser ❌ native (decoded to JPEG) Codec-agnostic, no go2rtc, rock-solid for multiple simultaneous viewers. One ffmpeg per viewer. Adapted from albrzmr.
webrtc HA Stream / go2rtc (HLS/WebRTC) ✅ needs transcode to H.264 Low latency + audio. Browsers can't decode HEVC over WebRTC, so HEVC firmware is transcoded (needs go2rtc; fails on weak hosts).

Since 0.13.14 the default is auto: at startup it sniffs the codec and uses webrtc for H.264 doorbells (audio + low latency) and mjpeg for HEVC ones (which WebRTC can't display without transcoding). This means live video works out of the box regardless of model, without you having to know the codec. Force a specific mode if you prefer — e.g. webrtc to always get audio, or mjpeg for multi-viewer robustness. If you force webrtc on an HEVC doorbell, the integration raises a Repairs notice steering you back to auto/mjpeg.

Video codec: auto / h264 / hevc / hevc_copy

Newer HP7 (HPD7) and CP7 firmware stream HEVC/H.265; older HP7 streams H.264. auto detects it. On the WebRTC path, hevc transcodes to H.264 (browser-friendly); hevc_copy passes H.265 through untouched, which costs no CPU but hands the decoding problem downstream. On the MJPEG path the codec doesn't matter (ffmpeg decodes either to JPEG).

⚠️ hevc_copy and recorded files. Most browsers cannot play H.265 — Chrome and Firefox generally refuse it, Safari is the exception. So an NVR that records the passthrough stream produces MP4s that its web UI then can't play: in Frigate the History/Detections view hangs on "Loading" even though the recording is a perfectly valid file (#48). Live view is unaffected. If you record and want to play those recordings back in a browser, either use hevc (we transcode) or keep hevc_copy and transcode in go2rtc instead, which keeps the relay cheap:

go2rtc:
  streams:
    hp7:
      - "ffmpeg:tcp://127.0.0.1:8554#video=h264"   # H.264 for recording/playback

Stream quality: main vs sub (local source only)

The LAN session asks the doorbell for its main (full-resolution) encoder stream by default. Setting Stream quality = sub requests the device's low-resolution substream instead, which is far cheaper to decode — worth trying if the picture lags on a low-powered host, or if you only need the stream for detection in Frigate.

⚠️ Not every firmware honours the substream request: on at least one HPD7 the stream simply fails to start with sub. If that happens, switch back to main. Leave it on main unless you are specifically chasing a performance problem.

Model / firmware support

Based on what users have actually confirmed on hardware — not on what the protocol should allow:

Model Cloud (VTM) Local (LAN / CPD7) Notes
HP7 (H.264) ✅ ✅ WebRTC works, so you get audio
HP7 Pro / HPD7 (HEVC) ✅ ✅ Use auto or mjpeg; WebRTC can't show HEVC without transcoding
CP7 ✅ ✅ Encrypted streams are decrypted with the device key
CP5 ✅ ❌ The firmware never authorises the LAN key: CAS keeps returning 1052175 even with encryption off. Use the cloud source
HP5 / HPD5 ✅ ✅ Confirmed working (#41)
HP7 / HPD7 fw V5.3.6+ ✅ ✅ The app no longer shows the encryption toggle, and encryption is on by default. Supply the key and the stream is decrypted; disabling it also still works, but with the code EZVIZ e-mails rather than the label code (#47)

On encryption: since 0.15.8 the integration detects a scrambled stream itself (via PES_scrambling_control) instead of leaving you to debug what looks like a decoder bug, and since 0.16.x it decrypts it given the key — see Encrypted streams. A firmware or app update can silently re-enable encryption, so this is worth knowing even if yours is currently off. Note that encryption can also make the CAS refuse the LAN key outright (1052170 / 1052175), which no key can work around: that one still needs encryption switched off, or the cloud source.

While a LAN stream has viewers the coordinator automatically drops to a quarter of its normal polling rate and snaps back when the last viewer disconnects. Several of the endpoints we poll are proxied by the cloud down to the doorbell itself, and answering them competes with its streaming task, so sensors updating a little more slowly during live view is deliberate.

A circuit-breaker rate-limits viewing attempts (30 s between retries, 10 min cool-down after 3 consecutive failures) so a transient cloud error can't trigger the EZVIZ account-lock heuristic. The resolved LAN IP + AES key are cached so the local stream rides out transient EZVIZ cloud 504s.

Exposing the live stream as RTSP (go2rtc / Frigate)

The relay listens on a random port by default. Set a Fixed TCP port (e.g. 8554) in Settings → Devices → EZVIZ HP7 / CP7 → Configure so external consumers can keep a stable URL across HA restarts. Then in go2rtc (already shipped in HA core):

# configuration.yaml
go2rtc:
  streams:
    hp7:
      - "ffmpeg:tcp://127.0.0.1:8554#video=copy"

⚠️ The ffmpeg: wrapper matters. go2rtc's native tcp:// source expects MPEG-TS, but the relay serves MPEG-PS; with a plain tcp:// source the RTSP restream answers 404 / "Invalid data" to downstream consumers. Thanks to @ycmp64 for pinning this down (#41).

go2rtc will publish the stream as:

  • rtsp://homeassistant.local:8554/hp7
  • HLS / WebRTC / MSE endpoints

Frigate then ingests rtsp://homeassistant.local:8554/hp7 like any other camera, with record and detect roles.

Frigate (or any consumer) on a different host: by default the relay binds 127.0.0.1, so only processes on the HA machine can read it. Since 0.14.0, Configure exposes a Relay listen host option — set it to 0.0.0.0 (together with a fixed port) to let another box connect directly to tcp://<ha-ip>:8554. ⚠️ The raw stream is unauthenticated: only do this on a trusted LAN / VLAN, ideally with a firewall rule limiting the source IP.

Full Frigate example

Courtesy of @digregoriovalerio (#44) — protect the go2rtc restream with credentials and point Frigate at it:

# Home Assistant configuration.yaml
go2rtc:
  debug_ui: true
  username: admin
  password: !secret go2rtc_password
# Frigate config.yaml
cameras:
  hp7:
    enabled: true
    friendly_name: EZVIZ HP7
    ffmpeg:
      input_args: preset-rtsp-generic
      inputs:
        - path: rtsp://admin:<go2rtc_password>@<ha_ip>:18554/ezviz_hp7_live
          roles:
            - detect
            - record

The password must be URL-encoded in the path. Open http://<ha_ip>:11984 to check the go2rtc page — the links section shows the exact RTSP URL for your setup, since the stream name depends on your entity id.

💡 For 24/7 recording, prefer event-driven clips: trigger Frigate (or a snapshot/record automation) from this integration's motion and doorbell binary sensors rather than holding a permanent session. Continuous recording through the cloud source in particular is a bad fit — long sessions get dropped and reconnect churn can trip EZVIZ rate limits.


🩺 Troubleshooting

Most reports fall into a handful of patterns. Start here before opening an issue.

First, check your version. HACS does not auto-update custom integrations — you have to trigger the update, then fully restart Home Assistant (a reload is not enough; the old module stays in memory). A surprising number of reported bugs are already fixed in a newer release.

Symptom Cause Fix
Live view stuck on idle / blank, Immediate exit requested, Invalid data found, or got_output=False The doorbell streams HEVC, or its video is encrypted Set Stream source = local, Stream mode = auto, Video codec = auto. If the log mentions scrambling, see Encrypted streams
Grey / black picture, or dial tcp … connection refused from go2rtc HEVC on the WebRTC path — browsers can't decode it Use Stream mode = auto (picks MJPEG for HEVC automatically) or force mjpeg
Snapshot is a blob starting with hikencodepicture Image Encryption is on — the picture is encrypted Turn Image/Video Encryption OFF in the EZVIZ app
Frigate recordings won't play — History/Detections stuck on "Loading" The recording is H.265 and the browser can't decode it (hevc_copy passes it through) Use Video codec hevc, or transcode in go2rtc with #video=h264 — see Video codec
Live view black, log says the doorbell is scrambling the video Image/Video Encryption is on — possibly re-enabled by an app/firmware update Give the integration the key so it can decrypt — see Encrypted streams. Turning encryption off in the app still works too, where the app offers it
Log says decrypting it with the camera key but the picture is still black The key is being used but is the wrong material for your firmware Fetch the real key from the cloud with ezviz_hp7.fetch_encryption_key (needs a one-time password) — see Encrypted streams
CAS get-encryption failed / Result=1052170 / 1052175 The device won't hand out a LAN key Encryption OFF first. If it persists, your firmware may not support the LAN path at all — see the support table above and use cloud
All entities go unknown / unavailable, sometimes for hours Transient EZVIZ cloud 504s, or an expired session on an old version Update: since 0.13.11 the coordinator keeps last-known values through a ~1 min grace window and re-logins automatically. Also remove any "reload the integration" automation — it makes outages longer and can trip rate limits
A switch flips back a few seconds after you toggle it The cloud reports the old state briefly Fixed in 0.13.21 (the switch holds your value during a grace window)
Unlock sensors fire on every Home Assistant restart The cloud always reports the last alarm, which looked new at startup Fixed in 0.15.1
Live view takes 20-30 s to appear The viewer had to wait for the doorbell's next keyframe Fixed in 0.13.21 — the relay replays the stream since the last keyframe to each new viewer

When opening an issue, these four things make it solvable quickly: the integration version, the device model, your Configure settings (stream source / mode / codec), and the log lines. Enable debug logging first — Settings → Devices & Services → EZVIZ HP7 / CP7 → ⋮ → Enable debug logging — then reproduce, and paste the lines mentioning ezviz_hp7. The relay's own progress line is especially informative:

Hp7StreamRelay: broadcast LAN MPEG-PS progress <bytes> audio=<bytes> subs=<N> kf_markers=<N> drops=<N>
[MJPEG] session END ... frames=<N> stale_dropped=<N> blocked=<N>s reason=...

Reading those numbers

They were added while chasing a stubborn stall (#44) and each one rules something in or out, so they're worth understanding before assuming where a problem is:

Field What it tells you
progress <bytes> / audio= Whether video and audio are still arriving from the doorbell. Video frozen while audio keeps climbing means the fault is in the video path specifically, not the session or the network
kf_markers= Keyframes seen. Still rising = the device is streaming normally; stuck = the LAN session died
subs= Subscribers on the relay. Should roughly match your viewers — every dashboard card, Frigate role and preview is one, and each costs its own ffmpeg
drops= Chunks the relay had to discard. Climbing means a consumer can't keep up (HA side); zero while the picture misbehaves means the problem is upstream or downstream, not the queues
blocked= Seconds spent waiting on the viewer's HTTP connection. A large share of the session duration means the browser or network is the bottleneck; a tiny value exonerates it
stale_dropped= Frames skipped because the viewer was behind. Nonzero is normal and healthy — it's how the live view stays current instead of accumulating delay
reason= client_disconnected is normal (you closed the view). ffmpeg_eof means the pipeline ended on its own and is worth reporting

The pairing that identifies most problems fastest is video vs audio: they travel on separate queues into the same ffmpeg, so if one keeps working while the other stops, that alone narrows the cause enormously.

⚠️ ps aux | grep ffmpeg run from the SSH/Terminal add-on always returns 0 — that container has its own process namespace and cannot see Home Assistant's processes. It is not a useful measurement.


🌐 Translations

UI labels and entity states are translated. Currently shipped:

  • 🇮🇹 Italian (it)
  • 🇬🇧 English (en)
  • 🇪🇸 Spanish (es)
  • 🇫🇷 French (fr)
  • 🇵🇱 Polish (pl) — contributed by @kurdak

To add a language, copy custom_components/ezviz_hp7/translations/en.json to <lang>.json, translate the values, and restart Home Assistant.


🤝 Contributing

Pull requests and issues welcome. Open an issue for bugs or feature requests.

This integration uses the EZVIZ API client from RenierM26/pyEzvizApi, vendored locally under custom_components/ezviz_hp7/pylocalapi/ to pin the version and avoid breaking changes from upstream releases.

Credits

  • Cloud VTM relay — built on RenierM26/pyEzvizApi.
  • Local LAN stream (CPD7) — the direct-LAN streaming protocol (ports 9010/9020, AES-128-CBC control frames, ECDH P-256 key agreement, ChaCha20 media decryption) was reverse engineered by albrzmr. The cpd7/ modules are vendored from that fork under its MIT license, with thanks. This integration adds the EZVIZ p2p-register + CAS step that unlocks the LAN AES key (the missing piece that returned 1052170 before).
  • Community diagnosis — several fixes here came from users' own analysis rather than mine: the hikencodepicture / encryption finding and the ffmpeg probe-window fix (@alex66a-hub), the HPD5 bitstream analysis (@ycmp64), the cloud-polling-vs-stream observation and the measurements that eliminated three wrong theories (@AnthoPakPak), and the Frigate recipe (@digregoriovalerio). Thank you.
  • MJPEG live-view mode — the codec-agnostic per-viewer ffmpeg→motion-JPEG approach (which sidesteps the go2rtc/WebRTC HEVC issues) is also adapted from albrzmr, with thanks. Selectable per device via the Stream mode option. Since 0.13.14 the default is auto, which probes the codec and picks MJPEG for HEVC and WebRTC (with audio) for H.264.

📜 License

Released under the MIT License — free to use, modify and redistribute, provided the copyright notice is kept. Provided as-is, without warranty of any kind.

Vendored third-party components keep their own licenses (albrzmr's CPD7 LAN + MJPEG code under MIT, RenierM26/pyEzvizApi under Apache-2.0) — see THIRD_PARTY_LICENSES.md.


☕ Support the project / Supportami

If you like this integration and want to support further development, you can buy me a coffee. Se il progetto ti è utile, puoi offrirmi un caffè:

Ko-fi PayPal

📲 Social

TikTok Instagram YouTube

About

Home Assistant Integration for EZVIZ HP7 Intercom

Topics

Resources

Stars

60 stars

Watchers

5 watching

Forks

Releases

Packages

Contributors

Languages