Aqara G400 Doorbell with 2-way audio in Home Assistant

I’ve recently been playing with dissecting the workings of the G400 Doorbell and have come up with a proof of concept integration for implementing 2-way audio in Home Assistant. No cloud, no hub, fully local.

Disclaimer

This is NOT a complete production ready integration for the Aqara G400 Doorbell, it is a proof of concept designed to test if fully local two-way audio independent of any hub/app/cloud connection is possible with the device. It is recommended to use the doorbell in Home Assistant via the official HomeKit integration.

Please do not install this integration and expect it to provide a fully functioning doorbell, it is purely a proof of concept for 2-way audio in Home Assistant

Features

  • Video streaming via RTSP (H.264)
  • Two-way audio via go2rtc backchannel — speak through the doorbell from the HA dashboard
  • Doorbell press detection via UDP multicast
  • Audio file playback — play pre-recorded messages through the doorbell speaker
  • Fully local — all communication stays on your LAN

I’ll hopefully be adding more features and making it work smoother in the coming future.

The end goal is to get the Aqara 2-way audio backchannel implemented natively in Go2RTC.

And now for the technical bit.

How it works

The Aqara G400 LAN talk protocol was reverse-engineered from the Aqara Android app. It uses three independent network channels:

Channel Protocol Port Purpose
Video/Audio stream RTSP over TCP 8554 H.264 video + AAC audio from camera
Voice control TCP 54324 Session management (start/stop/heartbeat)
Voice audio UDP (RTP) 54323 AAC-LC ADTS frames to doorbell speaker
Doorbell press UDP multicast 230.0.0.1:10008 Button press notification

Control channel (TCP 54324)

Uses a custom LmLocalPacket binary format:

Magic (0xFEEF) | Type (1B) | Payload Length (2B) | Payload (N) | CRC-16 (2B)
  • START_VOICE (type 0): Opens session, payload is epoch milliseconds
  • STOP_VOICE (type 1): Closes session
  • ACK (type 2): Response from camera (0 = success)
  • HEARTBEAT (type 3): Sent every 5 seconds to keep session alive

CRC is CRC-16/KERMIT (polynomial 0x8408, init 0xFFFF, final XOR 0xFFFF).

Audio channel (UDP 54323)

RTP (RFC 3550) with payload type 97 (dynamic AAC):

  • Codec: AAC-LC ADTS, 16kHz, mono, 32kbps
  • Frame size: 1024 samples (64ms per frame)
  • RTP timestamp clock: 16kHz

Available Services

Service Description
aqara_doorbell.talk_start Open a voice session with the doorbell
aqara_doorbell.talk_stop Close the active voice session
aqara_doorbell.talk_audio_file Play an AAC audio file through the doorbell speaker

Full details, install instructions, dashboard cards, and example automations are in the Github repository:

10 Likes

Dashboard card

Add a WebRTC Camera card to your dashboard:

type: custom:webrtc-camera
streams:
  - url: aqara_doorbell_DOORBELL_IP
    mode: webrtc
    media: video,audio,microphone
style: >
  video {aspect-ratio: 3/4; object-fit: fill;}    

Replace DOORBELL_IP with your doorbell’s IP address (dots replaced with underscores, e.g. aqara_doorbell_192_168_1_100).

Multi-stream card example with a toggle between listening and speaking:

type: custom:webrtc-camera
ui: true
streams:
  - url: aqara_doorbell_DOORBELL_IP
    mode: webrtc
    media: video,audio
    name: Listening
  - url: aqara_doorbell_DOORBELL_IP
    mode: webrtc
    media: video,audio,microphone
    name: Speaking
style: >
  video {aspect-ratio: 3/4; object-fit: fill;} .volume { padding: 4px 6px;
  display: flex } .stream { padding: 4px 8px; flex: 1 0 0; } .space, .header,
  .fullscreen, .screenshot, .pictureinpicture { display: none }

Note: The card must use url: (go2rtc stream name), not entity: (HA entity ID). The go2rtc stream name is aqara_doorbell_{ip_with_underscores}.

Note: The browser must be served over HTTPS for microphone access to work. The first connection will prompt for microphone permission.

Audio file playback

Play pre-recorded audio files through the doorbell speaker using the talk_audio_file service:

