npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

camera-ui-aqara

v2.3.0

Published

Aqara integration for camera.ui: local RTSP LAN video, snapshots, and a doorbell webhook (tested with G410), plus optional Aqara Cloud doorbell/motion sensors via the Open API. Merges the former camera-ui-aqara and camera-ui-aqara-cloud plugins into one,

Readme

Aqara plugin for camera.ui

Aqara integration for camera.ui: local RTSP LAN video (tested against the Aqara G410) and Aqara Cloud doorbell/motion events, in one plugin with independent switches for each half.

This replaces the two separate plugins, camera-ui-aqara (local) and camera-ui-aqara-cloud (cloud) — see What changed if you used either before.

Features

| Feature | Source | Status | | --- | --- | --- | | Live video (main + substream) | Local | Yes, for Aqara cameras adopted by this plugin | | Snapshots (from main stream) | Local | Yes, for Aqara cameras adopted by this plugin | | Doorbell ring, via local HTTP webhook | Local | Yes, on any camera assigned to this plugin | | Motion sensor, via local HTTP webhook | Local | Yes, on any camera assigned to this plugin | | Doorbell ring, via Aqara Cloud push | Cloud | Yes | | Motion sensor, via Aqara Cloud push | Cloud | Yes | | Two-way audio (talkback) | Local | Not yet (proprietary LAN protocol; planned) |

The webhook rows aren't limited to Aqara hardware: assign this plugin to any camera in camera.ui — one you adopted with it or one that already gets its video from a different plugin entirely — and that camera gets the doorbell/motion webhook too. See Setup → Local below.

Architecture

Two subsystems live in one plugin and run independently:

  • Local — has two separable jobs. It adopts Aqara cameras by IP + RTSP credentials (DiscoveryProvider) and gives them video sources; separately, any camera assigned to this plugin — Aqara or not — gets a per-camera HTTP webhook that can fire that camera's doorbell and motion sensors. RTSP is entirely optional and only relevant if this plugin is also the one providing that camera's video.
  • Cloud — logs into the Aqara Open API, subscribes to resource events for your devices, and receives them via an HTTP push listener and/or an optional aqara-rocketmq-bridge SSE feed. Matching doorbell/motion sensors are offered for adoption on the Sensors page, same as any other externally-sourced sensor — see Setup → Cloud below.

Both are on by default. Two settings at the top of the plugin's page — Enable Local RTSP and Enable Aqara Cloud — let you turn either off independently without losing its configuration. Turning Local off only stops offering new Aqara cameras for adoption (the "Add Aqara Camera (manual)" entry disappears); the doorbell/motion webhook keeps working on every camera already assigned to this plugin regardless, since it doesn't depend on RTSP. Turning Cloud off stops the push listener/SSE client and the Aqara API calls; any sensors you'd already adopted stay in camera.ui but go quiet until you turn it back on.

Prerequisites

1. Local (RTSP)

  1. The camera must be hardwired (RTSP does not work on battery-only models).
  2. In the Aqara Home app: open the camera → Settings → RTSP LAN Preview → enable, then copy the generated username and password and note the camera's LAN IP.

2. Cloud (Aqara Open API)

  1. An Aqara Developer project with App ID, Key ID, App Key.
  2. Message Push enabled, User-defined subscription mode, channel HTTP Push (recommended) or Message Queue + aqara-rocketmq-bridge.

Both: camera.ui ≥ 2.1.4, Node ≥ 20.19.

Install

unzip camera-ui-aqara.zip
cd camera-ui-aqara
npm install
npm run bundle

Install the resulting bundle into camera.ui (Plugins → Install from file / local package), or copy the bundle/ output into your camera.ui plugins directory as documented for your install.

Setup

1. Local (RTSP camera)

  1. Open Plugins → Aqara. Confirm Enable Local RTSP is on (it is by default).
  2. Use Discover / Add device and choose Add Aqara Camera (manual) — Aqara doesn't expose a LAN discovery protocol, so this is always a manual entry.
  3. Fill in Name, IP, RTSP username/password, and optional channels / webhook port. Confirm the live preview.

The G410 exposes three RTSP channels on port 8554: ch1 (main/high-res), ch2 (medium), ch3 (sub/low bitrate). Pick main/sub channels when adopting or later in camera settings.

Doorbell & motion webhooks: Aqara doesn't expose ring or motion/presence events to third parties over RTSP, so both use the same local webhook approach as the original Scrypted plugin:

  1. In the camera's settings, set Webhook listen port to a free port on the camera.ui host (e.g. 18789) and save.
  2. Note the Webhook token (or click Regenerate webhook token — this invalidates both paths below at once, since they share one token).
  3. Copy the finished URLs straight from camera settings — Ring webhook URL, Motion ON webhook URL, Motion OFF webhook URL are read-only fields built automatically from the port + token above, using camera.ui's own server address. Paste one into each of your trigger's actions:
    • Ring → doorbell, GET or POST both work.
    • Motion ON / Motion OFF → the two motion states, same.
    Building the URL by hand still works too, if you'd rather: http://<camera.ui-host>:<webhookPort>/ring/<token> and /motion/<token>/<on|off> (on also accepts 1 / true / detected / active, off also accepts 0 / false / clear / inactive).
  4. Or use Test doorbell ring / Test motion in camera settings to fire either locally, no HTTP call needed (test motion auto-clears after 10s).