# Example automation: play a greeting when doorbell rings
automation:
  trigger:
    platform: state
    entity_id: event.aqara_doorbell_DOORBELL_IP_doorbell
    attribute: event_type
    to: ring
  action:
    service: aqara_doorbell.talk_audio_file
    data:
      file_path: /media/doorbell_greeting.aac

The file path must be in HA’s allowlist_external_dirs configuration.

Note: Talk services and browser two-way audio are mutually exclusive. The doorbell supports one voice session at a time.

Doorbell Press Detection

The doorbell sends a UDP multicast packet to 230.0.0.1:10008 when the button is pressed. The integration listens for these packets and fires a ring event on the doorbell entity. This works independently of the Aqara hub — no cloud or hub connection needed.

Use the event entity in automations:

automation:
  trigger:
    platform: state
    entity_id: event.aqara_doorbell_DOORBELL_IP_doorbell
    attribute: event_type
    to: ring
  action:
    - service: notify.mobile_app
      data:
        message: "There's somebody at the door!"
5 Likes

Nice sharing!

2 Likes

This is a great project!
Shouldn’t this work with the G410 as well, or am I mistaken?

2 Likes

Thanks! This looks promising. I am still hoping for native Matter 1.5.1 Video Doorbell support in the G400 and G410, but this would make it more handable in the meantime.

1 Like

It may well work, but I don’t have a G410 to test.

2 Likes

Could you provide the automation trace to see what part of it it’s failing on?

And does a simple basic automation work? Like:

alias: "Doorbell test"
description: ""
triggers:
  - trigger: event.received
    target:
      entity_id: event.aqara_doorbell_10_1_20_150_doorbell
    options:
      event_type:
        - ring
conditions: []
actions:
  - action: light.toggle
    metadata: {}
    data: {}
    target:
      entity_id: light.office_lamp
mode: single

2 Likes

Hi, I used the sample automation you supplied and can successfully trigger it manually.

See below for YAML and Traces timeline. It doesn’t fire, though, when I ring the actual doorbell.

2 Likes

What step in the trace is your automation failing though? Does it detect the doorbell ring event or does it fail at a later point? Do the ring events show up in the device panel? Is your doorbell and Home Assistant on the same subnet?

2 Likes

It never detects the Ring event, so doesn’t ever enter the automation.

Yes it is on the same subnet (which I use for IoT devices). When I added your integration it was automatically discovered. Also, I get full camera notifications directly in Home Assistant from the G400 doorbell (via Frigate). i.e. person or car detected.

I run a Unifi home network and allow mDNS across VLANs, although this traffic should stay within the IoT network.

2 Likes

Ah, I found some errors in the HA log file…

Log details (WARNING)

This error originated from a custom integration.

Logger: custom_components.aqara_doorbell.event
Source: custom_components/aqara_doorbell/event.py:58
integration: Aqara Doorbell (documentation, issues)
First occurred: May 2, 2026 at 4:31:58 PM (1 occurrence)
Last logged: May 2, 2026 at 4:31:58 PM

Multicast protocol connection lost: None

======================================