The camera's own presence sensor isn't reachable over RTSP or any documented local API, so the motion webhook needs something else to actually call it. If you run Home Assistant, absent42/Aqara-LANLink reverse-engineers Aqara's local hub protocol and can expose the camera's presence/motion state as a binary_sensor — unofficial and only validated against the Aqara M3 hub (the G410 is a lumi1. hub too, so it's plausible but unconfirmed). Point an HA automation at the on/off transitions of that entity and you have local motion with no RTSP frame analysis and no cloud. Failing that, fall back to the Aqara Cloud subsystem below, or a camera.ui motion/object detector plugin on the video stream.

Using the webhook on a non-Aqara camera

The doorbell/motion webhook doesn't need this plugin to own that camera's video. To add it to a camera that already gets its stream from a different plugin: open that camera's settings in camera.ui, assign Aqara as an additional sensor provider (alongside whatever already provides its video), then leave the whole RTSP Video section blank — set Webhook listen port and use the paths above like normal. Motion is a single-provider slot per camera, so this replaces whatever else was providing that camera's motion sensor, if anything; doorbell allows multiple providers, so it simply adds a second doorbell alongside any existing one. Every camera needs its own webhook port — they can't share one.

2. Cloud (Aqara Open API)

  1. Open Plugins → Aqara. Confirm Enable Aqara Cloud is on.
  2. Under Cloud Account, set Region, App ID, Key ID, App Key, Aqara account.
  3. Click Request auth code → enter the code from email/SMS into Auth code → Complete login.
  4. Click Refresh devices & subscribe (this also runs automatically after login and on every restart).
  5. Under Cloud Ingress: for HTTP Push, set HTTP push port (e.g. 18080) and confirm the path (/aqara/push by default) — then in the Aqara Developer Console, set the push URL to a publicly reachable address pointing at that port (tunnel or port-forward as needed). For the bridge path instead, set RocketMQ bridge URL + Bridge token. Both can be enabled; events are merged.
  6. Go to camera.ui's Sensors page and rescan — a Doorbell and a Motion sensor will be offered for each cloud device found. Adopt the ones you want, then assign them to whichever camera(s) you like.

This adoption step is how camera.ui handles any externally-sourced sensor (Home Assistant entities, vendor accounts, etc.) — sensors are never created automatically without you picking them, so they show up as candidates rather than appearing on their own.

Default resource IDs: Doorbell 13.95.85 (face/recognition-style event on G410), Motion 3.21.85 + 3.51.85. Override Doorbell / Motion resource IDs and Extra subscribe resource IDs under Cloud Sensors if your region/model uses different attributes.

Development

npm install
npm run build        # tsc → dist/
npm run bundle        # production bundle via @camera.ui/cli
npm run bundle:dev    # development bundle
npm run format         # prettier
npm run lint            # eslint --fix

What changed from the two original plugins

This merge was checked against the real @camera.ui/sdk (verified at 1.2.38) and @camera.ui/cli (0.0.106), including a full npx tsc type-check and an actual cui bundle run with contract validation. A few things surfaced and were fixed along the way — worth knowing if you had either plugin before:

  • Local: the discovery method was named discover(); the SDK expects onDiscoverCameras(). As originally written, the "Add Aqara Camera (manual)" entry would never have appeared. Renamed.
  • Local: the "Regenerate doorbell token" button used color: 'warning', which isn't a valid value ('success' | 'info' | 'warn' | 'danger'). Changed to 'warn'.
  • Cloud: four hidden storage fields (the persisted auth tokens) were missing the description the schema type requires. Added.
  • Cloud, the bigger one: sensor creation called api.sensorManager.addSensor(...), which doesn't exist — SensorManager is read-only (history queries only). Standalone sensors can only be created through the SDK's SensorDiscoveryProvider adoption flow. This is now implemented properly: cloud doorbell/motion sensors are discoverable and adopted from the Sensors page (see Setup → Cloud, step 6) instead of registering themselves the moment a device is found. Functionally this is the same events → sensors pipeline, just routed through the adoption step the SDK actually requires.
  • Bumped the @camera.ui/sdk / @camera.ui/cli dev dependency versions to the ones this was verified against.

If you had both original plugins installed: uninstall them, install this one, then re-adopt your local camera(s) (same RTSP credentials) and re-run the Cloud login + device refresh. Point your Aqara HTTP Push URL at this plugin's push port if it changed.

Credits

License

MIT