Logger: homeassistant.util.loop
Source: util/loop.py:137
First occurred: May 2, 2026 at 4:31:58 PM (4 occurrences)
Last logged: May 2, 2026 at 4:31:58 PM

  • Detected blocking call to read_text with args (PosixPath(‘/config/go2rtc.yaml’),) inside the event loop by custom integration ‘aqara_doorbell’ at custom_components/aqara_doorbell/go2rtc.py, line 128: raw = config_path.read_text() (offender: /config/custom_components/aqara_doorbell/go2rtc.py, line 128: raw = config_path.read_text()), please create a bug report at Issues · absent42/aqara-doorbell · GitHub For developers, please see Blocking operations with asyncio | Home Assistant Developer Docs Traceback (most recent call last): File “”, line 198, in _run_module_as_main File “”, line 88, in _run_code File “/usr/src/homeassistant/homeassistant/main.py”, line 229, in sys.exit(main()) File “/usr/src/homeassistant/homeassistant/main.py”, line 215, in main exit_code = runner.run(runtime_conf) File “/usr/src/homeassistant/homeassistant/runner.py”, line 289, in run return loop.run_until_complete(setup_and_run_hass(runtime_config)) File “/usr/local/lib/python3.14/asyncio/base_events.py”, line 706, in run_until_complete self.run_forever() File “/usr/local/lib/python3.14/asyncio/base_events.py”, line 677, in run_forever self._run_once() File “/usr/local/lib/python3.14/asyncio/base_events.py”, line 2046, in _run_once handle._run() File “/usr/local/lib/python3.14/asyncio/events.py”, line 94, in _run self._context.run(self._callback, *self._args) File “/usr/local/lib/python3.14/site-packages/aiohttp/web_protocol.py”, line 605, in start task = asyncio.Task(coro, loop=loop, eager_start=True) File “/usr/local/lib/python3.14/site-packages/aiohttp/web_protocol.py”, line 517, in _handle_request resp = await request_handler(request) File “/usr/local/lib/python3.14/site-packages/aiohttp/web_app.py”, line 569, in _handle return await handler(request) File “/usr/local/lib/python3.14/site-packages/aiohttp/web_middlewares.py”, line 117, in impl return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/security_filter.py”, line 92, in security_filter_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/forwarded.py”, line 87, in forwarded_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/request_context.py”, line 26, in request_context_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/ban.py”, line 90, in ban_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/auth.py”, line 263, in auth_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/headers.py”, line 41, in headers_middleware response = await handler(request) File “/usr/src/homeassistant/homeassistant/helpers/http.py”, line 89, in handle result = await handler(request, **request.match_info) File “/usr/src/homeassistant/homeassistant/components/config/config_entries.py”, line 141, in post await hass.config_entries.async_reload(entry_id) File “/usr/src/homeassistant/homeassistant/config_entries.py”, line 2387, in async_reload unload_result = await self.async_unload(entry_id, _lock=False) File “/usr/src/homeassistant/homeassistant/config_entries.py”, line 2345, in async_unload return await entry.async_unload(self.hass) File “/usr/src/homeassistant/homeassistant/config_entries.py”, line 1006, in async_unload result = await component.async_unload_entry(hass, self) File “/config/custom_components/aqara_doorbell/init.py”, line 146, in async_unload_entry go2rtc_mod.remove_stream(hass.config.config_dir, entry.runtime_data.go2rtc_stream_name) File “/config/custom_components/aqara_doorbell/go2rtc.py”, line 128, in remove_stream raw = config_path.read_text()
  • Detected blocking call to open with args (PosixPath(‘/config/go2rtc.yaml’),) inside the event loop by custom integration ‘aqara_doorbell’ at custom_components/aqara_doorbell/go2rtc.py, line 128: raw = config_path.read_text() (offender: /usr/local/lib/python3.14/pathlib/init.py, line 787: with self.open(mode=‘r’, encoding=encoding, errors=errors, newline=newline) as f:), please create a bug report at Issues · absent42/aqara-doorbell · GitHub For developers, please see Blocking operations with asyncio | Home Assistant Developer Docs Traceback (most recent call last): File “”, line 198, in _run_module_as_main File “”, line 88, in _run_code File “/usr/src/homeassistant/homeassistant/main.py”, line 229, in sys.exit(main()) File “/usr/src/homeassistant/homeassistant/main.py”, line 215, in main exit_code = runner.run(runtime_conf) File “/usr/src/homeassistant/homeassistant/runner.py”, line 289, in run return loop.run_until_complete(setup_and_run_hass(runtime_config)) File “/usr/local/lib/python3.14/asyncio/base_events.py”, line 706, in run_until_complete self.run_forever() File “/usr/local/lib/python3.14/asyncio/base_events.py”, line 677, in run_forever self._run_once() File “/usr/local/lib/python3.14/asyncio/base_events.py”, line 2046, in _run_once handle._run() File “/usr/local/lib/python3.14/asyncio/events.py”, line 94, in _run self._context.run(self._callback, *self._args) File “/usr/local/lib/python3.14/site-packages/aiohttp/web_protocol.py”, line 605, in start task = asyncio.Task(coro, loop=loop, eager_start=True) File “/usr/local/lib/python3.14/site-packages/aiohttp/web_protocol.py”, line 517, in _handle_request resp = await request_handler(request) File “/usr/local/lib/python3.14/site-packages/aiohttp/web_app.py”, line 569, in _handle return await handler(request) File “/usr/local/lib/python3.14/site-packages/aiohttp/web_middlewares.py”, line 117, in impl return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/security_filter.py”, line 92, in security_filter_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/forwarded.py”, line 87, in forwarded_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/request_context.py”, line 26, in request_context_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/ban.py”, line 90, in ban_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/auth.py”, line 263, in auth_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/headers.py”, line 41, in headers_middleware response = await handler(request) File “/usr/src/homeassistant/homeassistant/helpers/http.py”, line 89, in handle result = await handler(request, **request.match_info) File “/usr/src/homeassistant/homeassistant/components/config/config_entries.py”, line 141, in post await hass.config_entries.async_reload(entry_id) File “/usr/src/homeassistant/homeassistant/config_entries.py”, line 2387, in async_reload unload_result = await self.async_unload(entry_id, _lock=False) File “/usr/src/homeassistant/homeassistant/config_entries.py”, line 2345, in async_unload return await entry.async_unload(self.hass) File “/usr/src/homeassistant/homeassistant/config_entries.py”, line 1006, in async_unload result = await component.async_unload_entry(hass, self) File “/config/custom_components/aqara_doorbell/init.py”, line 146, in async_unload_entry go2rtc_mod.remove_stream(hass.config.config_dir, entry.runtime_data.go2rtc_stream_name) File “/config/custom_components/aqara_doorbell/go2rtc.py”, line 128, in remove_stream raw = config_path.read_text()
  • Detected blocking call to write_text with args (PosixPath(‘/config/go2rtc.yaml’), ‘streams: {}\n’) inside the event loop by custom integration ‘aqara_doorbell’ at custom_components/aqara_doorbell/go2rtc.py, line 133: config_path.write_text(_dump_config(config)) (offender: /config/custom_components/aqara_doorbell/go2rtc.py, line 133: config_path.write_text(_dump_config(config))), please create a bug report at Issues · absent42/aqara-doorbell · GitHub For developers, please see Blocking operations with asyncio | Home Assistant Developer Docs Traceback (most recent call last): File “”, line 198, in _run_module_as_main File “”, line 88, in _run_code File “/usr/src/homeassistant/homeassistant/main.py”, line 229, in sys.exit(main()) File “/usr/src/homeassistant/homeassistant/main.py”, line 215, in main exit_code = runner.run(runtime_conf) File “/usr/src/homeassistant/homeassistant/runner.py”, line 289, in run return loop.run_until_complete(setup_and_run_hass(runtime_config)) File “/usr/local/lib/python3.14/asyncio/base_events.py”, line 706, in run_until_complete self.run_forever() File “/usr/local/lib/python3.14/asyncio/base_events.py”, line 677, in run_forever self._run_once() File “/usr/local/lib/python3.14/asyncio/base_events.py”, line 2046, in _run_once handle._run() File “/usr/local/lib/python3.14/asyncio/events.py”, line 94, in _run self._context.run(self._callback, *self._args) File “/usr/local/lib/python3.14/site-packages/aiohttp/web_protocol.py”, line 605, in start task = asyncio.Task(coro, loop=loop, eager_start=True) File “/usr/local/lib/python3.14/site-packages/aiohttp/web_protocol.py”, line 517, in _handle_request resp = await request_handler(request) File “/usr/local/lib/python3.14/site-packages/aiohttp/web_app.py”, line 569, in _handle return await handler(request) File “/usr/local/lib/python3.14/site-packages/aiohttp/web_middlewares.py”, line 117, in impl return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/security_filter.py”, line 92, in security_filter_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/forwarded.py”, line 87, in forwarded_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/request_context.py”, line 26, in request_context_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/ban.py”, line 90, in ban_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/auth.py”, line 263, in auth_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/headers.py”, line 41, in headers_middleware response = await handler(request) File “/usr/src/homeassistant/homeassistant/helpers/http.py”, line 89, in handle result = await handler(request, **request.match_info) File “/usr/src/homeassistant/homeassistant/components/config/config_entries.py”, line 141, in post await hass.config_entries.async_reload(entry_id) File “/usr/src/homeassistant/homeassistant/config_entries.py”, line 2387, in async_reload unload_result = await self.async_unload(entry_id, _lock=False) File “/usr/src/homeassistant/homeassistant/config_entries.py”, line 2345, in async_unload return await entry.async_unload(self.hass) File “/usr/src/homeassistant/homeassistant/config_entries.py”, line 1006, in async_unload result = await component.async_unload_entry(hass, self) File “/config/custom_components/aqara_doorbell/init.py”, line 146, in async_unload_entry go2rtc_mod.remove_stream(hass.config.config_dir, entry.runtime_data.go2rtc_stream_name) File “/config/custom_components/aqara_doorbell/go2rtc.py”, line 133, in remove_stream config_path.write_text(_dump_config(config))
  • Detected blocking call to open with args (PosixPath(‘/config/go2rtc.yaml’),) inside the event loop by custom integration ‘aqara_doorbell’ at custom_components/aqara_doorbell/go2rtc.py, line 133: config_path.write_text(_dump_config(config)) (offender: /usr/local/lib/python3.14/pathlib/init.py, line 809: with self.open(mode=‘w’, encoding=encoding, errors=errors, newline=newline) as f:), please create a bug report at Issues · absent42/aqara-doorbell · GitHub For developers, please see Blocking operations with asyncio | Home Assistant Developer Docs Traceback (most recent call last): File “”, line 198, in _run_module_as_main File “”, line 88, in _run_code File “/usr/src/homeassistant/homeassistant/main.py”, line 229, in sys.exit(main()) File “/usr/src/homeassistant/homeassistant/main.py”, line 215, in main exit_code = runner.run(runtime_conf) File “/usr/src/homeassistant/homeassistant/runner.py”, line 289, in run return loop.run_until_complete(setup_and_run_hass(runtime_config)) File “/usr/local/lib/python3.14/asyncio/base_events.py”, line 706, in run_until_complete self.run_forever() File “/usr/local/lib/python3.14/asyncio/base_events.py”, line 677, in run_forever self._run_once() File “/usr/local/lib/python3.14/asyncio/base_events.py”, line 2046, in _run_once handle._run() File “/usr/local/lib/python3.14/asyncio/events.py”, line 94, in _run self._context.run(self._callback, *self._args) File “/usr/local/lib/python3.14/site-packages/aiohttp/web_protocol.py”, line 605, in start task = asyncio.Task(coro, loop=loop, eager_start=True) File “/usr/local/lib/python3.14/site-packages/aiohttp/web_protocol.py”, line 517, in _handle_request resp = await request_handler(request) File “/usr/local/lib/python3.14/site-packages/aiohttp/web_app.py”, line 569, in _handle return await handler(request) File “/usr/local/lib/python3.14/site-packages/aiohttp/web_middlewares.py”, line 117, in impl return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/security_filter.py”, line 92, in security_filter_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/forwarded.py”, line 87, in forwarded_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/request_context.py”, line 26, in request_context_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/ban.py”, line 90, in ban_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/auth.py”, line 263, in auth_middleware return await handler(request) File “/usr/src/homeassistant/homeassistant/components/http/headers.py”, line 41, in headers_middleware response = await handler(request) File “/usr/src/homeassistant/homeassistant/helpers/http.py”, line 89, in handle result = await handler(request, **request.match_info) File “/usr/src/homeassistant/homeassistant/components/config/config_entries.py”, line 141, in post await hass.config_entries.async_reload(entry_id) File “/usr/src/homeassistant/homeassistant/config_entries.py”, line 2387, in async_reload unload_result = await self.async_unload(entry_id, _lock=False) File “/usr/src/homeassistant/homeassistant/config_entries.py”, line 2345, in async_unload return await entry.async_unload(self.hass) File “/usr/src/homeassistant/homeassistant/config_entries.py”, line 1006, in async_unload result = await component.async_unload_entry(hass, self) File “/config/custom_components/aqara_doorbell/init.py”, line 146, in async_unload_entry go2rtc_mod.remove_stream(hass.config.config_dir, entry.runtime_data.go2rtc_stream_name) File “/config/custom_components/aqara_doorbell/go2rtc.py”, line 133, in remove_stream config_path.write_text(_dump_config(config))
2 Likes

Please use the “Preformatted text” option (Ctrl+E) for log files. Thank you.

1 Like

Good to know, thanks!

1 Like

That error should be fix now in v0.1.2. But please be aware, as stated this is just a proof-of-concept for 2-way audio and not a fully working doorbell integration.

1 Like

Thanks a bunch & glad to help test the integration.

FYI, about 11pm last night the Doorbell Test automation that you provided triggered itself five times without anyone pressing the doorbell. Here’s the trace from the first event. BTW, I’m still running version 0.1.1

Changed Variables

this:
  entity_id: automation.doorbell_test
  state: 'on'
  attributes:
    id: '1777832904721'
    last_triggered: '2026-05-04T03:09:40.497523+00:00'
    mode: single
    current: 0
    friendly_name: Doorbell test
  last_changed: '2026-05-04T03:08:16.288250+00:00'
  last_reported: '2026-05-04T03:09:40.499171+00:00'
  last_updated: '2026-05-04T03:09:40.499171+00:00'
  context:
    id: 01KQRFD0RHV70AVH3MG0813ME2
    parent_id: 01KQRFD0RF4214VFJA2YYPXCEF
    user_id: null
trigger:
  id: '0'
  idx: '0'
  alias: null
  platform: event.received
  description: state of event.aqara_doorbell_192_168_4_40_doorbell
  entity_id: event.aqara_doorbell_192_168_4_40_doorbell
  from_state:
    entity_id: event.aqara_doorbell_192_168_4_40_doorbell
    state: '2026-05-04T03:09:40.494+00:00'
    attributes:
      event_types:
        - ring
      event_type: ring
      device_class: doorbell
      friendly_name: Aqara Doorbell (192.168.4.40) Doorbell
    last_changed: '2026-05-04T03:09:40.495121+00:00'
    last_reported: '2026-05-04T03:09:40.495121+00:00'
    last_updated: '2026-05-04T03:09:40.495121+00:00'
    context:
      id: 01KQRFD0RF4214VFJA2YYPXCEF
      parent_id: null
      user_id: null
  to_state:
    entity_id: event.aqara_doorbell_192_168_4_40_doorbell
    state: '2026-05-04T03:10:10.495+00:00'
    attributes:
      event_types:
        - ring
      event_type: ring
      device_class: doorbell
      friendly_name: Aqara Doorbell (192.168.4.40) Doorbell
    last_changed: '2026-05-04T03:10:10.495848+00:00'
    last_reported: '2026-05-04T03:10:10.495848+00:00'
    last_updated: '2026-05-04T03:10:10.495848+00:00'
    context:
      id: 01KQRFDY1ZMXKGCEMN9RZJVW88
      parent_id: null
      user_id: null
1 Like

That’ll be the multicast detection not working properly with your network setup. The integration currently doesn’t filter multicast propely, that’s not implemented. It’s only supposed to be a proof-of-concept for the 2-way audio, not a fully working doorbell integration, and I currently don’t plan on developing it into one. I suggest you use the official Homekit implemention for a properly working doorbell.

1 Like

Someone else has already taken the 2-way-audio method devised here and made a functioning Sycrypted Aqara plugin - you’d be much better off using that since it is being actively developed into more complete solution:

https://www.npmjs.com/package/aqara-scrypted

1 Like

The G410’s LAN protocol does not expose ring events directly — Aqara migrated to an encrypted ECDH+AES tunnel in newer firmware and the event is not visible to third-party plugins without a runtime DEX unpack of the official app (out of scope here). The plugin works around this by exposing a webhook URL per camera. You wire that webhook up once to any trigger source (Aqara’s own Matter Signal Sync via Home Assistant or Apple Home, an existing NVR, a physical switch, or anything else that can make an HTTP request). When the webhook fires, the camera’s Scrypted Doorbell / BinarySensor turns on for 10 seconds — HomeKit, Scrypted NVR, and everything else downstream see it as a real ring.

That probably won’t solve his problem with the doorbell’s trigger. Or rather, he can then solve it directly via a Matter signal. The linked page only mentions the G410. Is it any different for the G400?

1 Like

The integration is only meant to be a proof of concept for 2-way-audio not a fully working doorbell integration, and I won’t be developing it any further into one. I’ve folded the core of it into another project I’m doing, which does solve encrypted events mentioned, but it won’t be ready for a while.

The G410 and the G400 share the same basic architecture for these so the linked Scrypted project should work on both, and by reports I’ve seen it does.

2 Likes